Fluent interface is basically working
This commit is contained in:
parent
e66bd31171
commit
86e5948d60
|
@ -65,6 +65,7 @@ import ca.uhn.fhir.model.primitive.BooleanDt;
|
|||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeableConceptDt;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.rest.gclient.NumberParam;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -90,6 +91,7 @@ import ca.uhn.fhir.model.primitive.CodeDt;
|
|||
@ResourceDef(name="Encounter", profile="http://hl7.org/fhir/profiles/Encounter", id="encounter")
|
||||
public class Encounter extends BaseResource implements IResource {
|
||||
|
||||
|
||||
/**
|
||||
* Search parameter constant for <b>identifier</b>
|
||||
* <p>
|
||||
|
@ -156,6 +158,8 @@ public class Encounter extends BaseResource implements IResource {
|
|||
@SearchParamDefinition(name="length", path="Encounter.length", description="Length of encounter in days")
|
||||
public static final String SP_LENGTH = "length";
|
||||
|
||||
public static final NumberParam LENGTH = new NumberParam(SP_LENGTH);
|
||||
|
||||
/**
|
||||
* Search parameter constant for <b>indication</b>
|
||||
* <p>
|
||||
|
|
|
@ -73,6 +73,7 @@ import ca.uhn.fhir.model.primitive.CodeDt;
|
|||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.gclient.QuantityParam;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -120,6 +121,8 @@ public class Observation extends BaseResource implements IResource {
|
|||
@SearchParamDefinition(name="value-quantity", path="Observation.value[x]", description="The value of the observation, if the value is a Quantity, or a SampledData (just search on the bounds of the values in sampled data)")
|
||||
public static final String SP_VALUE_QUANTITY = "value-quantity";
|
||||
|
||||
public static final QuantityParam VALUE_QUANTITY = new QuantityParam(SP_VALUE_QUANTITY);
|
||||
|
||||
/**
|
||||
* Search parameter constant for <b>value-concept</b>
|
||||
* <p>
|
||||
|
|
|
@ -69,7 +69,8 @@ public class IdDt extends BasePrimitive<String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a new ID using a string
|
||||
* Create a new ID using a string. This String may contain a simple ID (e.g. "1234")
|
||||
* or it may contain a complete URL (http://example.com/fhir/Patient/1234).
|
||||
*
|
||||
* <p>
|
||||
* <b>Description</b>: A whole number in the range 0 to 2^64-1 (optionally represented in hex), a uuid, an oid, or any other combination of lowercase letters, numerals, "-" and ".", with a length
|
||||
|
@ -84,6 +85,10 @@ public class IdDt extends BasePrimitive<String> {
|
|||
setValue(theValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of this ID as a big decimal, or <code>null</code> if the value is null
|
||||
*
|
||||
|
|
|
@ -42,9 +42,9 @@ import ca.uhn.fhir.parser.IParser;
|
|||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.gclient.ICriterion;
|
||||
import ca.uhn.fhir.rest.gclient.ICriterionInternal;
|
||||
import ca.uhn.fhir.rest.gclient.IFor;
|
||||
import ca.uhn.fhir.rest.gclient.IParam;
|
||||
import ca.uhn.fhir.rest.gclient.IQuery;
|
||||
import ca.uhn.fhir.rest.gclient.IParam;
|
||||
import ca.uhn.fhir.rest.gclient.IUntypedQuery;
|
||||
import ca.uhn.fhir.rest.gclient.ISort;
|
||||
import ca.uhn.fhir.rest.gclient.Include;
|
||||
import ca.uhn.fhir.rest.method.BaseOutcomeReturningMethodBinding;
|
||||
|
@ -139,6 +139,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome delete(Class<? extends IResource> theType, String theId) {
|
||||
return delete(theType, new IdDt(theId));
|
||||
}
|
||||
|
||||
public HttpRequestBase getLastRequest() {
|
||||
return myLastRequest;
|
||||
}
|
||||
|
@ -164,6 +169,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IResource> Bundle history(Class<T> theType, String theId) {
|
||||
return history(theType, new IdDt(theId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IResource> T read(final Class<T> theType, IdDt theId) {
|
||||
GetClientInvocation invocation = ReadMethodBinding.createReadInvocation(theId, toResourceName(theType));
|
||||
|
@ -186,7 +196,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IQuery search() {
|
||||
public <T extends IResource> T read(Class<T> theType, String theId) {
|
||||
return read(theType, new IdDt(theId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IUntypedQuery search() {
|
||||
return new QueryInternal();
|
||||
}
|
||||
|
||||
|
@ -249,6 +264,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome update(String theId, IResource theResource) {
|
||||
return update(new IdDt(theId), theResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome validate(IResource theResource) {
|
||||
BaseClientInvocation invocation = ValidateMethodBinding.createValidateInvocation(theResource, null, myContext);
|
||||
|
@ -292,20 +312,25 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IResource> T vread(Class<T> theType, String theId, String theVersionId) {
|
||||
return vread(theType, new IdDt(theId), new IdDt(theVersionId));
|
||||
}
|
||||
|
||||
private String toResourceName(Class<? extends IResource> theType) {
|
||||
return myContext.getResourceDefinition(theType).getName();
|
||||
}
|
||||
|
||||
private class ForInternal implements IFor {
|
||||
private class ForInternal implements IQuery {
|
||||
|
||||
private List<ICriterionInternal> myCriterion = new ArrayList<ICriterionInternal>();
|
||||
private List<Include> myInclude = new ArrayList<Include>();
|
||||
private boolean myLogRequestAndResponse;
|
||||
private EncodingEnum myParamEncoding;
|
||||
private Integer myParamLimit;
|
||||
private String myResourceName;
|
||||
private Class<? extends IResource> myResourceType;
|
||||
private List<SortInternal> mySort = new ArrayList<SortInternal>();
|
||||
private boolean myLogRequestAndResponse;
|
||||
|
||||
public ForInternal(Class<? extends IResource> theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
|
@ -318,19 +343,25 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IFor and(ICriterion theCriterion) {
|
||||
public IQuery and(ICriterion theCriterion) {
|
||||
myCriterion.add((ICriterionInternal) theCriterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor encodedJson() {
|
||||
public IQuery andLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
||||
myLogRequestAndResponse = theLogRequestAndResponse;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery encodedJson() {
|
||||
myParamEncoding = EncodingEnum.JSON;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor encodedXml() {
|
||||
public IQuery encodedXml() {
|
||||
myParamEncoding = EncodingEnum.XML;
|
||||
return null;
|
||||
}
|
||||
|
@ -387,13 +418,13 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IFor include(Include theInclude) {
|
||||
public IQuery include(Include theInclude) {
|
||||
myInclude.add(theInclude);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor limitTo(int theLimitTo) {
|
||||
public IQuery limitTo(int theLimitTo) {
|
||||
if (theLimitTo > 0) {
|
||||
myParamLimit = theLimitTo;
|
||||
} else {
|
||||
|
@ -410,7 +441,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IFor where(ICriterion theCriterion) {
|
||||
public IQuery where(ICriterion theCriterion) {
|
||||
myCriterion.add((ICriterionInternal) theCriterion);
|
||||
return this;
|
||||
}
|
||||
|
@ -422,24 +453,18 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
params.get(parameterName).add(parameterValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor andLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
||||
myLogRequestAndResponse =theLogRequestAndResponse;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class QueryInternal implements IQuery {
|
||||
private class QueryInternal implements IUntypedQuery {
|
||||
|
||||
@Override
|
||||
public IFor forResource(String theResourceName) {
|
||||
return new ForInternal(theResourceName);
|
||||
public IQuery forResource(Class<? extends IResource> theResourceType) {
|
||||
return new ForInternal(theResourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor forResource(Class<? extends IResource> theResourceType) {
|
||||
return new ForInternal(theResourceType);
|
||||
public IQuery forResource(String theResourceName) {
|
||||
return new ForInternal(theResourceName);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -455,21 +480,21 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IFor ascending(IParam theParam) {
|
||||
public IQuery ascending(IParam theParam) {
|
||||
myParamName = Constants.PARAM_SORT_ASC;
|
||||
myParamValue = theParam.getParamName();
|
||||
return myFor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor defaultOrder(IParam theParam) {
|
||||
public IQuery defaultOrder(IParam theParam) {
|
||||
myParamName = Constants.PARAM_SORT;
|
||||
myParamValue = theParam.getParamName();
|
||||
return myFor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFor descending(IParam theParam) {
|
||||
public IQuery descending(IParam theParam) {
|
||||
myParamName = Constants.PARAM_SORT_DESC;
|
||||
myParamValue = theParam.getParamName();
|
||||
return myFor;
|
||||
|
|
|
@ -29,71 +29,10 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.gclient.IQuery;
|
||||
import ca.uhn.fhir.rest.gclient.IUntypedQuery;
|
||||
|
||||
public interface IGenericClient {
|
||||
|
||||
/**
|
||||
* Implementation of the "instance read" method.
|
||||
*
|
||||
* @param theType The type of resource to load
|
||||
* @param theId The ID to load
|
||||
* @return The resource
|
||||
*/
|
||||
<T extends IResource> T read(Class<T> theType, IdDt theId);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance vread" method.
|
||||
*
|
||||
* @param theType The type of resource to load
|
||||
* @param theId The ID to load
|
||||
* @param theVersionId The version ID
|
||||
* @return The resource
|
||||
*/
|
||||
<T extends IResource> T vread(Class<T> theType, IdDt theId, IdDt theVersionId);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance search" method.
|
||||
* @param theType The type of resource to load
|
||||
* @param theParams
|
||||
* @return
|
||||
*/
|
||||
<T extends IResource> Bundle search(Class<T> theType, Map<String, List<IQueryParameterType>> theParams);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance update" method.
|
||||
*
|
||||
* @param theId The ID to update
|
||||
* @param theResource The new resource body
|
||||
* @return An outcome containing the results and possibly the new version ID
|
||||
*/
|
||||
MethodOutcome update(IdDt theIdDt, IResource theResource);
|
||||
|
||||
/**
|
||||
* Implementation of the "type validate" method.
|
||||
*
|
||||
* @param theId The ID to validate
|
||||
* @param theResource The resource to validate
|
||||
* @return An outcome containing any validation issues
|
||||
*/
|
||||
MethodOutcome validate(IResource theResource);
|
||||
|
||||
/**
|
||||
* Implementation of the "delete instance" method.
|
||||
* @param theType The type of resource to delete
|
||||
* @param theId the ID of the resource to delete
|
||||
* @return An outcome
|
||||
*/
|
||||
MethodOutcome delete(Class<? extends IResource> theType, IdDt theId);
|
||||
|
||||
/**
|
||||
* Implementation of the "history instance" method.
|
||||
* @param theType The type of resource to return the history for
|
||||
* @param theId the ID of the resource to return the history for
|
||||
* @return An outcome
|
||||
*/
|
||||
<T extends IResource> Bundle history(Class<T> theType, IdDt theIdDt);
|
||||
|
||||
/**
|
||||
* Retrieves and returns the server conformance statement
|
||||
*/
|
||||
|
@ -101,11 +40,148 @@ public interface IGenericClient {
|
|||
|
||||
/**
|
||||
* Implementation of the "type create" method.
|
||||
* @param theResource The resource to create
|
||||
*
|
||||
* @param theResource
|
||||
* The resource to create
|
||||
* @return An outcome
|
||||
*/
|
||||
MethodOutcome create(IResource theResource);
|
||||
|
||||
IQuery search();
|
||||
/**
|
||||
* Implementation of the "delete instance" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to delete
|
||||
* @param theId
|
||||
* the ID of the resource to delete
|
||||
* @return An outcome
|
||||
*/
|
||||
MethodOutcome delete(Class<? extends IResource> theType, IdDt theId);
|
||||
|
||||
/**
|
||||
* Implementation of the "delete instance" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to delete
|
||||
* @param theId
|
||||
* the ID of the resource to delete
|
||||
* @return An outcome
|
||||
*/
|
||||
MethodOutcome delete(Class<? extends IResource> theType, String theId);
|
||||
|
||||
/**
|
||||
* Implementation of the "history instance" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to return the history for
|
||||
* @param theId
|
||||
* the ID of the resource to return the history for
|
||||
* @return An outcome
|
||||
*/
|
||||
<T extends IResource> Bundle history(Class<T> theType, IdDt theIdDt);
|
||||
|
||||
/**
|
||||
* Implementation of the "history instance" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to return the history for
|
||||
* @param theId
|
||||
* the ID of the resource to return the history for
|
||||
* @return An outcome
|
||||
*/
|
||||
<T extends IResource> Bundle history(Class<T> theType, String theIdDt);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance read" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to load
|
||||
* @param theId
|
||||
* The ID to load
|
||||
* @return The resource
|
||||
*/
|
||||
<T extends IResource> T read(Class<T> theType, IdDt theId);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance read" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to load
|
||||
* @param theId
|
||||
* The ID to load
|
||||
* @return The resource
|
||||
*/
|
||||
<T extends IResource> T read(Class<T> theType, String theId);
|
||||
|
||||
IUntypedQuery search();
|
||||
|
||||
/**
|
||||
* Implementation of the "instance search" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to load
|
||||
* @param theParams
|
||||
* @return
|
||||
*/
|
||||
<T extends IResource> Bundle search(Class<T> theType, Map<String, List<IQueryParameterType>> theParams);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance update" method.
|
||||
*
|
||||
* @param theId
|
||||
* The ID to update
|
||||
* @param theResource
|
||||
* The new resource body
|
||||
* @return An outcome containing the results and possibly the new version ID
|
||||
*/
|
||||
MethodOutcome update(IdDt theIdDt, IResource theResource);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance update" method.
|
||||
*
|
||||
* @param theId
|
||||
* The ID to update
|
||||
* @param theResource
|
||||
* The new resource body
|
||||
* @return An outcome containing the results and possibly the new version ID
|
||||
*/
|
||||
MethodOutcome update(String theIdDt, IResource theResource);
|
||||
|
||||
/**
|
||||
* Implementation of the "type validate" method.
|
||||
*
|
||||
* @param theId
|
||||
* The ID to validate
|
||||
* @param theResource
|
||||
* The resource to validate
|
||||
* @return An outcome containing any validation issues
|
||||
*/
|
||||
MethodOutcome validate(IResource theResource);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance vread" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to load
|
||||
* @param theId
|
||||
* The ID to load
|
||||
* @param theVersionId
|
||||
* The version ID
|
||||
* @return The resource
|
||||
*/
|
||||
<T extends IResource> T vread(Class<T> theType, IdDt theId, IdDt theVersionId);
|
||||
|
||||
/**
|
||||
* Implementation of the "instance vread" method.
|
||||
*
|
||||
* @param theType
|
||||
* The type of resource to load
|
||||
* @param theId
|
||||
* The ID to load
|
||||
* @param theVersionId
|
||||
* The version ID
|
||||
* @return The resource
|
||||
*/
|
||||
<T extends IResource> T vread(Class<T> theType, String theId, String theVersionId);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
|
||||
public interface IFor {
|
||||
|
||||
IFor where(ICriterion theCriterion);
|
||||
|
||||
IFor and(ICriterion theCriterion);
|
||||
|
||||
Bundle execute();
|
||||
|
||||
IFor include(Include theIncludeManagingorganization);
|
||||
|
||||
IFor encodedJson();
|
||||
|
||||
IFor encodedXml();
|
||||
|
||||
ISort sort();
|
||||
|
||||
IFor limitTo(int theLimitTo);
|
||||
|
||||
/**
|
||||
* If set to true, the client will log the request and response to the SLF4J logger. This
|
||||
* can be useful for debugging, but is generally not desirable in a production situation.
|
||||
*/
|
||||
IFor andLogRequestAndResponse(boolean theLogRequestAndResponse);
|
||||
|
||||
}
|
|
@ -1,12 +1,29 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
|
||||
public interface IQuery {
|
||||
|
||||
IFor forResource(String theResourceName);
|
||||
IQuery where(ICriterion theCriterion);
|
||||
|
||||
IQuery and(ICriterion theCriterion);
|
||||
|
||||
Bundle execute();
|
||||
|
||||
IFor forResource(Class<? extends IResource> theClass);
|
||||
IQuery include(Include theIncludeManagingorganization);
|
||||
|
||||
IQuery encodedJson();
|
||||
|
||||
IQuery encodedXml();
|
||||
|
||||
ISort sort();
|
||||
|
||||
IQuery limitTo(int theLimitTo);
|
||||
|
||||
/**
|
||||
* If set to true, the client will log the request and response to the SLF4J logger. This
|
||||
* can be useful for debugging, but is generally not desirable in a production situation.
|
||||
*/
|
||||
IQuery andLogRequestAndResponse(boolean theLogRequestAndResponse);
|
||||
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ package ca.uhn.fhir.rest.gclient;
|
|||
|
||||
public interface ISort {
|
||||
|
||||
IFor ascending(IParam theParam);
|
||||
IQuery ascending(IParam theParam);
|
||||
|
||||
IFor defaultOrder(IParam theParam);
|
||||
IQuery defaultOrder(IParam theParam);
|
||||
|
||||
IFor descending(IParam theParam);
|
||||
IQuery descending(IParam theParam);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
|
||||
public interface IUntypedQuery {
|
||||
|
||||
IQuery forResource(String theResourceName);
|
||||
|
||||
IQuery forResource(Class<? extends IResource> theClass);
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/**
|
||||
* Token parameter type for use in fluent client interfaces
|
||||
*/
|
||||
public class NumberParam implements IParam {
|
||||
|
||||
private String myParamName;
|
||||
|
||||
public NumberParam(String theParamName) {
|
||||
myParamName = theParamName;
|
||||
}
|
||||
|
||||
public IMatches<ICriterion> exactly() {
|
||||
return new IMatches<ICriterion>() {
|
||||
@Override
|
||||
public ICriterion number(long theNumber) {
|
||||
return new StringCriterion(getParamName(), Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion number(String theNumber) {
|
||||
return new StringCriterion(getParamName(), (theNumber));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParamName() {
|
||||
return myParamName;
|
||||
}
|
||||
|
||||
public IMatches<ICriterion> greaterThan() {
|
||||
return new IMatches<ICriterion>() {
|
||||
@Override
|
||||
public ICriterion number(long theNumber) {
|
||||
return new StringCriterion(getParamName(), ">" + Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion number(String theNumber) {
|
||||
return new StringCriterion(getParamName(), ">" + (theNumber));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<ICriterion> greaterThanOrEqual() {
|
||||
return new IMatches<ICriterion>() {
|
||||
@Override
|
||||
public ICriterion number(long theNumber) {
|
||||
return new StringCriterion(getParamName(), ">=" + Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion number(String theNumber) {
|
||||
return new StringCriterion(getParamName(), ">=" + (theNumber));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<ICriterion> lessThan() {
|
||||
return new IMatches<ICriterion>() {
|
||||
@Override
|
||||
public ICriterion number(long theNumber) {
|
||||
return new StringCriterion(getParamName(), "<" + Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion number(String theNumber) {
|
||||
return new StringCriterion(getParamName(), "<" + (theNumber));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<ICriterion> lessThanOrEqual() {
|
||||
return new IMatches<ICriterion>() {
|
||||
@Override
|
||||
public ICriterion number(long theNumber) {
|
||||
return new StringCriterion(getParamName(), "<=" + Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion number(String theNumber) {
|
||||
return new StringCriterion(getParamName(), "<=" + (theNumber));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public interface IMatches<T> {
|
||||
/**
|
||||
* Creates a search criterion that matches against the given number
|
||||
*
|
||||
* @param theNumber
|
||||
* The number
|
||||
* @return A criterion
|
||||
*/
|
||||
T number(long theNumber);
|
||||
|
||||
/**
|
||||
* Creates a search criterion that matches against the given number
|
||||
*
|
||||
* @param theNumber
|
||||
* The number
|
||||
* @return A criterion
|
||||
*/
|
||||
T number(String theNumber);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.rest.gclient.NumberParam.IMatches;
|
||||
|
||||
/**
|
||||
* Token parameter type for use in fluent client interfaces
|
||||
*/
|
||||
public class QuantityParam implements IParam {
|
||||
|
||||
private String myParamName;
|
||||
|
||||
@Override
|
||||
public String getParamName() {
|
||||
return myParamName;
|
||||
}
|
||||
|
||||
public QuantityParam(String theParamName) {
|
||||
myParamName = theParamName;
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> exactly() {
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits("", Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits("", theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> greaterThan() {
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits(">", Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits(">", theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> greaterThanOrEquals() {
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits(">=", Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits(">=", theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> approximately() {
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits("~", Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits("~", theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> withComparator(QuantityCompararatorEnum theComparator) {
|
||||
final String cmp = theComparator != null ? theComparator.getCode() : "";
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits(cmp, Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits(cmp, theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> lessThan() {
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits("<", Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits("<", theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public IMatches<IAndUnits> lessThanOrEquals() {
|
||||
return new NumberParam.IMatches<IAndUnits>() {
|
||||
@Override
|
||||
public IAndUnits number(long theNumber) {
|
||||
return new AndUnits("<=", Long.toString(theNumber));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAndUnits number(String theNumber) {
|
||||
return new AndUnits("<=", theNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class AndUnits implements IAndUnits {
|
||||
|
||||
private String myToken1;
|
||||
|
||||
public AndUnits(String theComparator, String theNumber) {
|
||||
myToken1 = StringUtils.defaultString(theComparator) + StringUtils.defaultString(theNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion andUnits(String theUnits) {
|
||||
return andUnits(theUnits, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion andUnits(String theSystem, String theUnits) {
|
||||
return new StringCriterion(getParamName(), myToken1 + "|" + defaultString(theSystem) + "|" + defaultString(theUnits));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICriterion andNoUnits() {
|
||||
return andUnits(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IAndUnits {
|
||||
|
||||
ICriterion andNoUnits();
|
||||
|
||||
ICriterion andUnits(String theUnits);
|
||||
|
||||
ICriterion andUnits(String theSystem, String theUnits);
|
||||
}
|
||||
|
||||
}
|
|
@ -554,6 +554,8 @@ public class RestfulServer extends HttpServlet {
|
|||
if (tok.hasMoreTokens()) {
|
||||
String versionString = tok.nextToken();
|
||||
versionId = new IdDt(versionString);
|
||||
} else {
|
||||
operation = Constants.PARAM_HISTORY;
|
||||
}
|
||||
} else if (nextString.startsWith("_")) {
|
||||
if (operation != null) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package example;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
|
@ -9,21 +8,44 @@ import ca.uhn.fhir.rest.client.IGenericClient;
|
|||
|
||||
public class GenericClientExample {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void simpleExample() {
|
||||
// START SNIPPET: simple
|
||||
FhirContext ctx = new FhirContext();
|
||||
String serverBase = "http://fhir.healthintersections.com.au/open";
|
||||
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
|
||||
|
||||
// Read a patient
|
||||
Patient patient = client.read(Patient.class, "1");
|
||||
|
||||
// Change the patient and update it to the server
|
||||
patient.getNameFirstRep().getFamilyFirstRep().setValue("Jones");
|
||||
client.update("1", patient);
|
||||
|
||||
// Return the version history for that patient
|
||||
Bundle versions = client.history(Patient.class, "1");
|
||||
// END SNIPPET: simple
|
||||
}
|
||||
|
||||
public static void fluentSearch() {
|
||||
FhirContext ctx = new FhirContext();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhir.healthintersections.com.au/open");
|
||||
|
||||
//START SNIPPET: fluentExample
|
||||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.PARAM_BIRTHDATE.beforeOrEquals().day("2011-01-01"))
|
||||
.and(Patient.PARAM_PROVIDER.hasChainedProperty(Organization.NAME.matches().value("Health")))
|
||||
.andLogRequestAndResponse(true)
|
||||
.execute();
|
||||
//END SNIPPET: fluentExample
|
||||
|
||||
System.out.println(ctx.newXmlParser().setPrettyPrint(true).encodeBundleToString(response));
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
FhirContext ctx = new FhirContext();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhir.healthintersections.com.au/open");
|
||||
|
||||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.PARAM_BIRTHDATE.beforeOrEquals().day("2011-01-01"))
|
||||
.and(Patient.PARAM_PROVIDER.hasChainedProperty(Organization.NAME.matches().value("Health")))
|
||||
.andLogRequestAndResponse(true)
|
||||
.execute();
|
||||
|
||||
System.out.println(ctx.newXmlParser().setPrettyPrint(true).encodeBundleToString(response));
|
||||
|
||||
|
||||
// nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,14 +24,73 @@
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Setup is mostly done using simple annotations, which means that it
|
||||
should
|
||||
be possible to create a FHIR compliant server quickly and
|
||||
easily. Once again,
|
||||
this design is intended to be similar to that of
|
||||
There are two types of clients provided by HAPI: Generic and Annotation-driven.
|
||||
The generic client (introduced in HAPI-FHIR 0.3) is much simpler to create
|
||||
and generally provides the faster way to get started. The annotation-driven
|
||||
client is more powerful and can rely on code generation to give better
|
||||
compile-time checking.
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="The Generic Client">
|
||||
|
||||
<p>
|
||||
Creating a generic client simply requires you to create an instance of
|
||||
<code>FhirContext</code> and use that to instantiate a client.
|
||||
<b>Performance Tip: </b> Note that FhirContext is an expensive object to create,
|
||||
so you should try to keep an instance around for the lifetime of your application. It
|
||||
is thread-safe so it can be passed as needed. Client instances, on the other hand,
|
||||
are very inexpensive to create so you can create a new one for each request if needed
|
||||
(although there is no requirement to do so, clients are reusable and thread-safe as well).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following example shows how to create a client, and a few operations which
|
||||
can be performed.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="simple" />
|
||||
<param name="file"
|
||||
value="src/site/example/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
|
||||
<subsection name="Search/Query">
|
||||
|
||||
<p>
|
||||
The generic client supports queries using a fluent interface
|
||||
which is inspired by the fantastic
|
||||
<a href="http://ewoutkramer.github.io/fhir-net-api/client-search.html">.NET FHIR API</a>.
|
||||
The fluent interface allows you to construct powerful queries by chaining
|
||||
method calls together, leading to highly readable code. It also allows
|
||||
you to take advantage of intellisense/code completion in your favourite
|
||||
IDE.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following example shows how to query using this interface:
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="fluentExample" />
|
||||
<param name="file"
|
||||
value="src/site/example/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="The Annotation-Driven Client">
|
||||
|
||||
<p>
|
||||
The design of the annotation-driven client
|
||||
is intended to be similar to that of
|
||||
JAX-WS, so users of that
|
||||
specification should be comfortable with
|
||||
this one.
|
||||
this one. It uses a user-defined interface containing special
|
||||
annotated methods which HAPI binds to calls against a server.
|
||||
</p>
|
||||
|
||||
<subsection name="Defining A Restful Client Interface">
|
||||
|
|
|
@ -669,7 +669,7 @@ public class XmlParserTest {
|
|||
|
||||
assertEquals("http://spark.furore.com/fhir/_snapshot?id=327d6bb9-83b0-4929-aa91-6dd9c41e587b&start=0&_count=20", bundle.getLinkSelf().getValue());
|
||||
assertEquals("Patient resource with id 3216379", bundle.getEntries().get(0).getTitle().getValue());
|
||||
assertEquals("3216379", bundle.getEntries().get(0).getId().getValue());
|
||||
assertEquals("http://spark.furore.com/fhir/Patient/3216379", bundle.getEntries().get(0).getId().getValue());
|
||||
assertEquals("3216379", bundle.getEntries().get(0).getResource().getId().getValue());
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.resource.Encounter;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -93,7 +95,6 @@ public class GenericClientTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchByStringExact() throws Exception {
|
||||
|
@ -115,9 +116,62 @@ public class GenericClientTest {
|
|||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?name:exact=james", capt.getValue().getURI().toString());
|
||||
assertEquals("http://example.com/fhir/Patient?name%3Aexact=james", capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchByNumberExact() throws Exception {
|
||||
|
||||
String msg = new FhirContext().newXmlParser().encodeBundleToString(new Bundle());
|
||||
|
||||
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), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; 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");
|
||||
|
||||
//@formatter:off
|
||||
Bundle response = client.search()
|
||||
.forResource(Observation.class)
|
||||
.where(Observation.VALUE_QUANTITY.greaterThan().number(123).andUnits("foo", "bar"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Observation?value-quantity=%3E123%7Cfoo%7Cbar", capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchByQuantity() throws Exception {
|
||||
|
||||
String msg = getPatientFeedWithOneResult();
|
||||
|
||||
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), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; 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");
|
||||
|
||||
//@formatter:off
|
||||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Encounter.LENGTH.exactly().number(123))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?length=123", capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchByToken() throws Exception {
|
||||
|
@ -139,7 +193,7 @@ public class GenericClientTest {
|
|||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?identifier=http%3A%2F%2Ffoo%7CZZZ", capt.getValue().getURI().toString());
|
||||
assertEquals("http://example.com/fhir/Patient?identifier=http%3A%2F%2Fexample.com%2Ffhir%7CZZZ", capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
@ -193,7 +247,6 @@ public class GenericClientTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testSearchByDate() throws Exception {
|
||||
|
|
|
@ -93,8 +93,8 @@ public class ResfulServerMethodTest {
|
|||
private static FhirContext ourCtx;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResfulServerMethodTest.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static DummyDiagnosticReportResourceProvider ourReportProvider;
|
||||
private static Server ourServer;
|
||||
|
||||
@Test
|
||||
public void test404IsPropagatedCorrectly() throws Exception {
|
||||
|
@ -188,22 +188,6 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAdditionalParams() throws Exception {
|
||||
|
||||
HttpDelete httpGet = new HttpDelete("http://localhost:" + ourPort + "/Patient/1234?_pretty=true");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
OperationOutcome patient = ourCtx.newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
||||
assertEquals("1234", patient.getIssueFirstRep().getDetails().getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNoResponse() throws Exception {
|
||||
|
||||
|
@ -383,6 +367,28 @@ public class ResfulServerMethodTest {
|
|||
// }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHistoryFailsIfResourcesAreIncorrectlyPopulated() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/999/_history");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(500, status.getStatusLine().getStatusCode());
|
||||
}
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/998/_history");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(500, status.getStatusLine().getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testSearchByComplex() throws Exception {
|
||||
//
|
||||
|
@ -446,28 +452,6 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHistoryFailsIfResourcesAreIncorrectlyPopulated() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/999/_history");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(500, status.getStatusLine().getStatusCode());
|
||||
}
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/998/_history");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(500, status.getStatusLine().getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHistoryResourceType() throws Exception {
|
||||
|
||||
|
@ -542,6 +526,19 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnTypeThatDoesntSupportRead() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/AdverseReaction/223");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(Constants.STATUS_HTTP_404_NOT_FOUND, status.getStatusLine().getStatusCode());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchAll() throws Exception {
|
||||
|
||||
|
@ -569,19 +566,6 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadOnTypeThatDoesntSupportRead() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/AdverseReaction/223");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(Constants.STATUS_HTTP_404_NOT_FOUND, status.getStatusLine().getStatusCode());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchAllProfiles() throws Exception {
|
||||
|
||||
|
@ -909,22 +893,6 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
public void testUpdateWrongResourceType() throws Exception {
|
||||
|
||||
// TODO: this method sends in the wrong resource type vs. the URL so it
|
||||
// should
|
||||
// give a useful error message (and then make this unit test actually
|
||||
// run)
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
ourClient.execute(httpPost);
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNoResponse() throws Exception {
|
||||
|
||||
|
@ -941,6 +909,30 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithTagMultiple() throws Exception {
|
||||
|
||||
DiagnosticReport dr = new DiagnosticReport();
|
||||
dr.addCodedDiagnosis().addCoding().setCode("AAA");
|
||||
|
||||
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||
httpPost.addHeader("Category", "Dog, Cat");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(dr), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
ourClient.execute(httpPost);
|
||||
assertEquals(2, ourReportProvider.getLastTags().size());
|
||||
assertEquals(new Tag("Dog"), ourReportProvider.getLastTags().get(0));
|
||||
assertEquals(new Tag("Cat"), ourReportProvider.getLastTags().get(1));
|
||||
|
||||
httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||
httpPost.addHeader("Category", "Dog; label=\"aa\", Cat; label=\"bb\"");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(dr), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
ourClient.execute(httpPost);
|
||||
assertEquals(2, ourReportProvider.getLastTags().size());
|
||||
assertEquals(new Tag("Dog", "aa", (String)null), ourReportProvider.getLastTags().get(0));
|
||||
assertEquals(new Tag("Cat", "bb", (String)null), ourReportProvider.getLastTags().get(1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithTagSimple() throws Exception {
|
||||
|
||||
|
@ -978,7 +970,6 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdateWithTagWithSchemeAndLabel() throws Exception {
|
||||
|
||||
|
@ -1001,30 +992,7 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithTagMultiple() throws Exception {
|
||||
|
||||
DiagnosticReport dr = new DiagnosticReport();
|
||||
dr.addCodedDiagnosis().addCoding().setCode("AAA");
|
||||
|
||||
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||
httpPost.addHeader("Category", "Dog, Cat");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(dr), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
ourClient.execute(httpPost);
|
||||
assertEquals(2, ourReportProvider.getLastTags().size());
|
||||
assertEquals(new Tag("Dog"), ourReportProvider.getLastTags().get(0));
|
||||
assertEquals(new Tag("Cat"), ourReportProvider.getLastTags().get(1));
|
||||
|
||||
httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||
httpPost.addHeader("Category", "Dog; label=\"aa\", Cat; label=\"bb\"");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(dr), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
ourClient.execute(httpPost);
|
||||
assertEquals(2, ourReportProvider.getLastTags().size());
|
||||
assertEquals(new Tag("Dog", "aa", (String)null), ourReportProvider.getLastTags().get(0));
|
||||
assertEquals(new Tag("Cat", "bb", (String)null), ourReportProvider.getLastTags().get(1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdateWithVersion() throws Exception {
|
||||
|
||||
|
@ -1064,20 +1032,20 @@ public class ResfulServerMethodTest {
|
|||
assertEquals(400, results.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateWithPrettyPrintResponse() throws Exception {
|
||||
public void testUpdateWrongResourceType() throws Exception {
|
||||
|
||||
// TODO: this method sends in the wrong resource type vs. the URL so it
|
||||
// should
|
||||
// give a useful error message (and then make this unit test actually
|
||||
// run)
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("FOO");
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate?_pretty=true");
|
||||
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
assertThat(responseContent, containsString("\n "));
|
||||
ourClient.execute(httpPost);
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1135,6 +1103,38 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateWithPrettyPrintResponse() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("FOO");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/_validate?_pretty=true");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
assertThat(responseContent, containsString("\n "));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAdditionalParams() throws Exception {
|
||||
|
||||
HttpDelete httpGet = new HttpDelete("http://localhost:" + ourPort + "/Patient/1234?_pretty=true");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
OperationOutcome patient = ourCtx.newXmlParser().parseResource(OperationOutcome.class, responseContent);
|
||||
assertEquals("1234", patient.getIssueFirstRep().getDetails().getValue());
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
|
@ -1165,6 +1165,30 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public static class DummyAdverseReactionResourceProvider implements IResourceProvider {
|
||||
|
||||
/*
|
||||
* *********************
|
||||
* NO NEW METHODS *********************
|
||||
*/
|
||||
|
||||
@Create()
|
||||
public MethodOutcome create(@ResourceParam AdverseReaction thePatient) {
|
||||
IdDt id = new IdDt(thePatient.getIdentifier().get(0).getValue().getValue());
|
||||
IdDt version = new IdDt(thePatient.getIdentifier().get(1).getValue().getValue());
|
||||
return new MethodOutcome(id, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return AdverseReaction.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DummyDiagnosticReportResourceProvider implements IResourceProvider {
|
||||
|
||||
private TagList myLastTags;
|
||||
|
@ -1191,6 +1215,10 @@ public class ResfulServerMethodTest {
|
|||
// do nothing
|
||||
}
|
||||
|
||||
public TagList getLastTags() {
|
||||
return myLastTags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return DiagnosticReport.class;
|
||||
|
@ -1204,10 +1232,6 @@ public class ResfulServerMethodTest {
|
|||
return new MethodOutcome(id, version);
|
||||
}
|
||||
|
||||
public TagList getLastTags() {
|
||||
return myLastTags;
|
||||
}
|
||||
|
||||
@Update()
|
||||
public MethodOutcome updateDiagnosticReportWithVersionAndNoResponse(@IdParam IdDt theId, @ResourceParam DiagnosticReport theDr) {
|
||||
IdDt id = theId;
|
||||
|
@ -1218,30 +1242,6 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public static class DummyAdverseReactionResourceProvider implements IResourceProvider {
|
||||
|
||||
/*
|
||||
* *********************
|
||||
* NO NEW METHODS *********************
|
||||
*/
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return AdverseReaction.class;
|
||||
}
|
||||
|
||||
@Create()
|
||||
public MethodOutcome create(@ResourceParam AdverseReaction thePatient) {
|
||||
IdDt id = new IdDt(thePatient.getIdentifier().get(0).getValue().getValue());
|
||||
IdDt version = new IdDt(thePatient.getIdentifier().get(1).getValue().getValue());
|
||||
return new MethodOutcome(id, version);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue