Clean up examples and unit tests to use new parameter types

This commit is contained in:
James Agnew 2014-07-21 18:37:08 -04:00
parent 063e2961ab
commit fc74cda994
38 changed files with 922 additions and 462 deletions

View File

@ -32,11 +32,16 @@
of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one!
</action>
<action type="add">
Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion.
Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion!
</action>
<action type="add" issue="1">
If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or
an OperationOutcome resource, include the message in the exception message so that it will be
more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion!
</action>
<action type="add" issue="2">
Read invocations in the client now process the "Content-Location" header and use it to
populate the ID of the returned resource.
populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion!
</action>
<action type="fix" issue="3">
Fix issue where vread invocations on server incorrectly get routed to instance history method if one is

View File

@ -26,27 +26,8 @@ import ca.uhn.fhir.rest.method.QualifiedParamList;
public interface IQueryParameterOr<T extends IQueryParameterType> {
/**
* Sets the value of this type using the <b>token</b> format. This format is used in HTTP queries as a parameter
* format.
* <p>
* See FHIR specification <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search
* SearchParameter Types</a> for information on the <b>token</b> format
* </p>
*/
public void setValuesAsQueryTokens(QualifiedParamList theParameters);
// public void setValuesAsQueryTokens(List<IQueryParameterType> theParameters);
/**
* Returns the value of this type using the <b>token</b> format. This format is used in HTTP queries as a parameter
* format.
*
* <p>
* See FHIR specification <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search
* SearchParameter Types</a> for information on the <b>token</b> format
* </p>
*/
public List<T> getValuesAsQueryTokens();
}

View File

@ -25,6 +25,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @deprecated IdDt can now hold both an ID and a version ID, so a single parameter with the {@link IdParam} annotation may be used
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface VersionIdParam {

View File

@ -92,6 +92,9 @@ public class MethodOutcome {
myOperationOutcome = theOperationOutcome;
}
/**
* @deprecated Put the ID and version ID into the same IdDt instance and pass it to {@link #setId(IdDt)}
*/
public void setVersionId(IdDt theVersionId) {
myVersionId = theVersionId;
}

View File

@ -46,7 +46,10 @@ import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
import ca.uhn.fhir.rest.method.IClientResponseHandler;
import ca.uhn.fhir.rest.method.IClientResponseHandlerHandlesBinary;
@ -119,15 +122,15 @@ public abstract class BaseClient {
return myUrlBase;
}
<T> T invokeClient(IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation) {
return invokeClient(binding, clientInvocation, false);
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation) {
return invokeClient(theContext, binding, clientInvocation, false);
}
<T> T invokeClient(IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, boolean theLogRequestAndResponse) {
return invokeClient(binding, clientInvocation, null, null, theLogRequestAndResponse);
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, boolean theLogRequestAndResponse) {
return invokeClient(theContext, binding, clientInvocation, null, null, theLogRequestAndResponse);
}
<T> T invokeClient(IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, EncodingEnum theEncoding, Boolean thePrettyPrint, boolean theLogRequestAndResponse) {
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, EncodingEnum theEncoding, Boolean thePrettyPrint, boolean theLogRequestAndResponse) {
// TODO: handle non 2xx status codes by throwing the correct exception,
// and ensure it's passed upwards
HttpRequestBase httpRequest;
@ -201,6 +204,19 @@ public abstract class BaseClient {
String message = "HTTP " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase();
if (Constants.CT_TEXT.equals(mimeType)) {
message = message + ": " + body;
} else {
EncodingEnum enc = EncodingEnum.forContentType(mimeType);
if (enc != null) {
IParser p = enc.newParser(theContext);
try {
OperationOutcome oo = p.parseResource(OperationOutcome.class, body);
if (oo.getIssueFirstRep().getDetails().isEmpty()==false) {
message = message + ": " + oo.getIssueFirstRep().getDetails().getValue();
}
} catch (Exception e) {
ourLog.debug("Failed to process OperationOutcome response");
}
}
}
keepResponseAndLogIt(theLogRequestAndResponse, response, body);

View File

@ -41,9 +41,13 @@ public class ClientInvocationHandler extends BaseClient implements InvocationHan
private final Map<Method, Object> myMethodToReturnValue = new HashMap<Method, Object>();
private FhirContext myContext;
public ClientInvocationHandler(HttpClient theClient, FhirContext theContext, String theUrlBase, Class<? extends IRestfulClient> theClientType) {
super(theClient, theUrlBase);
myContext =theContext;
try {
myMethodToReturnValue.put(theClientType.getMethod("getFhirContext"), theContext);
myMethodToReturnValue.put(theClientType.getMethod("getHttpClient"), theClient);
@ -75,7 +79,7 @@ public class ClientInvocationHandler extends BaseClient implements InvocationHan
BaseMethodBinding<?> binding = myBindings.get(theMethod);
if (binding != null) {
BaseHttpClientInvocation clientInvocation = binding.invokeClient(theArgs);
return invokeClient(binding, clientInvocation);
return invokeClient(myContext, binding, clientInvocation);
}
ILambda lambda = myMethodToLambda.get(theMethod);

View File

@ -105,7 +105,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
ResourceResponseHandler<Conformance> binding = new ResourceResponseHandler<Conformance>(Conformance.class, null);
Conformance resp = invokeClient(binding, invocation, myLogRequestAndResponse);
Conformance resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -126,7 +126,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
MethodOutcome resp = invokeClient(binding, invocation, myLogRequestAndResponse);
MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -140,7 +140,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
final String resourceName = myContext.getResourceDefinition(theType).getName();
OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
MethodOutcome resp = invokeClient(binding, invocation, myLogRequestAndResponse);
MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -168,7 +168,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
BundleResponseHandler binding = new BundleResponseHandler(theType);
Bundle resp = invokeClient(binding, invocation, myLogRequestAndResponse);
Bundle resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -199,7 +199,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
ResourceResponseHandler<T> binding = new ResourceResponseHandler<T>(theType, theId);
T resp = invokeClient(binding, invocation, myLogRequestAndResponse);
T resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -233,7 +233,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
BundleResponseHandler binding = new BundleResponseHandler(theType);
Bundle resp = invokeClient(binding, invocation, myLogRequestAndResponse);
Bundle resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -265,7 +265,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
}
Bundle resp = invokeClient(new BundleResponseHandler(null), invocation, myLogRequestAndResponse);
Bundle resp = invokeClient(myContext, new BundleResponseHandler(null), invocation, myLogRequestAndResponse);
return resp.toListOfResources();
}
@ -281,7 +281,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
final String resourceName = def.getName();
OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
MethodOutcome resp = invokeClient(binding, invocation, myLogRequestAndResponse);
MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -301,7 +301,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
final String resourceName = def.getName();
OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName);
MethodOutcome resp = invokeClient(binding, invocation, myLogRequestAndResponse);
MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -313,7 +313,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
ResourceResponseHandler<T> binding = new ResourceResponseHandler<T>(theType, theId);
T resp = invokeClient(binding, invocation, myLogRequestAndResponse);
T resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
return resp;
}
@ -368,7 +368,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
myLastRequest = theInvocation.asHttpRequest(getServerBase(), theParams, getEncoding());
}
Z resp = invokeClient(theHandler, theInvocation, myParamEncoding, myPrettyPrint, myQueryLogRequestAndResponse || myLogRequestAndResponse);
Z resp = invokeClient(myContext, theHandler, theInvocation, myParamEncoding, myPrettyPrint, myQueryLogRequestAndResponse || myLogRequestAndResponse);
return resp;
}

View File

@ -29,7 +29,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
interface IParamBinder {
List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException;
List<IQueryParameterOr<?>> encode(FhirContext theContext, Object theString) throws InternalErrorException;
Object parse(List<QualifiedParamList> theList) throws InternalErrorException, InvalidRequestException;

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.method;
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException;
import java.io.PushbackReader;
@ -95,7 +95,7 @@ public class MethodUtil {
ourLog.warn("Unable to parse date string '{}'. Error is: {}", headerValue, e.toString());
}
}
List<String> clHeaders = theHeaders.get(Constants.HEADER_CONTENT_LOCATION_LC);
if (clHeaders != null && clHeaders.size() > 0 && StringUtils.isNotBlank(clHeaders.get(0))) {
String headerValue = clHeaders.get(0);
@ -115,28 +115,28 @@ public class MethodUtil {
}
public static HttpPostClientInvocation createCreateInvocation(IResource theResource, FhirContext theContext) {
return createCreateInvocation(theResource, null,null, theContext);
return createCreateInvocation(theResource, null, null, theContext);
}
public static HttpPostClientInvocation createCreateInvocation(IResource theResource, String theResourceBody, String theId, FhirContext theContext) {
RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource);
String resourceName = def.getName();
StringBuilder urlExtension = new StringBuilder();
urlExtension.append(resourceName);
if (StringUtils.isNotBlank(theId)) {
urlExtension.append('/');
urlExtension.append(theId);
}
HttpPostClientInvocation retVal;
if (StringUtils.isBlank(theResourceBody)) {
retVal = new HttpPostClientInvocation(theContext, theResource, urlExtension.toString());
}else {
} else {
retVal = new HttpPostClientInvocation(theContext, theResourceBody, false, urlExtension.toString());
}
addTagsToPostOrPut(theResource, retVal);
return retVal;
}
@ -144,8 +144,18 @@ public class MethodUtil {
return new HttpGetClientInvocation("metadata");
}
public static MethodOutcome process2xxResponse(FhirContext theContext, String theResourceName, int theResponseStatusCode, String theResponseMimeType, Reader theResponseReader, Map<String, List<String>> theHeaders) {
List<String> locationHeaders = theHeaders.get(Constants.HEADER_LOCATION_LC);
public static MethodOutcome process2xxResponse(FhirContext theContext, String theResourceName, int theResponseStatusCode, String theResponseMimeType, Reader theResponseReader,
Map<String, List<String>> theHeaders) {
List<String> locationHeaders = new ArrayList<String>();
List<String> lh = theHeaders.get(Constants.HEADER_LOCATION_LC);
if (lh != null) {
locationHeaders.addAll(lh);
}
List<String> clh = theHeaders.get(Constants.HEADER_CONTENT_LOCATION_LC);
if (clh != null) {
locationHeaders.addAll(clh);
}
MethodOutcome retVal = new MethodOutcome();
if (locationHeaders != null && locationHeaders.size() > 0) {
String locationHeader = locationHeaders.get(0);
@ -155,7 +165,7 @@ public class MethodUtil {
EncodingEnum ct = EncodingEnum.forContentType(theResponseMimeType);
if (ct != null) {
PushbackReader reader = new PushbackReader(theResponseReader);
try {
int firstByte = reader.read();
if (firstByte == -1) {
@ -168,7 +178,7 @@ public class MethodUtil {
BaseOutcomeReturningMethodBinding.ourLog.debug("No content in response, not going to read", e);
reader = null;
}
if (reader != null) {
IParser parser = ct.newParser(theContext);
IResource outcome = parser.parseResource(reader);
@ -176,7 +186,7 @@ public class MethodUtil {
retVal.setOperationOutcome((OperationOutcome) outcome);
}
}
} else {
BaseOutcomeReturningMethodBinding.ourLog.debug("Ignoring response content of type: {}", theResponseMimeType);
}
@ -212,9 +222,9 @@ public class MethodUtil {
}
}
public static IQueryParameterOr singleton(final IQueryParameterType theParam) {
return new IQueryParameterOr() {
public static IQueryParameterOr<?> singleton(final IQueryParameterType theParam) {
return new IQueryParameterOr<IQueryParameterType>() {
@Override
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
if (theParameters.isEmpty()) {
@ -225,7 +235,7 @@ public class MethodUtil {
}
theParam.setValueAsQueryToken(theParameters.getQualifier(), theParameters.get(0));
}
@Override
public List<IQueryParameterType> getValuesAsQueryTokens() {
return Collections.singletonList(theParam);
@ -233,6 +243,7 @@ public class MethodUtil {
};
}
@SuppressWarnings("deprecation")
public static Integer findVersionIdParameterIndex(Method theMethod) {
return MethodUtil.findParamAnnotationIndex(theMethod, VersionIdParam.class);
}
@ -248,11 +259,11 @@ public class MethodUtil {
@SuppressWarnings("unchecked")
public static List<IParameter> getResourceParameters(Method theMethod) {
List<IParameter> parameters = new ArrayList<IParameter>();
Class<?>[] parameterTypes = theMethod.getParameterTypes();
int paramIndex = 0;
for (Annotation[] annotations : theMethod.getParameterAnnotations()) {
IParameter param = null;
Class<?> parameterType = parameterTypes[paramIndex];
Class<? extends java.util.Collection<?>> outerCollectionType = null;
@ -271,7 +282,8 @@ public class MethodUtil {
parameterType = ReflectionUtil.getGenericCollectionTypeOfMethodParameter(theMethod, paramIndex);
}
if (Collection.class.isAssignableFrom(parameterType)) {
throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of an invalid generic type (can not be a collection of a collection of a collection)");
throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName()
+ "' is of an invalid generic type (can not be a collection of a collection of a collection)");
}
}
if (parameterType.equals(HttpServletRequest.class) || parameterType.equals(ServletRequest.class)) {
@ -281,7 +293,7 @@ public class MethodUtil {
} else {
for (int i = 0; i < annotations.length && param == null; i++) {
Annotation nextAnnotation = annotations[i];
if (nextAnnotation instanceof RequiredParam) {
SearchParameter parameter = new SearchParameter();
parameter.setName(((RequiredParam) nextAnnotation).name());
@ -301,21 +313,24 @@ public class MethodUtil {
} else if (nextAnnotation instanceof IncludeParam) {
Class<? extends Collection<Include>> instantiableCollectionType;
Class<?> specType;
if (parameterType == String.class) {
instantiableCollectionType = null;
specType = String.class;
} else if ((parameterType != Include.class && parameterType != PathSpecification.class) || innerCollectionType == null || outerCollectionType != null) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<" + Include.class.getSimpleName() + ">");
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<"
+ Include.class.getSimpleName() + ">");
} else {
instantiableCollectionType = (Class<? extends Collection<Include>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName() + "'");
instantiableCollectionType = (Class<? extends Collection<Include>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName()
+ "'");
specType = parameterType;
}
param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType, specType);
} else if (nextAnnotation instanceof ResourceParam) {
if (!IResource.class.isAssignableFrom(parameterType)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName() + " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName()
+ " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
}
param = new ResourceParameter((Class<? extends IResource>) parameterType);
} else if (nextAnnotation instanceof IdParam || nextAnnotation instanceof VersionIdParam) {
@ -333,19 +348,19 @@ public class MethodUtil {
} else {
continue;
}
}
}
if (param == null) {
throw new ConfigurationException("Parameter #" + ((paramIndex+1))+"/" + (parameterTypes.length) + " of method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName()
+ "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter");
throw new ConfigurationException("Parameter #" + ((paramIndex + 1)) + "/" + (parameterTypes.length) + " of method '" + theMethod.getName() + "' on type '"
+ theMethod.getDeclaringClass().getCanonicalName() + "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter");
}
param.initializeTypes(theMethod, outerCollectionType, innerCollectionType, parameterType);
parameters.add(param);
paramIndex++;
}
return parameters;

View File

@ -29,21 +29,22 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
final class QueryParameterAndBinder implements IParamBinder {
private final Class<? extends IQueryParameterAnd> myType;
private final Class<? extends IQueryParameterAnd<?>> myType;
QueryParameterAndBinder(Class<? extends IQueryParameterAnd> theType) {
QueryParameterAndBinder(Class<? extends IQueryParameterAnd<?>> theType) {
myType = theType;
}
@SuppressWarnings("unchecked")
@Override
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
List<IQueryParameterOr> retVal = ((IQueryParameterAnd) theString).getValuesAsQueryTokens();
public List<IQueryParameterOr<?>> encode(FhirContext theContext, Object theString) throws InternalErrorException {
List<IQueryParameterOr<?>> retVal = (List<IQueryParameterOr<?>>) ((IQueryParameterAnd<?>) theString).getValuesAsQueryTokens();
return retVal;
}
@Override
public Object parse(List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
IQueryParameterAnd dt;
IQueryParameterAnd<?> dt;
try {
dt = myType.newInstance();
dt.setValuesAsQueryTokens(theString);

View File

@ -29,21 +29,23 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
final class QueryParameterOrBinder implements IParamBinder {
private final Class<? extends IQueryParameterOr> myType;
private final Class<? extends IQueryParameterOr<?>> myType;
QueryParameterOrBinder(Class<? extends IQueryParameterOr> theType) {
QueryParameterOrBinder(Class<? extends IQueryParameterOr<?>> theType) {
myType = theType;
}
@SuppressWarnings("unchecked")
@Override
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
IQueryParameterOr retVal = ((IQueryParameterOr) theString);
return Collections.singletonList(retVal);
public List<IQueryParameterOr<?>> encode(FhirContext theContext, Object theString) throws InternalErrorException {
IQueryParameterOr<?> retVal = ((IQueryParameterOr<?>) theString);
List<?> retVal2 = Collections.singletonList((IQueryParameterOr<?>)retVal);
return (List<IQueryParameterOr<?>>) retVal2;
}
@Override
public Object parse(List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
IQueryParameterOr dt;
IQueryParameterOr<?> dt;
try {
dt = myType.newInstance();
if (theString.size() == 0 || theString.get(0).size() == 0) {

View File

@ -38,10 +38,12 @@ final class QueryParameterTypeBinder implements IParamBinder {
myType = theType;
}
@SuppressWarnings("unchecked")
@Override
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
public List<IQueryParameterOr<?>> encode(FhirContext theContext, Object theString) throws InternalErrorException {
IQueryParameterType param = (IQueryParameterType) theString;
return Collections.singletonList(MethodUtil.singleton(param));
List<?> retVal = Collections.singletonList(MethodUtil.singleton(param));
return (List<IQueryParameterOr<?>>) retVal;
}
@Override

View File

@ -39,9 +39,20 @@ import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.param.BaseQueryParameter;
import ca.uhn.fhir.rest.param.CodingListParam;
import ca.uhn.fhir.rest.param.DateAndListParam;
import ca.uhn.fhir.rest.param.DateOrListParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.IdentifierListParam;
import ca.uhn.fhir.rest.param.NumberAndListParam;
import ca.uhn.fhir.rest.param.NumberOrListParam;
import ca.uhn.fhir.rest.param.NumberParam;
import ca.uhn.fhir.rest.param.QualifiedDateParam;
import ca.uhn.fhir.rest.param.QuantityAndListParam;
import ca.uhn.fhir.rest.param.QuantityOrListParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
@ -55,6 +66,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
/**
* Created by dsotnikov on 2/25/2014.
*/
@SuppressWarnings("deprecation")
public class SearchParameter extends BaseQueryParameter {
private static HashMap<Class<?>, SearchParamTypeEnum> ourParamTypes;
@ -83,8 +95,8 @@ public class SearchParameter extends BaseQueryParameter {
public List<QualifiedParamList> encode(FhirContext theContext, Object theObject) throws InternalErrorException {
ArrayList<QualifiedParamList> retVal = new ArrayList<QualifiedParamList>();
List<IQueryParameterOr> val = myParamBinder.encode(theContext, theObject);
for (IQueryParameterOr nextOr : val) {
List<IQueryParameterOr<?>> val = myParamBinder.encode(theContext, theObject);
for (IQueryParameterOr<?> nextOr : val) {
retVal.add(new QualifiedParamList(theContext, nextOr));
}
@ -165,10 +177,26 @@ public class SearchParameter extends BaseQueryParameter {
ourParamTypes.put(TokenOrListParam.class, SearchParamTypeEnum.TOKEN);
ourParamTypes.put(TokenAndListParam.class, SearchParamTypeEnum.TOKEN);
ourParamTypes.put(DateParam.class, SearchParamTypeEnum.DATE);
ourParamTypes.put(DateOrListParam.class, SearchParamTypeEnum.DATE);
ourParamTypes.put(DateAndListParam.class, SearchParamTypeEnum.DATE);
ourParamTypes.put(DateRangeParam.class, SearchParamTypeEnum.DATE);
ourParamTypes.put(QuantityParam.class, SearchParamTypeEnum.QUANTITY);
ourParamTypes.put(QuantityOrListParam.class, SearchParamTypeEnum.QUANTITY);
ourParamTypes.put(QuantityAndListParam.class, SearchParamTypeEnum.QUANTITY);
ourParamTypes.put(NumberParam.class, SearchParamTypeEnum.NUMBER);
ourParamTypes.put(NumberOrListParam.class, SearchParamTypeEnum.NUMBER);
ourParamTypes.put(NumberAndListParam.class, SearchParamTypeEnum.NUMBER);
ourParamTypes.put(ReferenceParam.class, SearchParamTypeEnum.REFERENCE);
ourParamTypes.put(ReferenceOrListParam.class, SearchParamTypeEnum.REFERENCE);
ourParamTypes.put(ReferenceAndListParam.class, SearchParamTypeEnum.REFERENCE);
}
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked" })
public void setType(final Class<?> type, Class<? extends Collection<?>> theInnerCollectionType, Class<? extends Collection<?>> theOuterCollectionType) {
this.myType = type;
if (IQueryParameterType.class.isAssignableFrom(type)) {

View File

@ -33,10 +33,12 @@ final class StringBinder implements IParamBinder {
StringBinder() {
}
@SuppressWarnings("unchecked")
@Override
public List<IQueryParameterOr> encode(FhirContext theContext, Object theString) throws InternalErrorException {
public List<IQueryParameterOr<?>> encode(FhirContext theContext, Object theString) throws InternalErrorException {
String retVal = ((String) theString);
return Collections.singletonList(MethodUtil.singleton(new StringParam(retVal)));
List<?> retValList = Collections.singletonList(MethodUtil.singleton(new StringParam(retVal)));
return (List<IQueryParameterOr<?>>) retValList;
}
@Override

View File

@ -82,6 +82,12 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
}
}
if (theRequest.getId() != null && theRequest.getId().hasVersionIdPart() == false) {
if (id != null && id.hasVersionIdPart()) {
theRequest.setId(id);
}
}
if (isNotBlank(locationHeader)) {
MethodOutcome mo = new MethodOutcome();
parseContentLocation(mo, getResourceName(), locationHeader);
@ -131,10 +137,10 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
HttpPutClientInvocation retVal = new HttpPutClientInvocation(context, theResource, urlExtension.toString());
if (idDt.hasVersionIdPart()) {
String versionId = versionIdDt.getValue();
String versionId = idDt.getVersionIdPart();
if (StringUtils.isNotBlank(versionId)) {
StringBuilder b = new StringBuilder();
b.append('/');
// b.append('/');
b.append(urlExtension);
b.append("/_history/");
b.append(versionId);
@ -144,7 +150,7 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
String versionId = versionIdDt.getValue();
if (StringUtils.isNotBlank(versionId)) {
StringBuilder b = new StringBuilder();
b.append('/');
// b.append('/');
b.append(urlExtension);
b.append("/_history/");
b.append(versionId);

View File

@ -0,0 +1,53 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
abstract class BaseAndListParam<T extends IQueryParameterOr<?>> implements IQueryParameterAnd<T> {
private List<T> myValues=new ArrayList<T>();
@Override
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
myValues.clear();
for (QualifiedParamList nextParam : theParameters) {
T nextList = newInstance();
nextList.setValuesAsQueryTokens(nextParam);
myValues.add(nextList);
}
}
abstract T newInstance();
@Override
public List<T> getValuesAsQueryTokens() {
return myValues;
}
}

View File

@ -0,0 +1,64 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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.ArrayList;
import java.util.List;
import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.method.QualifiedParamList;
abstract class BaseOrListParam<T extends IQueryParameterType> implements IQueryParameterOr<T> {
private List<T> myList=new ArrayList<T>();
public void addToken(T theParam) {
Validate.notNull(theParam,"Param can not be null");
myList.add(theParam);
}
@Override
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
myList.clear();
for (String next : theParameters) {
T nextParam = newInstance();
nextParam.setValueAsQueryToken(theParameters.getQualifier(), next);
myList.add(nextParam);
}
}
abstract T newInstance();
public void add(T theParameter) {
if (theParameter != null) {
myList.add(theParameter);
}
}
@Override
public List<T> getValuesAsQueryTokens() {
return myList;
}
}

View File

@ -0,0 +1,31 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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%
*/
public class DateAndListParam extends BaseAndListParam<DateOrListParam> {
@Override
DateOrListParam newInstance() {
return new DateOrListParam();
}
}

View File

@ -0,0 +1,31 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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%
*/
public class DateOrListParam extends BaseOrListParam<DateParam> {
@Override
DateParam newInstance() {
return new DateParam();
}
}

View File

@ -28,7 +28,10 @@ import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.rest.method.QualifiedParamList;
public class IdentifierListParam implements IQueryParameterOr {
/**
* @deprecated Use {@link TokenOrListParam} instead. That class provides similar functionality but is named to be consistent with other types
*/
public class IdentifierListParam implements IQueryParameterOr<IQueryParameterType> {
private List<IdentifierDt> myIdentifiers = new ArrayList<IdentifierDt>();

View File

@ -0,0 +1,31 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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%
*/
public class NumberAndListParam extends BaseAndListParam<NumberOrListParam> {
@Override
NumberOrListParam newInstance() {
return new NumberOrListParam();
}
}

View File

@ -0,0 +1,31 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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%
*/
public class NumberOrListParam extends BaseOrListParam<NumberParam> {
@Override
NumberParam newInstance() {
return new NumberParam();
}
}

View File

@ -0,0 +1,31 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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%
*/
public class QuantityAndListParam extends BaseAndListParam<QuantityOrListParam> {
@Override
QuantityOrListParam newInstance() {
return new QuantityOrListParam();
}
}

View File

@ -0,0 +1,31 @@
package ca.uhn.fhir.rest.param;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 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%
*/
public class QuantityOrListParam extends BaseOrListParam<QuantityParam> {
@Override
QuantityParam newInstance() {
return new QuantityParam();
}
}

View File

@ -38,8 +38,8 @@ import ca.uhn.fhir.model.primitive.UriDt;
public class QuantityParam implements IQueryParameterType {
private QuantityDt myQuantity = new QuantityDt();
private boolean myApproximate;
private QuantityDt myQuantity = new QuantityDt();
/**
* Constructor
@ -47,6 +47,63 @@ public class QuantityParam implements IQueryParameterType {
public QuantityParam() {
}
/**
* Constructor
*
* @param theComparator
* The comparator, or <code>null</code> for an equals comparator
* @param theQuantity
* A quantity value
* @param theSystem
* The unit system
* @param theUnits
* The unit code
*/
public QuantityParam(QuantityCompararatorEnum theComparator, BigDecimal theValue, String theSystem, String theUnits) {
setComparator(theComparator);
setValue(theValue);
setSystem(theSystem);
setUnits(theUnits);
}
/**
* Constructor
*
* @param theComparator
* The comparator, or <code>null</code> for an equals comparator
* @param theQuantity
* A quantity value
* @param theSystem
* The unit system
* @param theUnits
* The unit code
*/
public QuantityParam(QuantityCompararatorEnum theComparator, double theValue, String theSystem, String theUnits) {
setComparator(theComparator);
setValue(theValue);
setSystem(theSystem);
setUnits(theUnits);
}
/**
* Constructor
*
* @param theComparator
* The comparator, or <code>null</code> for an equals comparator
* @param theQuantity
* A quantity value
* @param theSystem
* The unit system
* @param theUnits
* The unit code
*/
public QuantityParam(QuantityCompararatorEnum theComparator, long theValue, String theSystem, String theUnits) {
setComparator(theComparator);
setValue(theValue);
setSystem(theSystem);
setUnits(theUnits);
}
/**
* Constructor
*
@ -73,10 +130,69 @@ public class QuantityParam implements IQueryParameterType {
setUnits(theUnits);
}
private void clear() {
myQuantity.setComparator((BoundCodeDt<QuantityCompararatorEnum>) null);
myQuantity.setCode((CodeDt) null);
myQuantity.setSystem((UriDt) null);
myQuantity.setUnits((StringDt) null);
myQuantity.setValue((DecimalDt) null);
myApproximate = false;
}
public QuantityCompararatorEnum getComparator() {
return myQuantity.getComparator().getValueAsEnum();
}
@Override
public String getQueryParameterQualifier() {
return null;
}
public UriDt getSystem() {
return myQuantity.getSystem();
}
public String getUnits() {
return myQuantity.getUnits().getValue();
}
public DecimalDt getValue() {
return myQuantity.getValue();
}
@Override
public String getValueAsQueryToken() {
StringBuilder b = new StringBuilder();
if (myQuantity.getComparator() != null) {
b.append(ParameterUtil.escape(myQuantity.getComparator().getValue()));
} else if (myApproximate) {
b.append('~');
}
if (!myQuantity.getValue().isEmpty()) {
b.append(ParameterUtil.escape(myQuantity.getValue().getValueAsString()));
}
b.append('|');
if (!myQuantity.getSystem().isEmpty()) {
b.append(ParameterUtil.escape(myQuantity.getSystem().getValueAsString()));
}
b.append('|');
if (!myQuantity.getUnits().isEmpty()) {
b.append(ParameterUtil.escape(myQuantity.getUnits().getValueAsString()));
}
return b.toString();
}
public boolean isApproximate() {
return myApproximate;
}
public void setApproximate(boolean theApproximate) {
myApproximate = theApproximate;
myQuantity.setComparator((QuantityCompararatorEnum) null);
}
public QuantityParam setComparator(QuantityCompararatorEnum theComparator) {
myQuantity.setComparator(theComparator);
return this;
@ -93,8 +209,19 @@ public class QuantityParam implements IQueryParameterType {
return this;
}
public DecimalDt getValue() {
return myQuantity.getValue();
public QuantityParam setSystem(String theSystem) {
myQuantity.setSystem(theSystem);
return this;
}
public QuantityParam setSystem(UriDt theSystem) {
myQuantity.setSystem(theSystem);
return this;
}
public QuantityParam setUnits(String theUnits) {
myQuantity.setUnits(theUnits);
return this;
}
public QuantityParam setValue(BigDecimal theValue) {
@ -107,49 +234,16 @@ public class QuantityParam implements IQueryParameterType {
return this;
}
public QuantityParam setValue(long theValue) {
myQuantity.setValue(theValue);
return this;
}
public QuantityParam setValue(double theValue) {
myQuantity.setValue(theValue);
return this;
}
public UriDt getSystem() {
return myQuantity.getSystem();
}
public QuantityParam setSystem(String theSystem) {
myQuantity.setSystem(theSystem);
public QuantityParam setValue(long theValue) {
myQuantity.setValue(theValue);
return this;
}
public QuantityParam setSystem(UriDt theSystem) {
myQuantity.setSystem(theSystem);
return this;
}
public String getUnits() {
return myQuantity.getUnits().getValue();
}
public QuantityParam setUnits(String theUnits) {
myQuantity.setUnits(theUnits);
return this;
}
@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("cmp", myQuantity.getComparator().getValueAsString());
b.append("value", myQuantity.getValue().getValueAsString());
b.append("system", myQuantity.getSystem().getValueAsString());
b.append("units", myQuantity.getUnits().getValueAsString());
return b.toString();
}
@Override
public void setValueAsQueryToken(String theQualifier, String theValue) {
clear();
@ -189,51 +283,14 @@ public class QuantityParam implements IQueryParameterType {
}
private void clear() {
myQuantity.setComparator((BoundCodeDt<QuantityCompararatorEnum>) null);
myQuantity.setCode((CodeDt) null);
myQuantity.setSystem((UriDt) null);
myQuantity.setUnits((StringDt) null);
myQuantity.setValue((DecimalDt) null);
myApproximate = false;
}
public boolean isApproximate() {
return myApproximate;
}
public void setApproximate(boolean theApproximate) {
myApproximate = theApproximate;
myQuantity.setComparator((QuantityCompararatorEnum)null);
}
@Override
public String getValueAsQueryToken() {
StringBuilder b = new StringBuilder();
if (myQuantity.getComparator() != null) {
b.append(ParameterUtil.escape(myQuantity.getComparator().getValue()));
} else if (myApproximate) {
b.append('~');
}
if (!myQuantity.getValue().isEmpty()) {
b.append(ParameterUtil.escape(myQuantity.getValue().getValueAsString()));
}
b.append('|');
if (!myQuantity.getSystem().isEmpty()) {
b.append(ParameterUtil.escape(myQuantity.getSystem().getValueAsString()));
}
b.append('|');
if (!myQuantity.getUnits().isEmpty()) {
b.append(ParameterUtil.escape(myQuantity.getUnits().getValueAsString()));
}
public String toString() {
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
b.append("cmp", myQuantity.getComparator().getValueAsString());
b.append("value", myQuantity.getValue().getValueAsString());
b.append("system", myQuantity.getSystem().getValueAsString());
b.append("units", myQuantity.getUnits().getValueAsString());
return b.toString();
}
@Override
public String getQueryParameterQualifier() {
return null;
}
}

View File

@ -20,30 +20,12 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class ReferenceAndListParam extends BaseAndListParam<ReferenceOrListParam> {
public class ReferenceAndListParam implements IQueryParameterAnd<ReferenceOrListParam> {
private List<ReferenceOrListParam> myValues=new ArrayList<ReferenceOrListParam>();
@Override
ReferenceOrListParam newInstance() {
return new ReferenceOrListParam();
}
@Override
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
myValues.clear();
for (QualifiedParamList nextParam : theParameters) {
ReferenceOrListParam nextList = new ReferenceOrListParam();
nextList.setValuesAsQueryTokens(nextParam);
myValues.add(nextList);
}
}
@Override
public List<ReferenceOrListParam> getValuesAsQueryTokens() {
return myValues;
}
}

View File

@ -20,36 +20,12 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.rest.method.QualifiedParamList;
public class ReferenceOrListParam implements IQueryParameterOr<ReferenceParam> {
private List<ReferenceParam> myList = new ArrayList<ReferenceParam>();
public void addToken(ReferenceParam theParam) {
Validate.notNull(theParam, "Param can not be null");
myList.add(theParam);
}
public class ReferenceOrListParam extends BaseOrListParam<ReferenceParam> {
@Override
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
myList.clear();
for (String next : theParameters) {
ReferenceParam nextParam = new ReferenceParam();
nextParam.setValueAsQueryToken(theParameters.getQualifier(), next);
myList.add(nextParam);
}
ReferenceParam newInstance() {
return new ReferenceParam();
}
@Override
public List<ReferenceParam> getValuesAsQueryTokens() {
return myList;
}
}
}

View File

@ -20,30 +20,12 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class StringAndListParam extends BaseAndListParam<StringOrListParam> {
public class StringAndListParam implements IQueryParameterAnd<StringOrListParam> {
private List<StringOrListParam> myValues=new ArrayList<StringOrListParam>();
@Override
StringOrListParam newInstance() {
return new StringOrListParam();
}
@Override
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
myValues.clear();
for (QualifiedParamList nextParam : theParameters) {
StringOrListParam nextList = new StringOrListParam();
nextList.setValuesAsQueryTokens(nextParam);
myValues.add(nextList);
}
}
@Override
public List<StringOrListParam> getValuesAsQueryTokens() {
return myValues;
}
}

View File

@ -20,36 +20,12 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.rest.method.QualifiedParamList;
public class StringOrListParam implements IQueryParameterOr<TokenParam> {
private List<TokenParam> myList=new ArrayList<TokenParam>();
public void addToken(TokenParam theParam) {
Validate.notNull(theParam,"Param can not be null");
myList.add(theParam);
}
@Override
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
myList.clear();
for (String next : theParameters) {
TokenParam nextParam = new TokenParam();
nextParam.setValueAsQueryToken(theParameters.getQualifier(), next);
myList.add(nextParam);
}
}
public class StringOrListParam extends BaseOrListParam<StringParam> {
@Override
public List<TokenParam> getValuesAsQueryTokens() {
return myList;
StringParam newInstance() {
return new StringParam();
}
}
}

View File

@ -20,30 +20,12 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class TokenAndListParam extends BaseAndListParam<TokenOrListParam> {
public class TokenAndListParam implements IQueryParameterAnd<TokenOrListParam> {
private List<TokenOrListParam> myValues=new ArrayList<TokenOrListParam>();
@Override
TokenOrListParam newInstance() {
return new TokenOrListParam();
}
@Override
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
myValues.clear();
for (QualifiedParamList nextParam : theParameters) {
TokenOrListParam nextList = new TokenOrListParam();
nextList.setValuesAsQueryTokens(nextParam);
myValues.add(nextList);
}
}
@Override
public List<TokenOrListParam> getValuesAsQueryTokens() {
return myValues;
}
}

View File

@ -1,5 +1,10 @@
package ca.uhn.fhir.rest.param;
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
/*
* #%L
* HAPI FHIR - Core Library
@ -20,48 +25,27 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.Validate;
public class TokenOrListParam extends BaseOrListParam<TokenParam> {
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.rest.method.QualifiedParamList;
public class TokenOrListParam implements IQueryParameterOr<TokenParam> {
private List<TokenParam> myList = new ArrayList<TokenParam>();
public void addToken(TokenParam theParam) {
Validate.notNull(theParam, "Param can not be null");
myList.add(theParam);
@Override
TokenParam newInstance() {
return new TokenParam();
}
/**
* Returns a copy of all tokens in this list as {@link CodingDt} instances
*/
public List<CodingDt> toCodings() {
public List<CodingDt> getListAsCodings() {
ArrayList<CodingDt> retVal = new ArrayList<CodingDt>();
for (TokenParam next : myList) {
retVal.add(new CodingDt(next.getSystem(), next.getValue()));
for (TokenParam next : getValuesAsQueryTokens()) {
CodingDt nextCoding = next.getValueAsCoding();
if (!nextCoding.isEmpty()) {
retVal.add(nextCoding);
}
}
return retVal;
}
@Override
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
myList.clear();
for (String next : theParameters) {
TokenParam nextParam = new TokenParam();
nextParam.setValueAsQueryToken(theParameters.getQualifier(), next);
myList.add(nextParam);
}
public void add(CodingDt theCodingDt) {
add(new TokenParam(theCodingDt));
}
@Override
public List<TokenParam> getValuesAsQueryTokens() {
return myList;
}
}
}

View File

@ -27,6 +27,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.rest.server.Constants;
public class TokenParam implements IQueryParameterType {
@ -53,6 +54,16 @@ public class TokenParam implements IQueryParameterType {
}
/**
* Constructor which copies the {@link CodingDt#getSystem() system} and {@link CodingDt#getCode() code} from a {@link CodingDt}
* instance and adds it as a parameter
*
* @param theCodingDt The coding
*/
public TokenParam(CodingDt theCodingDt) {
this(theCodingDt.getSystem().getValue().toASCIIString(), theCodingDt.getCode().getValue());
}
@Override
public String getQueryParameterQualifier() {
if (isText()) {
@ -134,4 +145,8 @@ public class TokenParam implements IQueryParameterType {
return builder.toString();
}
public CodingDt getValueAsCoding() {
return new CodingDt(mySystem, myValue);
}
}

View File

@ -19,8 +19,6 @@ import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.api.annotation.TagListParam;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.Observation;
@ -33,7 +31,6 @@ import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.annotation.AddTags;
import ca.uhn.fhir.rest.annotation.Count;
@ -55,18 +52,19 @@ import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.annotation.VersionIdParam;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.client.ITestClient;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient;
import ca.uhn.fhir.rest.param.CodingListParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QualifiedDateParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
@ -232,9 +230,9 @@ public List<Patient> searchByNamedQuery(@RequiredParam(name="someparam") StringP
//START SNIPPET: searchIdentifierParam
@Search()
public List<Patient> searchByIdentifier(@RequiredParam(name=Patient.SP_IDENTIFIER) IdentifierDt theId) {
String identifierSystem = theId.getSystem().getValueAsString();
String identifier = theId.getValue().getValue();
public List<Patient> searchByIdentifier(@RequiredParam(name=Patient.SP_IDENTIFIER) TokenParam theId) {
String identifierSystem = theId.getSystem();
String identifier = theId.getValue();
List<Patient> retVal = new ArrayList<Patient>();
// ...populate...
@ -257,10 +255,10 @@ public List<Patient> searchByNames( @RequiredParam(name=Patient.SP_FAMILY) Strin
//START SNIPPET: searchMultiple
@Search()
public List<Observation> searchByObservationNames( @RequiredParam(name=Observation.SP_NAME) CodingListParam theCodings ) {
// This search should return any observations matching one or more
// of the codings here.
List<CodingDt> wantedCodings = theCodings.getCodings();
public List<Observation> searchByObservationNames( @RequiredParam(name=Observation.SP_NAME) TokenOrListParam theCodings ) {
// The list here will contain 0..* codings, and any observations which match any of the
// given codings should be returned
List<CodingDt> wantedCodings = theCodings.getListAsCodings();
List<Observation> retVal = new ArrayList<Observation>();
// ...populate...
@ -270,7 +268,7 @@ public List<Observation> searchByObservationNames( @RequiredParam(name=Observati
//START SNIPPET: dates
@Search()
public List<Patient> searchByObservationNames( @RequiredParam(name=Patient.SP_BIRTHDATE) QualifiedDateParam theDate ) {
public List<Patient> searchByObservationNames( @RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theDate ) {
QuantityCompararatorEnum comparator = theDate.getComparator(); // e.g. <=
Date date = theDate.getValue(); // e.g. 2011-01-02
TemporalPrecisionEnum precision = theDate.getPrecision(); // e.g. DAY
@ -284,7 +282,7 @@ public List<Patient> searchByObservationNames( @RequiredParam(name=Patient.SP_BI
public void dateClientExample() {
ITestClient client = provideTc();
//START SNIPPET: dateClient
QualifiedDateParam param = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02");
DateParam param = new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02");
List<Patient> response = client.getPatientByDob(param);
//END SNIPPET: dateClient
}
@ -318,9 +316,11 @@ public Class<? extends IResource> getResourceType() {
@Search()
public List<DiagnosticReport> getDiagnosticReport(
@RequiredParam(name=DiagnosticReport.SP_IDENTIFIER)
IdentifierDt theIdentifier,
TokenParam theIdentifier,
@IncludeParam(allow= {"DiagnosticReport.subject"})
Set<Include> theIncludes ) {
List<DiagnosticReport> retVal = new ArrayList<DiagnosticReport>();
// Assume this method exists and loads the report from the DB
@ -330,7 +330,7 @@ public List<DiagnosticReport> getDiagnosticReport(
if (theIncludes.contains(new Include("DiagnosticReport.subject"))) {
// The resource reference should contain the ID of the patient
IdDt subjectId = report.getSubject().getId();
IdDt subjectId = report.getSubject().getReference();
// So load the patient ID and return it
Patient subject = loadSomePatientFromDatabase(subjectId);
@ -348,9 +348,11 @@ public List<DiagnosticReport> getDiagnosticReport(
@Search()
public List<DiagnosticReport> getDiagnosticReport(
@RequiredParam(name=DiagnosticReport.SP_IDENTIFIER)
IdentifierDt theIdentifier,
TokenParam theIdentifier,
@IncludeParam(allow= {"DiagnosticReport.subject"})
String theInclude ) {
List<DiagnosticReport> retVal = new ArrayList<DiagnosticReport>();
// Assume this method exists and loads the report from the DB
@ -360,7 +362,7 @@ public List<DiagnosticReport> getDiagnosticReport(
if ("DiagnosticReport.subject".equals(theInclude)) {
// The resource reference should contain the ID of the patient
IdDt subjectId = report.getSubject().getId();
IdDt subjectId = report.getSubject().getReference();
// So load the patient ID and return it
Patient subject = loadSomePatientFromDatabase(subjectId);
@ -376,13 +378,13 @@ public List<DiagnosticReport> getDiagnosticReport(
//START SNIPPET: quantity
@Search()
public List<Observation> getObservationsByQuantity(
@RequiredParam(name=Observation.SP_VALUE_QUANTITY) QuantityDt theQuantity) {
@RequiredParam(name=Observation.SP_VALUE_QUANTITY) QuantityParam theQuantity) {
List<Observation> retVal = new ArrayList<Observation>();
QuantityCompararatorEnum comparator = theQuantity.getComparator().getValueAsEnum();
QuantityCompararatorEnum comparator = theQuantity.getComparator();
DecimalDt value = theQuantity.getValue();
StringDt units = theQuantity.getUnits();
String units = theQuantity.getUnits();
// .. Apply these parameters ..
// ... populate ...
@ -390,7 +392,7 @@ public List<Observation> getObservationsByQuantity(
}
//END SNIPPET: quantity
private DiagnosticReport loadSomeDiagnosticReportFromDatabase(IdentifierDt theIdentifier) {
private DiagnosticReport loadSomeDiagnosticReportFromDatabase(TokenParam theIdentifier) {
return null;
}
@ -420,10 +422,10 @@ public MethodOutcome createPatient(@ResourceParam Patient thePatient) {
savePatientToDatabase(thePatient);
// This method returns a MethodOutcome object which contains
// the ID and Version ID for the newly saved resource
// the ID (composed of the type Patient, the logical ID 3746, and the
// version ID 1)
MethodOutcome retVal = new MethodOutcome();
retVal.setId(new IdDt("3746"));
retVal.setVersionId(new IdDt("1"));
retVal.setId(new IdDt("Patient", "3746", "1"));
// You can also add an OperationOutcome resource to return
// This part is optional though:
@ -457,15 +459,25 @@ public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient t
*/
throw new UnprocessableEntityException("No identifier supplied");
}
String versionId = theId.getVersionIdPart();
if (versionId != null) {
// If the client passed in a version number in the request URL, which means they are
// doing a version-aware update. You may wish to throw an exception if the supplied
// version is not the latest version.
if (detectedVersionConflict) {
throw new ResourceVersionConflictException("Invalid version");
}
}
// Save this patient to the database...
savePatientToDatabase(theId, thePatient);
// This method returns a MethodOutcome object which contains
// the ID and Version ID for the newly saved resource
MethodOutcome retVal = new MethodOutcome();
retVal.setId(theId);
retVal.setVersionId(new IdDt("2")); // Leave this blank if the server doesn't version
String newVersion = "2"; // may be null if the server is not version aware
retVal.setId(theId.withVersion(newVersion));
// You can also add an OperationOutcome resource to return
// This part is optional though:
@ -482,21 +494,6 @@ public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient t
public abstract MethodOutcome updateSomePatient(@IdParam IdDt theId, @ResourceParam Patient thePatient);
//END SNIPPET: updateClient
//START SNIPPET: updateVersion
@Update
public MethodOutcome updatePatient(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @ResourceParam Patient thePatient) {
// ..Process..
if (detectedVersionConflict) {
throw new ResourceVersionConflictException("Invalid version");
}
MethodOutcome retVal = new MethodOutcome();
return retVal;
}
//END SNIPPET: updateVersion
//START SNIPPET: validate
@Validate
public MethodOutcome validatePatient(@ResourceParam Patient thePatient) {
@ -705,8 +702,7 @@ public class TagMethodProvider
/** Return a list of all tags that exist on a specific version
* of the given resource type */
@GetTags(type=Patient.class)
public TagList getTagsForResourceVersion(@IdParam IdDt theId,
@VersionIdParam IdDt theVersion) {
public TagList getTagsForResourceVersion(@IdParam IdDt theId) {
return new TagList(); // populate this
}
@ -720,7 +716,6 @@ public class TagMethodProvider
/** Add tags to a resource version */
@AddTags(type=Patient.class)
public void addTagsToResourceVersion(@IdParam IdDt theId,
@VersionIdParam IdDt theVersion,
@TagListParam TagList theTagList) {
// add tags
}
@ -732,14 +727,6 @@ public class TagMethodProvider
// add tags
}
/** Remove tags from a resource version */
@DeleteTags(type=Patient.class)
public void deleteTagsFromResourceVersion(@IdParam IdDt theId,
@VersionIdParam IdDt theVersion,
@TagListParam TagList theTagList) {
// add tags
}
}
//END SNIPPET: tagMethodProvider

View File

@ -314,16 +314,6 @@
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
</macro>
<p>
In the case of a server which is able to do version conflict checking, an
extra parameter would be added:
</p>
<macro name="snippet">
<param name="id" value="updateVersion" />
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
</macro>
<a name="instance_delete" />
</section>

View File

@ -1,8 +1,11 @@
package ca.uhn.fhir.rest.client;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.InputStream;
import java.io.StringReader;
@ -22,7 +25,6 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import org.hamcrest.core.StringContains;
import org.hamcrest.core.StringEndsWith;
@ -36,14 +38,12 @@ import org.mockito.stubbing.Answer;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.PathSpecification;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Patient;
@ -51,7 +51,6 @@ import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
@ -59,10 +58,12 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.param.CodingListParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QualifiedDateParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -141,7 +142,7 @@ public class ClientTest {
HttpPost post = (HttpPost) capt.getValue();
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
assertEquals("200", response.getVersionId().getValue());
assertEquals("200", response.getId().getVersionIdPart());
}
@Test
@ -187,7 +188,7 @@ public class ClientTest {
HttpPost post = (HttpPost) capt.getValue();
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
assertEquals("200", response.getVersionId().getValue());
assertEquals("200", response.getId().getVersionIdPart());
}
@Test
@ -215,7 +216,7 @@ public class ClientTest {
HttpPost post = (HttpPost) capt.getValue();
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
assertEquals("200", response.getVersionId().getValue());
assertEquals("200", response.getId().getVersionIdPart());
Header[] headers = post.getHeaders("Category");
assertEquals(2, headers.length);
@ -701,8 +702,8 @@ public class ClientTest {
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
DateRangeParam param = new DateRangeParam();
param.setLowerBound(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-01"));
param.setUpperBound(new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, "2021-01-01"));
param.setLowerBound(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-01"));
param.setUpperBound(new DateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, "2021-01-01"));
client.getPatientByDateRange(param);
assertEquals("http://foo/Patient?dateRange=%3E%3D2011-01-01&dateRange=%3C%3D2021-01-01", capt.getValue().getURI().toString());
@ -724,7 +725,7 @@ public class ClientTest {
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
List<Patient> response = client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
List<Patient> response = client.getPatientByDob(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02", capt.getValue().getURI().toString());
assertEquals("PRP1660", response.get(0).getIdentifier().get(0).getValue().getValue());
@ -743,7 +744,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
Patient response = client.findPatientQuantity(new QuantityDt(QuantityCompararatorEnum.GREATERTHAN, 123L, "foo", "bar"));
Patient response = client.findPatientQuantity(new QuantityParam(QuantityCompararatorEnum.GREATERTHAN, 123L, "foo", "bar"));
assertEquals("http://foo/Patient?quantityParam=%3E123%7Cfoo%7Cbar", capt.getValue().getURI().toString());
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
@ -762,7 +763,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
Patient response = client.findPatientByMrn(new TokenParam("urn:foo", "123"));
assertEquals("http://foo/Patient?identifier=urn%3Afoo%7C123", capt.getValue().getURI().toString());
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
@ -781,7 +782,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
CodingListParam identifiers = new CodingListParam();
TokenOrListParam identifiers = new TokenOrListParam();
identifiers.add(new CodingDt("foo", "bar"));
identifiers.add(new CodingDt("baz", "boz"));
client.getPatientMultipleIdentifiers(identifiers);
@ -820,7 +821,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
client.getPatientOneParam(new StringDt("BB"));
client.getPatientOneParam(new StringParam("BB"));
assertEquals("http://foo/Patient?_query=someQueryOneParam&param1=BB", capt.getValue().getURI().toString());
@ -838,7 +839,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClientWithCustomType client = ctx.newRestfulClient(ITestClientWithCustomType.class, "http://foo");
CustomPatient response = client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
CustomPatient response = client.getPatientByDob(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02", capt.getValue().getURI().toString());
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
@ -857,7 +858,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClientWithCustomTypeList client = ctx.newRestfulClient(ITestClientWithCustomTypeList.class, "http://foo");
List<CustomPatient> response = client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
List<CustomPatient> response = client.getPatientByDob(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02", capt.getValue().getURI().toString());
assertEquals("PRP1660", response.get(0).getIdentifier().get(0).getValue().getValue());
@ -878,18 +879,18 @@ public class ClientTest {
// TODO: document this
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
client.getPatientByDob(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02", capt.getAllValues().get(0).getURI().toString());
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
client.setEncoding(EncodingEnum.JSON); // this needs to be actually
// implemented
client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
client.getPatientByDob(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02&_format=json", capt.getAllValues().get(1).getURI().toString());
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
client.setPrettyPrint(true);
client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
client.getPatientByDob(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02"));
assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02&_format=json&_pretty=true", capt.getAllValues().get(2).getURI().toString());
}
@ -906,7 +907,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
client.getPatientWithIncludes(new StringDt("aaa"), Arrays.asList(new PathSpecification[] { new PathSpecification("inc1"), new PathSpecification("inc2") }));
client.getPatientWithIncludes(new StringParam("aaa"), Arrays.asList(new Include[] { new Include("inc1"), new Include("inc2") }));
assertEquals("http://foo/Patient?withIncludes=aaa&_include=inc1&_include=inc2", capt.getValue().getURI().toString());
@ -924,7 +925,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
Bundle response = client.findPatientByName(new StringDt("AAA"), null);
Bundle response = client.findPatientByName(new StringParam("AAA"), null);
assertEquals("http://foo/Patient?family=AAA", capt.getValue().getURI().toString());
Patient resource = (Patient) response.getEntries().get(0).getResource();
@ -936,7 +937,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
client = ctx.newRestfulClient(ITestClient.class, "http://foo");
response = client.findPatientByName(new StringDt("AAA"), new StringDt("BBB"));
response = client.findPatientByName(new StringParam("AAA"), new StringParam("BBB"));
assertEquals("http://foo/Patient?family=AAA&given=BBB", capt.getValue().getURI().toString());
resource = (Patient) response.getEntries().get(0).getResource();
@ -956,7 +957,7 @@ public class ClientTest {
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
ITestClientWithStringIncludes client = ctx.newRestfulClient(ITestClientWithStringIncludes.class, "http://foo");
client.getPatientWithIncludes(new StringDt("aaa"), "inc1");
client.getPatientWithIncludes(new StringParam("aaa"), "inc1");
assertEquals("http://foo/Patient?withIncludes=aaa&_include=inc1", capt.getValue().getURI().toString());
@ -983,7 +984,7 @@ public class ClientTest {
assertThat(post.getURI().toASCIIString(), StringEndsWith.endsWith("/Patient/100"));
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
assertEquals("200", response.getVersionId().getValue());
assertEquals("200", response.getId().getVersionIdPart());
}
/**
@ -1000,10 +1001,18 @@ public class ClientTest {
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8")));
when(httpResponse.getAllHeaders()).thenReturn(toHeaderArray("Location", "http://example.com/fhir/Patient/100/_history/200"));
when(httpResponse.getAllHeaders()).thenReturn(toHeaderArray("Content-Location", "http://example.com/fhir/Patient/100/_history/200"));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
client.updatePatient(new IdDt("100"), new IdDt("200"), patient);
client.updatePatient(new IdDt("Patient/100/_history/200"), patient);
assertEquals(HttpPut.class, capt.getValue().getClass());
HttpPut post = (HttpPut) capt.getValue();
assertEquals("http://foo/Patient/100", post.getURI().toASCIIString());
Header h = post.getFirstHeader("content-location");
assertEquals("Patient/100/_history/200", h.getValue());
}
@Test(expected = ResourceVersionConflictException.class)
@ -1019,7 +1028,7 @@ public class ClientTest {
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), Constants.STATUS_HTTP_409_CONFLICT, "Conflict"));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
client.updatePatient(new IdDt("100"), new IdDt("200"), patient);
client.updatePatient(new IdDt("Patient/100/_history/200"), patient);
}
@Test
@ -1036,15 +1045,15 @@ public class ClientTest {
when(httpResponse.getAllHeaders()).thenReturn(toHeaderArray("Location", "http://example.com/fhir/Patient/100/_history/200"));
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
MethodOutcome response = client.updatePatient(new IdDt("100"), new IdDt("200"), patient);
MethodOutcome response = client.updatePatient(new IdDt("Patient/100/_history/200"), patient);
assertEquals(HttpPut.class, capt.getValue().getClass());
HttpPut post = (HttpPut) capt.getValue();
assertThat(post.getURI().toASCIIString(), StringEndsWith.endsWith("/Patient/100"));
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
assertThat(post.getFirstHeader("Content-Location").getValue(), StringEndsWith.endsWith("/Patient/100/_history/200"));
assertThat(post.getFirstHeader("Content-Location").getValue(), StringEndsWith.endsWith("Patient/100/_history/200"));
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
assertEquals("200", response.getVersionId().getValue());
assertEquals("200", response.getId().getVersionIdPart());
}
@Test
@ -1068,7 +1077,7 @@ public class ClientTest {
assertThat(post.getURI().toASCIIString(), StringEndsWith.endsWith("/Patient/_validate"));
assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString("<Patient"));
assertEquals("http://example.com/fhir/Patient/100/_history/200", response.getId().getValue());
assertEquals("200", response.getVersionId().getValue());
assertEquals("200", response.getId().getVersionIdPart());
}
@ -1096,7 +1105,7 @@ public class ClientTest {
ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo");
// Patient response = client.findPatientByMrn(new
// IdentifierDt("urn:foo", "123"));
Patient response = client.getPatientByVersionId(new IdDt("111"), new IdDt("999"));
Patient response = client.getPatientById(new IdDt("Patient/111/_history/999"));
assertEquals("http://foo/Patient/111/_history/999", capt.getValue().getURI().toString());
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
@ -1118,16 +1127,16 @@ public class ClientTest {
public interface ITestClientWithCustomType extends IBasicClient {
@Search()
public CustomPatient getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate);
public CustomPatient getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
}
public interface ITestClientWithCustomTypeList extends IBasicClient {
@Search()
public List<CustomPatient> getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate);
public List<CustomPatient> getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
}
public interface ITestClientWithStringIncludes extends IBasicClient {
@Search()
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringDt theString, @IncludeParam String theInclude);
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam String theInclude);
}
}

View File

@ -0,0 +1,154 @@
package ca.uhn.fhir.rest.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.StringReader;
import java.nio.charset.Charset;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine;
import org.hamcrest.core.StringContains;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class ExceptionHandlingTest {
private static FhirContext myCtx;
private HttpClient myHttpClient;
private HttpResponse myHttpResponse;
@BeforeClass
public static void beforeClass() {
myCtx = new FhirContext();
}
@Before
public void before() {
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
myCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
}
@Test
public void testFail500WithPlainMessage() throws Exception {
String msg = "Help I'm a bug";
String contentType = Constants.CT_TEXT;
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "Internal Error"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", contentType + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
try {
client.read(Patient.class, new IdDt("Patient/1234"));
fail();
} catch (InternalErrorException e) {
assertThat(e.getMessage(), StringContains.containsString("HTTP 500 Internal Error"));
assertThat(e.getMessage(), StringContains.containsString("Help I'm a bug"));
}
}
@Test
public void testFail500WithOperationOutcomeMessage() throws Exception {
OperationOutcome oo = new OperationOutcome();
oo.getIssueFirstRep().getDetails().setValue("Help I'm a bug");
String msg = myCtx.newXmlParser().encodeResourceToString(oo);
String contentType = Constants.CT_FHIR_XML;
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "Internal Error"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", contentType + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
try {
client.read(Patient.class, new IdDt("Patient/1234"));
fail();
} catch (InternalErrorException e) {
assertThat(e.getMessage(), StringContains.containsString("HTTP 500 Internal Error"));
assertThat(e.getMessage(), StringContains.containsString("Help I'm a bug"));
}
}
@Test
public void testFail500WithUnexpectedResource() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setSystem("foo").setValue("bar");
String msg = myCtx.newXmlParser().encodeResourceToString(patient);
String contentType = Constants.CT_FHIR_XML;
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "Internal Error"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", contentType + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
try {
client.read(Patient.class, new IdDt("Patient/1234"));
fail();
} catch (InternalErrorException e) {
assertEquals("HTTP 500 Internal Error", e.getMessage());
assertThat(e.getResponseBody(), StringContains.containsString("value=\"foo\""));
}
}
@Test
public void testFail500WithOperationOutcomeMessageJson() throws Exception {
OperationOutcome oo = new OperationOutcome();
oo.getIssueFirstRep().getDetails().setValue("Help I'm a bug");
String msg = myCtx.newJsonParser().encodeResourceToString(oo);
String contentType = Constants.CT_FHIR_JSON;
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "Internal Error"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", contentType + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
try {
client.read(Patient.class, new IdDt("Patient/1234"));
fail();
} catch (InternalErrorException e) {
assertThat(e.getMessage(), StringContains.containsString("HTTP 500 Internal Error"));
assertThat(e.getMessage(), StringContains.containsString("Help I'm a bug"));
}
}
}

View File

@ -507,7 +507,6 @@ public class GenericClientTest {
}
@Test
public void testRead() throws Exception {

View File

@ -4,15 +4,12 @@ import java.util.Date;
import java.util.List;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.PathSpecification;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.Count;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
@ -27,12 +24,14 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.annotation.VersionIdParam;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.param.CodingListParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QualifiedDateParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
public interface ITestClient extends IBasicClient {
@ -43,23 +42,20 @@ public interface ITestClient extends IBasicClient {
public List<Patient> getPatientByDateRange(@RequiredParam(name = "dateRange") DateRangeParam theIdentifiers);
@Search()
public List<Patient> getPatientByDob(@RequiredParam(name=Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate);
public List<Patient> getPatientByDob(@RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate);
@Search()
public List<Patient> getPatientMultipleIdentifiers(@RequiredParam(name = "ids") CodingListParam theIdentifiers);
public List<Patient> getPatientMultipleIdentifiers(@RequiredParam(name = "ids") TokenOrListParam theIdentifiers);
@Search(queryName="someQueryNoParams")
public Patient getPatientNoParams();
@Search(queryName="someQueryOneParam")
public Patient getPatientOneParam(@RequiredParam(name="param1") StringDt theParam);
public Patient getPatientOneParam(@RequiredParam(name="param1") StringParam theParam);
@Search()
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringDt theString, @IncludeParam List<PathSpecification> theIncludes);
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam List<Include> theIncludes);
@Update
public MethodOutcome updatePatient(@IdParam IdDt theId, @VersionIdParam IdDt theVersion, @ResourceParam Patient thePatient);
@Update
public MethodOutcome updatePatient(@IdParam IdDt theId, @ResourceParam Patient thePatient);
@ -70,10 +66,10 @@ public interface ITestClient extends IBasicClient {
MethodOutcome deletePatient(@IdParam IdDt theId);
@Search(type=Patient.class)
Patient findPatientByMrn(@RequiredParam(name = Patient.SP_IDENTIFIER) IdentifierDt theId);
Patient findPatientByMrn(@RequiredParam(name = Patient.SP_IDENTIFIER) TokenParam theId);
@Search(type=Patient.class)
Bundle findPatientByName(@RequiredParam(name = Patient.SP_FAMILY) StringDt theId, @OptionalParam(name=Patient.SP_GIVEN) StringDt theGiven);
Bundle findPatientByName(@RequiredParam(name = Patient.SP_FAMILY) StringParam theId, @OptionalParam(name=Patient.SP_GIVEN) StringParam theGiven);
@History(type=Patient.class)
Bundle getHistoryPatientInstance(@IdParam IdDt theId);
@ -93,13 +89,10 @@ public interface ITestClient extends IBasicClient {
@Read(type=Patient.class)
Patient getPatientById(@IdParam IdDt theId);
@Read(type=Patient.class)
Patient getPatientByVersionId(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId);
@Validate(type=Patient.class)
MethodOutcome validatePatient(@ResourceParam Patient thePatient);
@Search(type=Patient.class)
Patient findPatientQuantity(@RequiredParam(name="quantityParam") QuantityDt theQuantityDt);
Patient findPatientQuantity(@RequiredParam(name="quantityParam") QuantityParam theQuantityDt);
}