A few fixes and additions to the fluent client, as well as fixing a bug on extension encoding (null extensions were still being encoded)
This commit is contained in:
parent
622e528f43
commit
4cd3bdf441
|
@ -67,6 +67,14 @@
|
|||
<![CDATA[<a href="http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_id=677&tracker_item_id=3298">FHIR Tracker Bug 3298</a>]]>
|
||||
for more information.
|
||||
</action>
|
||||
<action type="add">
|
||||
Support has been added for using an HTTP proxy for outgoing requests.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Fix: Primitive extensions declared against custom resource types
|
||||
are encoded even if they have no value. Thanks to David Hay of Orion for
|
||||
reporting this!
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.4" date="2014-Jul-13">
|
||||
<action type="add">
|
||||
|
|
|
@ -318,12 +318,12 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini
|
|||
|
||||
RuntimeResourceDefinition def = this;
|
||||
|
||||
if (StringUtils.isNotBlank(myId)) {
|
||||
retVal.setId(new IdDt(myId));
|
||||
}else {
|
||||
throw new ConfigurationException("Resource class " + getImplementingClass().getCanonicalName() + " has no ID specified");
|
||||
if (StringUtils.isBlank(myId)) {
|
||||
myId = getName().toLowerCase();
|
||||
}
|
||||
|
||||
retVal.setId(new IdDt(myId));
|
||||
|
||||
// Scan for extensions
|
||||
scanForExtensions(retVal, def);
|
||||
Collections.sort(retVal.getExtensionDefn(), new Comparator<ExtensionDefn>() {
|
||||
|
|
|
@ -432,4 +432,8 @@ public class IdDt extends BasePrimitive<String> {
|
|||
return new IdDt(value + '/' + Constants.PARAM_HISTORY + '/' + theVersion);
|
||||
}
|
||||
|
||||
public IdDt withResourceType(String theResourceName) {
|
||||
return new IdDt(theResourceName, getIdPart(), getVersionIdPart());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -560,6 +560,9 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
for (RuntimeChildDeclaredExtensionDefinition nextDef : resDef.getExtensionsNonModifier()) {
|
||||
for (IElement nextValue : nextDef.getAccessor().getValues(theResource)) {
|
||||
if (nextValue != null) {
|
||||
if (nextValue == null || nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
extensions.add(new HeldExtension(nextDef, nextValue));
|
||||
}
|
||||
}
|
||||
|
@ -567,6 +570,9 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
for (RuntimeChildDeclaredExtensionDefinition nextDef : resDef.getExtensionsModifier()) {
|
||||
for (IElement nextValue : nextDef.getAccessor().getValues(theResource)) {
|
||||
if (nextValue != null) {
|
||||
if (nextValue == null || nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
modifierExtensions.add(new HeldExtension(nextDef, nextValue));
|
||||
}
|
||||
}
|
||||
|
@ -577,11 +583,17 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
if (theResource instanceof ISupportsUndeclaredExtensions) {
|
||||
List<ExtensionDt> ext = ((ISupportsUndeclaredExtensions) theResource).getUndeclaredExtensions();
|
||||
for (ExtensionDt next : ext) {
|
||||
if (next == null || next.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
extensions.add(new HeldExtension(next));
|
||||
}
|
||||
|
||||
ext = ((ISupportsUndeclaredExtensions) theResource).getUndeclaredModifierExtensions();
|
||||
for (ExtensionDt next : ext) {
|
||||
if (next == null || next.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
modifierExtensions.add(new HeldExtension(next));
|
||||
}
|
||||
}
|
||||
|
@ -708,7 +720,7 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
if (elementId != null) {
|
||||
IElement object = (IElement) theState.getObject();
|
||||
if (object instanceof IIdentifiableElement) {
|
||||
((IIdentifiableElement) object).setId(new IdDt(elementId));
|
||||
((IIdentifiableElement) object).setElementSpecificId(elementId);
|
||||
} else if (object instanceof IResource) {
|
||||
((IResource) object).setId(new IdDt(elementId));
|
||||
}
|
||||
|
|
|
@ -489,7 +489,7 @@ public class XmlParser extends BaseParser implements IParser {
|
|||
}
|
||||
|
||||
for (IElement nextValue : values) {
|
||||
if (nextValue == null) {
|
||||
if (nextValue == null || nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Class<? extends IElement> type = nextValue.getClass();
|
||||
|
|
|
@ -138,6 +138,15 @@ public abstract class BaseClient {
|
|||
try {
|
||||
Map<String, List<String>> params = createExtraParams();
|
||||
|
||||
if (theEncoding == EncodingEnum.XML) {
|
||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||
} else if (theEncoding == EncodingEnum.JSON) {
|
||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||
}
|
||||
if (thePrettyPrint == Boolean.TRUE) {
|
||||
params.put(Constants.PARAM_PRETTY, Collections.singletonList(Constants.PARAM_PRETTY_VALUE_TRUE));
|
||||
}
|
||||
|
||||
EncodingEnum encoding = getEncoding();
|
||||
if (theEncoding != null) {
|
||||
encoding=theEncoding;
|
||||
|
|
|
@ -25,7 +25,6 @@ import static org.apache.commons.lang3.StringUtils.*;
|
|||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -45,8 +44,10 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
||||
|
@ -55,6 +56,8 @@ import ca.uhn.fhir.rest.gclient.ICreate;
|
|||
import ca.uhn.fhir.rest.gclient.ICreateTyped;
|
||||
import ca.uhn.fhir.rest.gclient.ICriterion;
|
||||
import ca.uhn.fhir.rest.gclient.ICriterionInternal;
|
||||
import ca.uhn.fhir.rest.gclient.IDelete;
|
||||
import ca.uhn.fhir.rest.gclient.IDeleteTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IGetPage;
|
||||
import ca.uhn.fhir.rest.gclient.IGetPageTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IGetTags;
|
||||
|
@ -83,6 +86,8 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
|
||||
public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClient.class);
|
||||
|
||||
private FhirContext myContext;
|
||||
|
||||
private HttpRequestBase myLastRequest;
|
||||
|
@ -131,9 +136,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDelete delete() {
|
||||
return new DeleteInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome delete(final Class<? extends IResource> theType, IdDt theId) {
|
||||
HttpDeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(toResourceName(theType), theId);
|
||||
HttpDeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(theId.withResourceType(toResourceName(theType)));
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
|
||||
}
|
||||
|
@ -210,7 +220,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
@Override
|
||||
public IUntypedQuery search() {
|
||||
return new QueryInternal();
|
||||
return new SearchInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -249,10 +259,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
myLogRequestAndResponse = theLogRequestAndResponse;
|
||||
}
|
||||
|
||||
private String toResourceName(Class<? extends IResource> theType) {
|
||||
return myContext.getResourceDefinition(theType).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITransaction transaction() {
|
||||
return new TransactionInternal();
|
||||
|
@ -322,18 +328,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return vread(theType, new IdDt(theId), new IdDt(theVersionId));
|
||||
}
|
||||
|
||||
private String toResourceName(Class<? extends IResource> theType) {
|
||||
return myContext.getResourceDefinition(theType).getName();
|
||||
}
|
||||
|
||||
private abstract class BaseClientExecutable<T extends IClientExecutable<?, ?>, Y> implements IClientExecutable<T, Y> {
|
||||
private EncodingEnum myParamEncoding;
|
||||
private Boolean myPrettyPrint;
|
||||
private boolean myQueryLogRequestAndResponse;
|
||||
|
||||
protected void addParam(Map<String, List<String>> params, String parameterName, String parameterValue) {
|
||||
if (!params.containsKey(parameterName)) {
|
||||
params.put(parameterName, new ArrayList<String>());
|
||||
}
|
||||
params.get(parameterName).add(parameterValue);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T andLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
||||
|
@ -355,14 +358,28 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return (T) this;
|
||||
}
|
||||
|
||||
protected <Z> Z invoke(Map<String, List<String>> theParams, IClientResponseHandler<Z> theHandler, BaseHttpClientInvocation theInvocation) {
|
||||
if (myParamEncoding != null) {
|
||||
theParams.put(Constants.PARAM_FORMAT, Collections.singletonList(myParamEncoding.getFormatContentType()));
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T prettyPrint() {
|
||||
myPrettyPrint = true;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
if (myPrettyPrint != null) {
|
||||
theParams.put(Constants.PARAM_PRETTY, Collections.singletonList(myPrettyPrint.toString()));
|
||||
protected void addParam(Map<String, List<String>> params, String parameterName, String parameterValue) {
|
||||
if (!params.containsKey(parameterName)) {
|
||||
params.put(parameterName, new ArrayList<String>());
|
||||
}
|
||||
params.get(parameterName).add(parameterValue);
|
||||
}
|
||||
|
||||
protected <Z> Z invoke(Map<String, List<String>> theParams, IClientResponseHandler<Z> theHandler, BaseHttpClientInvocation theInvocation) {
|
||||
// if (myParamEncoding != null) {
|
||||
// theParams.put(Constants.PARAM_FORMAT, Collections.singletonList(myParamEncoding.getFormatContentType()));
|
||||
// }
|
||||
//
|
||||
// if (myPrettyPrint != null) {
|
||||
// theParams.put(Constants.PARAM_PRETTY, Collections.singletonList(myPrettyPrint.toString()));
|
||||
// }
|
||||
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = theInvocation.asHttpRequest(getServerBase(), theParams, getEncoding());
|
||||
|
@ -372,13 +389,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return resp;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T prettyPrint() {
|
||||
myPrettyPrint = true;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class BundleResponseHandler implements IClientResponseHandler<Bundle> {
|
||||
|
@ -390,8 +400,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Bundle invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
public Bundle invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (respType == null) {
|
||||
throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
|
||||
|
@ -427,7 +436,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
myResource = encoding.newParser(myContext).parseResource(myResourceBody);
|
||||
}
|
||||
|
||||
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(myResource,myResourceBody, myId, myContext);
|
||||
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(myResource, myResourceBody, myId, myContext);
|
||||
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource);
|
||||
final String resourceName = def.getName();
|
||||
|
@ -467,100 +476,53 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
private class ForInternal extends BaseClientExecutable<IQuery, Bundle> implements IQuery {
|
||||
private class DeleteInternal extends BaseClientExecutable<IDeleteTyped, OperationOutcome> implements IDelete, IDeleteTyped {
|
||||
|
||||
private List<ICriterionInternal> myCriterion = new ArrayList<ICriterionInternal>();
|
||||
private List<Include> myInclude = new ArrayList<Include>();
|
||||
private Integer myParamLimit;
|
||||
private final String myResourceName;
|
||||
private final Class<? extends IResource> myResourceType;
|
||||
private List<SortInternal> mySort = new ArrayList<SortInternal>();
|
||||
|
||||
public ForInternal() {
|
||||
myResourceType = null;
|
||||
myResourceName = null;
|
||||
}
|
||||
|
||||
public ForInternal(Class<? extends IResource> theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
RuntimeResourceDefinition definition = myContext.getResourceDefinition(theResourceType);
|
||||
myResourceName = definition.getName();
|
||||
}
|
||||
|
||||
public ForInternal(String theResourceName) {
|
||||
myResourceType = myContext.getResourceDefinition(theResourceName).getImplementingClass();
|
||||
myResourceName = theResourceName;
|
||||
}
|
||||
private IdDt myId;
|
||||
|
||||
@Override
|
||||
public IQuery and(ICriterion theCriterion) {
|
||||
myCriterion.add((ICriterionInternal) theCriterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle execute() {
|
||||
|
||||
Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
|
||||
Map<String, List<String>> initial = createExtraParams();
|
||||
if (initial != null) {
|
||||
params.putAll(initial);
|
||||
}
|
||||
|
||||
for (ICriterionInternal next : myCriterion) {
|
||||
String parameterName = next.getParameterName();
|
||||
String parameterValue = next.getParameterValue();
|
||||
addParam(params, parameterName, parameterValue);
|
||||
}
|
||||
|
||||
for (Include next : myInclude) {
|
||||
addParam(params, Constants.PARAM_INCLUDE, next.getValue());
|
||||
}
|
||||
|
||||
for (SortInternal next : mySort) {
|
||||
addParam(params, next.getParamName(), next.getParamValue());
|
||||
}
|
||||
|
||||
if (myParamLimit != null) {
|
||||
addParam(params, Constants.PARAM_COUNT, Integer.toString(myParamLimit));
|
||||
}
|
||||
|
||||
BundleResponseHandler binding = new BundleResponseHandler(myResourceType);
|
||||
HttpGetClientInvocation invocation = new HttpGetClientInvocation(params, myResourceName);
|
||||
|
||||
public OperationOutcome execute() {
|
||||
HttpDeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(myId);
|
||||
OperationOutcomeResponseHandler binding = new OperationOutcomeResponseHandler();
|
||||
Map<String, List<String>> params = new HashMap<String, List<String>>();
|
||||
return invoke(params, binding, invocation);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery include(Include theInclude) {
|
||||
myInclude.add(theInclude);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery limitTo(int theLimitTo) {
|
||||
if (theLimitTo > 0) {
|
||||
myParamLimit = theLimitTo;
|
||||
} else {
|
||||
myParamLimit = null;
|
||||
public IDeleteTyped resource(IResource theResource) {
|
||||
Validate.notNull(theResource, "theResource can not be null");
|
||||
IdDt id = theResource.getId();
|
||||
Validate.notNull(id, "theResource.getId() can not be null");
|
||||
if (id.hasResourceType() == false || id.hasIdPart() == false) {
|
||||
throw new IllegalArgumentException("theResource.getId() must contain a resource type and logical ID at a minimum (e.g. Patient/1234), found: " + id.getValue());
|
||||
}
|
||||
myId = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISort sort() {
|
||||
SortInternal retVal = new SortInternal(this);
|
||||
mySort.add(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery where(ICriterion theCriterion) {
|
||||
myCriterion.add((ICriterionInternal) theCriterion);
|
||||
public IDeleteTyped resourceById(IdDt theId) {
|
||||
Validate.notNull(theId, "theId can not be null");
|
||||
if (theId.hasResourceType() == false || theId.hasIdPart() == false) {
|
||||
throw new IllegalArgumentException("theId must contain a resource type and logical ID at a minimum (e.g. Patient/1234)found: " + theId.getValue());
|
||||
}
|
||||
myId = theId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDeleteTyped resourceById(String theResourceType, String theLogicalId) {
|
||||
Validate.notBlank(theResourceType, "theResourceType can not be blank/null");
|
||||
if (myContext.getResourceDefinition(theResourceType) == null) {
|
||||
throw new IllegalArgumentException("Unknown resource type");
|
||||
}
|
||||
Validate.notBlank(theLogicalId, "theLogicalId can not be blank/null");
|
||||
if (theLogicalId.contains("/")) {
|
||||
throw new IllegalArgumentException("LogicalId can not contain '/' (should only be the logical ID portion, not a qualified ID)");
|
||||
}
|
||||
myId = new IdDt(theResourceType, theLogicalId);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
private class GetPageInternal extends BaseClientExecutable<IGetPageTyped, Bundle> implements IGetPageTyped {
|
||||
|
@ -669,6 +631,28 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
private final class OperationOutcomeResponseHandler implements IClientResponseHandler<OperationOutcome> {
|
||||
|
||||
@Override
|
||||
public OperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (respType == null) {
|
||||
return null;
|
||||
}
|
||||
IParser parser = respType.newParser(myContext);
|
||||
OperationOutcome retVal;
|
||||
try {
|
||||
retVal = parser.parseResource(OperationOutcome.class, theResponseReader);
|
||||
} catch (DataFormatException e) {
|
||||
ourLog.warn("Failed to parse OperationOutcome response", e);
|
||||
return null;
|
||||
}
|
||||
MethodUtil.parseClientRequestResourceHeaders(theHeaders, retVal);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
private final class OutcomeResponseHandler implements IClientResponseHandler<MethodOutcome> {
|
||||
private final String myResourceName;
|
||||
|
||||
|
@ -677,32 +661,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
MethodOutcome response = MethodUtil.process2xxResponse(myContext, myResourceName, theResponseStatusCode, theResponseMimeType, theResponseReader, theHeaders);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
private class QueryInternal implements IUntypedQuery {
|
||||
|
||||
@Override
|
||||
public IQuery forAllResources() {
|
||||
return new ForInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery forResource(Class<? extends IResource> theResourceType) {
|
||||
return new ForInternal(theResourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery forResource(String theResourceName) {
|
||||
return new ForInternal(theResourceName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class ResourceListResponseHandler implements IClientResponseHandler<List<IResource>> {
|
||||
|
||||
private Class<? extends IResource> myType;
|
||||
|
@ -712,8 +676,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
public List<IResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
return new BundleResponseHandler(myType).invokeClient(theResponseMimeType, theResponseReader, theResponseStatusCode, theHeaders).toListOfResources();
|
||||
}
|
||||
}
|
||||
|
@ -742,18 +705,133 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
MethodUtil.parseClientRequestResourceHeaders(theHeaders, retVal);
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
private class SearchInternal extends BaseClientExecutable<IQuery, Bundle> implements IQuery, IUntypedQuery {
|
||||
|
||||
private List<ICriterionInternal> myCriterion = new ArrayList<ICriterionInternal>();
|
||||
|
||||
private List<Include> myInclude = new ArrayList<Include>();
|
||||
|
||||
private Integer myParamLimit;
|
||||
private String myResourceName;
|
||||
private Class<? extends IResource> myResourceType;
|
||||
private List<SortInternal> mySort = new ArrayList<SortInternal>();
|
||||
|
||||
public SearchInternal() {
|
||||
myResourceType = null;
|
||||
myResourceName = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery and(ICriterion theCriterion) {
|
||||
myCriterion.add((ICriterionInternal) theCriterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle execute() {
|
||||
|
||||
Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
|
||||
Map<String, List<String>> initial = createExtraParams();
|
||||
if (initial != null) {
|
||||
params.putAll(initial);
|
||||
}
|
||||
|
||||
for (ICriterionInternal next : myCriterion) {
|
||||
String parameterName = next.getParameterName();
|
||||
String parameterValue = next.getParameterValue();
|
||||
addParam(params, parameterName, parameterValue);
|
||||
}
|
||||
|
||||
for (Include next : myInclude) {
|
||||
addParam(params, Constants.PARAM_INCLUDE, next.getValue());
|
||||
}
|
||||
|
||||
for (SortInternal next : mySort) {
|
||||
addParam(params, next.getParamName(), next.getParamValue());
|
||||
}
|
||||
|
||||
if (myParamLimit != null) {
|
||||
addParam(params, Constants.PARAM_COUNT, Integer.toString(myParamLimit));
|
||||
}
|
||||
|
||||
BundleResponseHandler binding = new BundleResponseHandler(myResourceType);
|
||||
HttpGetClientInvocation invocation = new HttpGetClientInvocation(params, myResourceName);
|
||||
|
||||
return invoke(params, binding, invocation);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery forAllResources() {
|
||||
return this;
|
||||
}
|
||||
|
||||
private void setType(Class<? extends IResource> theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
RuntimeResourceDefinition definition = myContext.getResourceDefinition(theResourceType);
|
||||
myResourceName = definition.getName();
|
||||
}
|
||||
|
||||
private void setType(String theResourceName) {
|
||||
myResourceType = myContext.getResourceDefinition(theResourceName).getImplementingClass();
|
||||
myResourceName = theResourceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery forResource(Class<? extends IResource> theResourceType) {
|
||||
setType(theResourceType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery forResource(String theResourceName) {
|
||||
setType(theResourceName);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery include(Include theInclude) {
|
||||
myInclude.add(theInclude);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery limitTo(int theLimitTo) {
|
||||
if (theLimitTo > 0) {
|
||||
myParamLimit = theLimitTo;
|
||||
} else {
|
||||
myParamLimit = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISort sort() {
|
||||
SortInternal retVal = new SortInternal(this);
|
||||
mySort.add(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery where(ICriterion theCriterion) {
|
||||
myCriterion.add((ICriterionInternal) theCriterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SortInternal implements ISort {
|
||||
|
||||
private ForInternal myFor;
|
||||
private SearchInternal myFor;
|
||||
private String myParamName;
|
||||
private String myParamValue;
|
||||
|
||||
public SortInternal(ForInternal theFor) {
|
||||
public SortInternal(SearchInternal theFor) {
|
||||
myFor = theFor;
|
||||
}
|
||||
|
||||
|
@ -791,8 +869,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private final class TagListResponseHandler implements IClientResponseHandler<TagList> {
|
||||
|
||||
@Override
|
||||
public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (respType == null) {
|
||||
throw NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
|
||||
|
|
|
@ -32,6 +32,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.gclient.ICreate;
|
||||
import ca.uhn.fhir.rest.gclient.IDelete;
|
||||
import ca.uhn.fhir.rest.gclient.IGetPage;
|
||||
import ca.uhn.fhir.rest.gclient.IGetTags;
|
||||
import ca.uhn.fhir.rest.gclient.ITransaction;
|
||||
|
@ -83,6 +84,7 @@ public interface IGenericClient {
|
|||
* @param theId
|
||||
* the ID of the resource to delete
|
||||
* @return An outcome
|
||||
* @deprecated Use {@link #delete()) instead
|
||||
*/
|
||||
MethodOutcome delete(Class<? extends IResource> theType, IdDt theId);
|
||||
|
||||
|
@ -94,6 +96,7 @@ public interface IGenericClient {
|
|||
* @param theId
|
||||
* the ID of the resource to delete
|
||||
* @return An outcome
|
||||
* @deprecated Use {@link #delete()) instead
|
||||
*/
|
||||
MethodOutcome delete(Class<? extends IResource> theType, String theId);
|
||||
|
||||
|
@ -260,4 +263,9 @@ public interface IGenericClient {
|
|||
*/
|
||||
ICreate create();
|
||||
|
||||
/**
|
||||
* Fluent method for the "delete" operation, which performs a logical delete on a server resource
|
||||
*/
|
||||
IDelete delete();
|
||||
|
||||
}
|
||||
|
|
|
@ -75,4 +75,12 @@ public interface IRestfulClientFactory {
|
|||
|
||||
void setConnectionRequestTimeout(int theConnectionRequestTimeout);
|
||||
|
||||
/**
|
||||
* Sets the HTTP proxy to use for outgoing connections
|
||||
*
|
||||
* @param theHost The host (or null to disable proxying, as is the default)
|
||||
* @param thePort The port (or null to disable proxying, as is the default)
|
||||
*/
|
||||
void setProxy(String theHost, Integer thePort);
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
@ -39,12 +40,22 @@ import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
|||
|
||||
public class RestfulClientFactory implements IRestfulClientFactory {
|
||||
|
||||
private int myConnectionRequestTimeout=10000;
|
||||
private int myConnectTimeout=10000;
|
||||
private int myConnectionRequestTimeout = 10000;
|
||||
private int myConnectTimeout = 10000;
|
||||
private FhirContext myContext;
|
||||
private HttpClient myHttpClient;
|
||||
private Map<Class<? extends IRestfulClient>, ClientInvocationHandler> myInvocationHandlers = new HashMap<Class<? extends IRestfulClient>, ClientInvocationHandler>();
|
||||
private int mySocketTimeout = 10000;
|
||||
private HttpHost myProxy;
|
||||
|
||||
@Override
|
||||
public void setProxy(String theHost, Integer thePort) {
|
||||
if (theHost != null) {
|
||||
myProxy = new HttpHost(theHost, thePort, "http");
|
||||
} else {
|
||||
myProxy = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -53,7 +64,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
* The context
|
||||
*/
|
||||
public RestfulClientFactory(FhirContext theFhirContext) {
|
||||
myContext=theFhirContext;
|
||||
myContext = theFhirContext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,11 +74,10 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the context associated with this client factory. Must not be called
|
||||
* more than once.
|
||||
* Sets the context associated with this client factory. Must not be called more than once.
|
||||
*/
|
||||
public void setFhirContext(FhirContext theContext) {
|
||||
if(myContext!=null&&myContext!=theContext) {
|
||||
if (myContext != null && myContext != theContext) {
|
||||
throw new IllegalStateException("RestfulClientFactory instance is already associated with one FhirContext. RestfulClientFactory instances can not be shared.");
|
||||
}
|
||||
myContext = theContext;
|
||||
|
@ -86,13 +96,14 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
if (myHttpClient == null) {
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
//@formatter:off
|
||||
RequestConfig defaultRequestConfig = RequestConfig.custom()
|
||||
.setSocketTimeout(mySocketTimeout)
|
||||
.setConnectTimeout(myConnectTimeout)
|
||||
.setConnectionRequestTimeout(myConnectionRequestTimeout)
|
||||
.setStaleConnectionCheckEnabled(true)
|
||||
.setProxy(myProxy)
|
||||
.build();
|
||||
|
||||
myHttpClient = HttpClients.custom()
|
||||
|
@ -103,7 +114,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
//@formatter:on
|
||||
|
||||
}
|
||||
|
||||
|
||||
return myHttpClient;
|
||||
}
|
||||
|
||||
|
@ -144,7 +155,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
}
|
||||
myInvocationHandlers.put(theClientType, invocationHandler);
|
||||
}
|
||||
|
||||
|
||||
T proxy = instantiateProxy(theClientType, invocationHandler);
|
||||
|
||||
return proxy;
|
||||
|
@ -158,18 +169,18 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
@Override
|
||||
public synchronized void setConnectionRequestTimeout(int theConnectionRequestTimeout) {
|
||||
myConnectionRequestTimeout = theConnectionRequestTimeout;
|
||||
myHttpClient=null;
|
||||
myHttpClient = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setConnectTimeout(int theConnectTimeout) {
|
||||
myConnectTimeout = theConnectTimeout;
|
||||
myHttpClient=null;
|
||||
myHttpClient = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Apache HTTP client instance to be used by any new restful clients created by this factory. If set to <code>null</code>, which is the default, a new HTTP client with default settings
|
||||
* will be created.
|
||||
* Sets the Apache HTTP client instance to be used by any new restful clients created by this factory. If set to
|
||||
* <code>null</code>, which is the default, a new HTTP client with default settings will be created.
|
||||
*
|
||||
* @param theHttpClient
|
||||
* An HTTP client instance to use, or <code>null</code>
|
||||
|
@ -182,7 +193,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
|||
@Override
|
||||
public synchronized void setSocketTimeout(int theSocketTimeout) {
|
||||
mySocketTimeout = theSocketTimeout;
|
||||
myHttpClient=null;
|
||||
myHttpClient = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -144,6 +144,7 @@ public class LoggingInterceptor implements IClientInterceptor {
|
|||
|
||||
if (myLogResponseBody) {
|
||||
HttpEntity respEntity = theResponse.getEntity();
|
||||
if (respEntity != null) {
|
||||
final byte[] bytes;
|
||||
try {
|
||||
bytes = IOUtils.toByteArray(respEntity.getContent());
|
||||
|
@ -152,8 +153,10 @@ public class LoggingInterceptor implements IClientInterceptor {
|
|||
}
|
||||
|
||||
myLog.info("Client response body:\n{}", new String(bytes));
|
||||
|
||||
theResponse.setEntity(new MyEntityWrapper(respEntity, bytes));
|
||||
} else {
|
||||
myLog.info("Client response body: (none)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -20,12 +22,8 @@ package ca.uhn.fhir.rest.gclient;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
||||
public interface ICreate {
|
||||
|
||||
public interface ICreate {
|
||||
ICreateTyped resource(IResource theResource);
|
||||
|
||||
ICreateTyped resource(String theResourceAsText);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
/*
|
||||
* #%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 interface IDelete {
|
||||
|
||||
IDeleteTyped resource(IResource theResource);
|
||||
|
||||
IDeleteTyped resourceById(IdDt theId);
|
||||
|
||||
IDeleteTyped resourceById(String theResourceType, String theLogicalId);
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%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 ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
|
||||
public interface IDeleteTyped extends IClientExecutable<IDeleteTyped, OperationOutcome> {
|
||||
|
||||
// nothing for now
|
||||
|
||||
}
|
|
@ -38,6 +38,7 @@ import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
|||
import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
|
||||
|
||||
|
@ -120,9 +121,14 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
|
|||
if (idDt == null) {
|
||||
throw new NullPointerException("ID can not be null");
|
||||
}
|
||||
String resourceName = getResourceName();
|
||||
|
||||
HttpDeleteClientInvocation retVal = createDeleteInvocation(resourceName, idDt);
|
||||
if (idDt.hasResourceType()==false) {
|
||||
idDt = idDt.withResourceType(getResourceName());
|
||||
}else if (getResourceName().equals(idDt.getResourceType())==false) {
|
||||
throw new InvalidRequestException("ID parameter has the wrong resource type, expected '" + getResourceName() + "', found: " + idDt.getResourceType());
|
||||
}
|
||||
|
||||
HttpDeleteClientInvocation retVal = createDeleteInvocation(idDt);
|
||||
|
||||
for (int idx = 0; idx < theArgs.length; idx++) {
|
||||
IParameter nextParam = getParameters().get(idx);
|
||||
|
@ -132,9 +138,8 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static HttpDeleteClientInvocation createDeleteInvocation(String theResourceName, IdDt idDt) {
|
||||
String id = idDt.getValue();
|
||||
HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theResourceName, id);
|
||||
public static HttpDeleteClientInvocation createDeleteInvocation(IdDt theId) {
|
||||
HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theId);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@ package ca.uhn.fhir.rest.method;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
|
||||
|
@ -34,9 +34,9 @@ public class HttpDeleteClientInvocation extends BaseHttpClientInvocation {
|
|||
|
||||
private String myUrlPath;
|
||||
|
||||
public HttpDeleteClientInvocation(String... theUrlFragments) {
|
||||
public HttpDeleteClientInvocation(IdDt theId) {
|
||||
super();
|
||||
myUrlPath = StringUtils.join(theUrlFragments, '/');
|
||||
myUrlPath = theId.toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package example;
|
||||
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.IRestfulClientFactory;
|
||||
|
@ -16,6 +14,16 @@ public class ClientExamples {
|
|||
// nothing yet
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createProxy() {
|
||||
//START SNIPPET: proxy
|
||||
FhirContext ctx = new FhirContext();
|
||||
ctx.getRestfulClientFactory().setProxy("example.com", 8888);
|
||||
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
//START SNIPPET: end
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createSecurity() {
|
||||
//START SNIPPET: security
|
||||
|
|
|
@ -7,8 +7,10 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
|
||||
public class GenericClientExample {
|
||||
|
@ -60,6 +62,19 @@ System.out.println(conf.getDescription().getValue());
|
|||
//END SNIPPET: conformance
|
||||
}
|
||||
{
|
||||
//START SNIPPET: delete
|
||||
// Retrieve the server's conformance statement and print its description
|
||||
OperationOutcome outcome = client.delete()
|
||||
.resourceById(new IdDt("Patient", "1234"))
|
||||
.execute();
|
||||
|
||||
// outcome may be null if the server didn't return one
|
||||
if (outcome != null) {
|
||||
System.out.println(outcome.getIssueFirstRep().getDetails().getValue());
|
||||
}
|
||||
//END SNIPPET: delete
|
||||
}
|
||||
{
|
||||
//START SNIPPET: search
|
||||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
|
@ -68,6 +83,20 @@ Bundle response = client.search()
|
|||
.andLogRequestAndResponse(true)
|
||||
.execute();
|
||||
//END SNIPPET: search
|
||||
|
||||
//START SNIPPET: searchAdv
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.encodedJson()
|
||||
.where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22"))
|
||||
.and(Patient.BIRTHDATE.after().day("2011-01-01"))
|
||||
.include(Patient.INCLUDE_MANAGINGORGANIZATION)
|
||||
.sort().ascending(Patient.BIRTHDATE)
|
||||
.sort().descending(Patient.NAME)
|
||||
.limitTo(123)
|
||||
.execute();
|
||||
//END SNIPPET: searchAdv
|
||||
|
||||
//START SNIPPET: searchPaging
|
||||
if (response.getLinkNext().isEmpty() == false) {
|
||||
|
||||
|
|
|
@ -106,6 +106,27 @@
|
|||
<param name="file"
|
||||
value="src/site/example/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
<p>
|
||||
The fluent search also has methods for sorting, limiting, specifying
|
||||
JSON encoding, etc.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="searchAdv" />
|
||||
<param name="file"
|
||||
value="src/site/example/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Instance - Delete">
|
||||
<p>
|
||||
The following example shows how to perform a delete
|
||||
operation using the generic client:
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="delete" />
|
||||
<param name="file"
|
||||
value="src/site/example/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Server - Conformance">
|
||||
|
@ -289,9 +310,9 @@
|
|||
</p>
|
||||
|
||||
<p>
|
||||
The underlying client configuration is provided by setting an
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/client/IRestfulClientFactory.html#setHttpClient(org.apache.http.client.HttpClient)">HttpClient</a>
|
||||
on the RestfulClientFactory.
|
||||
The underlying client configuration is provided by accessing the
|
||||
<a href="./apidocs/ca/uhn/fhir/rest/client/IRestfulClientFactory.html">IRestfulClientFactory</a>
|
||||
class from the FhirContext.
|
||||
</p>
|
||||
|
||||
<subsection name="Interceptors">
|
||||
|
@ -338,6 +359,20 @@
|
|||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Configuring an HTTP Proxy">
|
||||
|
||||
<p>
|
||||
An HTTP proxy may be configured directly on the
|
||||
restful client factory, as shown below.
|
||||
</p>
|
||||
|
||||
<macro name="snippet">
|
||||
<param name="id" value="logging" />
|
||||
<param name="file" value="src/site/example/java/example/ClientExamples.java" />
|
||||
</macro>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
//START SNIPPET: patientDef
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
/**
|
||||
* Definition class for adding extensions to the built-in
|
||||
* Patient resource type.
|
||||
*/
|
||||
@ResourceDef(name="Patient")
|
||||
public class DummyPatientWithExtensions extends Patient {
|
||||
|
||||
/**
|
||||
* Each extension is defined in a field. Any valid HAPI Data Type
|
||||
* can be used for the field type. Note that the [name=""] attribute
|
||||
* in the @Child annotation needs to match the name for the bean accessor
|
||||
* and mutator methods.
|
||||
*/
|
||||
@Child(name="petName")
|
||||
@Extension(url="http://example.com/dontuse#petname", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The name of the patient's favourite pet")
|
||||
private StringDt myPetName;
|
||||
|
||||
/**
|
||||
* The second example extension uses a List type to provide
|
||||
* repeatable values. Note that a [max=] value has been placed in
|
||||
* the @Child annotation.
|
||||
*
|
||||
* Note also that this extension is a modifier extension
|
||||
*/
|
||||
@Child(name="importantDates", max=Child.MAX_UNLIMITED)
|
||||
@Extension(url="http://example.com/dontuse#importantDates", definedLocally=false, isModifier=true)
|
||||
@Description(shortDefinition="Some dates of note for this patient")
|
||||
private List<DateTimeDt> myImportantDates;
|
||||
|
||||
/**
|
||||
* It is important to override the isEmpty() method, adding a check for any
|
||||
* newly added fields.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(myPetName, myImportantDates);
|
||||
}
|
||||
|
||||
/********
|
||||
* Accessors and mutators follow
|
||||
*
|
||||
* IMPORTANT:
|
||||
* Each extension is required to have an getter/accessor and a stter/mutator.
|
||||
* You are highly recommended to create getters which create instances if they
|
||||
* do not already exist, since this is how the rest of the HAPI FHIR API works.
|
||||
********/
|
||||
|
||||
/** Getter for important dates */
|
||||
public List<DateTimeDt> getImportantDates() {
|
||||
if (myImportantDates==null) {
|
||||
myImportantDates = new ArrayList<DateTimeDt>();
|
||||
}
|
||||
return myImportantDates;
|
||||
}
|
||||
|
||||
/** Getter for pet name */
|
||||
public StringDt getPetName() {
|
||||
if (myPetName == null) {
|
||||
myPetName = new StringDt();
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
/** Setter for important dates */
|
||||
public void setImportantDates(List<DateTimeDt> theImportantDates) {
|
||||
myImportantDates = theImportantDates;
|
||||
}
|
||||
|
||||
/** Setter for pet name */
|
||||
public void setPetName(StringDt thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: patientDef
|
|
@ -0,0 +1,87 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.MyPatient;
|
||||
|
||||
public class ExtensionTest {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExtensionTest.class);
|
||||
|
||||
private static FhirContext ourCtx = new FhirContext();
|
||||
|
||||
@Test
|
||||
public void testExtensionType() {
|
||||
|
||||
DummyPatientWithExtensions patient = new DummyPatientWithExtensions();
|
||||
patient.setPetName(new StringDt("Fido"));
|
||||
patient.getImportantDates().add(new DateTimeDt("2010-01-02"));
|
||||
patient.getImportantDates().add(new DateTimeDt("2014-01-26T11:11:11"));
|
||||
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Quincy").addSuffix("Jr");
|
||||
|
||||
String messageString = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
ourLog.info(messageString);
|
||||
assertThat(messageString, containsString("<modifierExtension url=\"http://example.com/dontuse#importantDates\"><valueDateTime value=\"2010-01-02\"/></modifierExtension>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyExtensionType() {
|
||||
DummyPatientWithExtensions patient = new DummyPatientWithExtensions();
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Quincy").addSuffix("Jr");
|
||||
String messageString = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
ourLog.info(messageString);
|
||||
|
||||
assertThat(messageString, not(containsString("xtension")));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEmptyExtensionTypeJson() {
|
||||
DummyPatientWithExtensions patient = new DummyPatientWithExtensions();
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Quincy").addSuffix("Jr");
|
||||
String messageString = ourCtx.newJsonParser().encodeResourceToString(patient);
|
||||
ourLog.info(messageString);
|
||||
|
||||
assertThat(messageString, not(containsString("xtension")));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
// START SNIPPET: patientUse
|
||||
MyPatient patient = new MyPatient();
|
||||
patient.setPetName(new StringDt("Fido"));
|
||||
patient.getImportantDates().add(new DateTimeDt("2010-01-02"));
|
||||
patient.getImportantDates().add(new DateTimeDt("2014-01-26T11:11:11"));
|
||||
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Quincy").addSuffix("Jr");
|
||||
|
||||
IParser p = new FhirContext().newXmlParser().setPrettyPrint(true);
|
||||
String messageString = p.encodeResourceToString(patient);
|
||||
|
||||
System.out.println(messageString);
|
||||
// END SNIPPET: patientUse
|
||||
|
||||
// START SNIPPET: patientParse
|
||||
IParser parser = new FhirContext().newXmlParser();
|
||||
MyPatient newPatient = parser.parseResource(MyPatient.class, messageString);
|
||||
// END SNIPPET: patientParse
|
||||
|
||||
{
|
||||
FhirContext ctx2 = new FhirContext();
|
||||
RuntimeResourceDefinition def = ctx2.getResourceDefinition(patient);
|
||||
System.out.println(ctx2.newXmlParser().setPrettyPrint(true).encodeResourceToString(def.toProfile()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -70,17 +70,18 @@ public class JsonParserTest {
|
|||
p.addUndeclaredExtension(extension);
|
||||
String str = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://foo#bar\"}]}", str);
|
||||
assertEquals("{\"resourceType\":\"Patient\"}", str);
|
||||
|
||||
extension.setValue(new StringDt());
|
||||
|
||||
str = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://foo#bar\"}]}", str);
|
||||
assertEquals("{\"resourceType\":\"Patient\"}", str);
|
||||
|
||||
extension.setValue(new StringDt(""));
|
||||
|
||||
str = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://foo#bar\"}]}", str);
|
||||
assertEquals("{\"resourceType\":\"Patient\"}", str);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import ca.uhn.fhir.model.api.Tag;
|
|||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu.resource.Encounter;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -135,6 +136,37 @@ public class GenericClientTest {
|
|||
assertEquals(resourceText, IOUtils.toString(((HttpPost)capt.getAllValues().get(2)).getEntity().getContent()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception {
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().addLocation().setValue("testDelete01");
|
||||
String ooStr = myCtx.newXmlParser().encodeResourceToString(oo);
|
||||
|
||||
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), 201, "OK"));
|
||||
when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") });
|
||||
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(ooStr), Charset.forName("UTF-8")));
|
||||
|
||||
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
OperationOutcome outcome = client.delete().resourceById("Patient", "123").execute();
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getValue().getURI().toString());
|
||||
assertEquals("DELETE", capt.getValue().getMethod());
|
||||
assertEquals("testDelete01",outcome.getIssueFirstRep().getLocationFirstRep().getValue());
|
||||
|
||||
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("LKJHLKJGLKJKLL"), Charset.forName("UTF-8")));
|
||||
outcome = client.delete().resourceById(new IdDt("Location", "123","456")).prettyPrint().encodedJson().execute();
|
||||
|
||||
assertEquals("http://example.com/fhir/Location/123?_format=json&_pretty=true", capt.getAllValues().get(1).getURI().toString());
|
||||
assertEquals("DELETE", capt.getValue().getMethod());
|
||||
assertEquals(null,outcome);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String getPatientFeedWithOneResult() {
|
||||
|
@ -420,7 +452,7 @@ public class GenericClientTest {
|
|||
assertNotNull(ct);
|
||||
assertEquals(Constants.CT_FHIR_JSON + "; charset=UTF-8", ct.getValue());
|
||||
|
||||
assertEquals("http://example.com/fhir", value.getURI().toString());
|
||||
assertEquals("http://example.com/fhir?_format=json", value.getURI().toString());
|
||||
assertThat(IOUtils.toString(value.getEntity().getContent()), StringContains.containsString("\"resourceType\""));
|
||||
assertEquals(bundle.getEntries().get(0).getId(), response.getEntries().get(0).getId());
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.test;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -22,6 +19,7 @@ import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
|||
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.PeriodDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Encounter;
|
||||
|
@ -32,10 +30,13 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
import ca.uhn.fhir.model.dstu.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu.valueset.EncounterClassEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.EncounterStateEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
||||
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
@ -82,7 +83,9 @@ public class CompleteResourceProviderTest {
|
|||
private static IFhirResourceDao<Questionnaire> questionnaireDao;
|
||||
|
||||
@Test
|
||||
public void testCreateWithId() {
|
||||
public void testCreateWithClientSuppliedId() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testCreateWithId01");
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testCreateWithId01");
|
||||
IdDt p1Id = ourClient.create().resource(p1).withId("testCreateWithId").execute().getId();
|
||||
|
@ -103,71 +106,37 @@ public class CompleteResourceProviderTest {
|
|||
// good
|
||||
}
|
||||
|
||||
Bundle history = ourClient.history(null, (String)null, null, null);
|
||||
Bundle history = ourClient.history(null, (String) null, null, null);
|
||||
assertEquals(p1Id.getIdPart(), history.getEntries().get(0).getId().getIdPart());
|
||||
assertNotNull(history.getEntries().get(0).getResource());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertBadReference() {
|
||||
public void testTryToCreateResourceWithReferenceThatDoesntExist() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01");
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
||||
p1.setManagingOrganization(new ResourceReferenceDt("Organization/132312323"));
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testTryToCreateResourceWithReferenceThatDoesntExist01");
|
||||
p1.addName().addFamily("testTryToCreateResourceWithReferenceThatDoesntExistFamily01").addGiven("testTryToCreateResourceWithReferenceThatDoesntExistGiven01");
|
||||
p1.setManagingOrganization(new ResourceReferenceDt("Organization/1323123232349875324987529835"));
|
||||
|
||||
try {
|
||||
ourClient.create(p1).getId();
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Organization/132312323"));
|
||||
assertThat(e.getMessage(), containsString("Organization/1323123232349875324987529835"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertUpdatesConformance() {
|
||||
// Conformance conf = ourConfProvider.getServerConformance();
|
||||
// ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conf));
|
||||
//
|
||||
// RestResource res=null;
|
||||
// for (Rest nextRest : conf.getRest()) {
|
||||
// for (RestResource nextRes : nextRest.getResource()) {
|
||||
// if (nextRes.getType().getValueAsEnum()==ResourceTypeEnum.PATIENT) {
|
||||
// res = nextRes;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// List<ExtensionDt> resCounts = res.getUndeclaredExtensionsByUrl(ExtensionConstants.CONF_RESOURCE_COUNT);
|
||||
//
|
||||
// int initial = 0;
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
||||
|
||||
ourClient.create(p1).getId();
|
||||
|
||||
// conf = ourConfProvider.getServerConformance();
|
||||
// res=null;
|
||||
// for (Rest nextRest : conf.getRest()) {
|
||||
// for (RestResource nextRes : nextRest.getResource()) {
|
||||
// if (nextRes.getType().getValueAsEnum()==ResourceTypeEnum.PATIENT) {
|
||||
// res = nextRes;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// resCounts = res.getUndeclaredExtensionsByUrl(ExtensionConstants.CONF_RESOURCE_COUNT);
|
||||
// assertNotNull(resCounts);
|
||||
// assertEquals(1, resCounts.size());
|
||||
// DecimalDt number = (DecimalDt) resCounts.get(0).getValue();
|
||||
// assertEquals(initial+1, number.getValueAsInteger());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveAndRetrieveExistingNarrative() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01");
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.getText().setStatus(NarrativeStatusEnum.GENERATED);
|
||||
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
|
||||
|
||||
IdDt newId = ourClient.create(p1).getId();
|
||||
|
||||
|
@ -188,6 +157,9 @@ public class CompleteResourceProviderTest {
|
|||
|
||||
@Test
|
||||
public void testSearchByIdentifier() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01");
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier02");
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
|
||||
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
|
||||
|
@ -205,12 +177,13 @@ public class CompleteResourceProviderTest {
|
|||
|
||||
@Test
|
||||
public void testSearchByIdentifierWithoutSystem() {
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "", "testSearchByIdentifierWithoutSystem01");
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||
IdDt p1Id = ourClient.create(p1).getId();
|
||||
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
|
||||
.execute();
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
|
||||
|
||||
|
@ -218,20 +191,19 @@ public class CompleteResourceProviderTest {
|
|||
|
||||
@Test
|
||||
public void testDeepChaining() {
|
||||
// ourClient = ourCtx.newRestfulGenericClient("http://fhir.healthintersections.com.au/open");
|
||||
// ourClient = ourCtx.newRestfulGenericClient("https://fhir.orionhealth.com/blaze/fhir");
|
||||
// ourClient = ourCtx.newRestfulGenericClient("http://spark.furore.com/fhir");
|
||||
// ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
delete("Location", Location.SP_NAME, "testDeepChainingL1");
|
||||
delete("Location", Location.SP_NAME, "testDeepChainingL2");
|
||||
deleteToken("Encounter", Encounter.SP_IDENTIFIER, "urn:foo", "testDeepChainingE1");
|
||||
|
||||
Location l1 = new Location();
|
||||
l1.getName().setValue("testDeepChainingL1");
|
||||
IdDt l1id = ourClient.create().resource(l1).execute().getId();
|
||||
|
||||
|
||||
Location l2 = new Location();
|
||||
l2.getName().setValue("testDeepChainingL2");
|
||||
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
|
||||
IdDt l2id = ourClient.create().resource(l2).execute().getId();
|
||||
|
||||
|
||||
Encounter e1 = new Encounter();
|
||||
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
|
||||
e1.getStatus().setValueAsEnum(EncounterStateEnum.IN_PROGRESS);
|
||||
|
@ -240,7 +212,7 @@ public class CompleteResourceProviderTest {
|
|||
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
|
||||
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
|
||||
IdDt e1id = ourClient.create().resource(e1).execute().getId();
|
||||
|
||||
|
||||
//@formatter:off
|
||||
Bundle res = ourClient.search()
|
||||
.forResource(Encounter.class)
|
||||
|
@ -249,15 +221,34 @@ public class CompleteResourceProviderTest {
|
|||
.include(Location.INCLUDE_PARTOF)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
|
||||
assertEquals(3, res.size());
|
||||
assertEquals(1, res.getResources(Encounter.class).size());
|
||||
assertEquals(e1id.toUnqualifiedVersionless(), res.getResources(Encounter.class).get(0).getId().toUnqualifiedVersionless());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new StringClientParam(theParamName).matches().value(theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
ourLog.info("Deleting resource: {}", next.getId());
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
ourLog.info("Deleting resource: {}", next.getId());
|
||||
ourClient.delete().resource(next).execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByResourceChain() {
|
||||
delete("Organization", Organization.SP_NAME, "testSearchByResourceChainName01");
|
||||
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByResourceChain01");
|
||||
|
||||
Organization o1 = new Organization();
|
||||
o1.setName("testSearchByResourceChainName01");
|
||||
IdDt o1id = ourClient.create(o1).getId();
|
||||
|
@ -297,63 +288,71 @@ public class CompleteResourceProviderTest {
|
|||
@SuppressWarnings("unchecked")
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourAppCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
||||
|
||||
patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
||||
PatientResourceProvider patientRp = new PatientResourceProvider();
|
||||
patientRp.setDao(patientDao);
|
||||
|
||||
questionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDao", IFhirResourceDao.class);
|
||||
QuestionnaireResourceProvider questionnaireRp = new QuestionnaireResourceProvider();
|
||||
questionnaireRp.setDao(questionnaireDao);
|
||||
|
||||
observationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
||||
ObservationResourceProvider observationRp = new ObservationResourceProvider();
|
||||
observationRp.setDao(observationDao);
|
||||
|
||||
IFhirResourceDao<Location> locationDao = (IFhirResourceDao<Location>) ourAppCtx.getBean("myLocationDao", IFhirResourceDao.class);
|
||||
LocationResourceProvider locationRp = new LocationResourceProvider();
|
||||
locationRp.setDao(locationDao);
|
||||
|
||||
IFhirResourceDao<Encounter> encounterDao = (IFhirResourceDao<Encounter>) ourAppCtx.getBean("myEncounterDao", IFhirResourceDao.class);
|
||||
EncounterResourceProvider encounterRp = new EncounterResourceProvider();
|
||||
encounterRp.setDao(encounterDao);
|
||||
|
||||
IFhirResourceDao<Organization> organizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDao", IFhirResourceDao.class);
|
||||
OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
|
||||
organizationRp.setDao(organizationDao);
|
||||
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
RestfulServer restServer = new RestfulServer();
|
||||
|
||||
restServer.setResourceProviders(encounterRp, locationRp, patientRp, questionnaireRp, observationRp, organizationRp);
|
||||
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
String serverBase = "http://localhost:" + port + "/fhir/context";
|
||||
|
||||
IFhirSystemDao systemDao = (IFhirSystemDao) ourAppCtx.getBean("mySystemDao", IFhirSystemDao.class);
|
||||
JpaSystemProvider systemProv = new JpaSystemProvider(systemDao);
|
||||
restServer.setPlainProviders(systemProv);
|
||||
|
||||
// ourConfProvider = new JpaConformanceProvider(restServer, systemDao, Collections.singletonList((IFhirResourceDao)patientDao));
|
||||
if (true) {
|
||||
ourAppCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
|
||||
|
||||
int myPort = RandomServerPortProvider.findFreePort();
|
||||
ourServer = new Server(myPort);
|
||||
patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDao", IFhirResourceDao.class);
|
||||
PatientResourceProvider patientRp = new PatientResourceProvider();
|
||||
patientRp.setDao(patientDao);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
questionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDao", IFhirResourceDao.class);
|
||||
QuestionnaireResourceProvider questionnaireRp = new QuestionnaireResourceProvider();
|
||||
questionnaireRp.setDao(questionnaireDao);
|
||||
|
||||
String serverBase = "http://localhost:" + myPort + "/fhir/context";
|
||||
// testerServlet.setServerBase("http://fhir.healthintersections.com.au/open");
|
||||
observationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDao", IFhirResourceDao.class);
|
||||
ObservationResourceProvider observationRp = new ObservationResourceProvider();
|
||||
observationRp.setDao(observationDao);
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(restServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
IFhirResourceDao<Location> locationDao = (IFhirResourceDao<Location>) ourAppCtx.getBean("myLocationDao", IFhirResourceDao.class);
|
||||
LocationResourceProvider locationRp = new LocationResourceProvider();
|
||||
locationRp.setDao(locationDao);
|
||||
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
IFhirResourceDao<Encounter> encounterDao = (IFhirResourceDao<Encounter>) ourAppCtx.getBean("myEncounterDao", IFhirResourceDao.class);
|
||||
EncounterResourceProvider encounterRp = new EncounterResourceProvider();
|
||||
encounterRp.setDao(encounterDao);
|
||||
|
||||
IFhirResourceDao<Organization> organizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDao", IFhirResourceDao.class);
|
||||
OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
|
||||
organizationRp.setDao(organizationDao);
|
||||
|
||||
restServer.setResourceProviders(encounterRp, locationRp, patientRp, questionnaireRp, observationRp, organizationRp);
|
||||
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
IFhirSystemDao systemDao = (IFhirSystemDao) ourAppCtx.getBean("mySystemDao", IFhirSystemDao.class);
|
||||
JpaSystemProvider systemProv = new JpaSystemProvider(systemDao);
|
||||
restServer.setPlainProviders(systemProv);
|
||||
|
||||
// ourConfProvider = new JpaConformanceProvider(restServer, systemDao,
|
||||
// Collections.singletonList((IFhirResourceDao)patientDao));
|
||||
|
||||
ourServer = new Server(port);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
proxyHandler.setContextPath("/");
|
||||
|
||||
// testerServlet.setServerBase("http://fhir.healthintersections.com.au/open");
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
servletHolder.setServlet(restServer);
|
||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
}
|
||||
|
||||
ourCtx = restServer.getFhirContext();
|
||||
// ourCtx.getRestfulClientFactory().setProxy("localhost", 8888);
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(serverBase);
|
||||
// ourClient = ourCtx.newRestfulGenericClient("http://fhir.healthintersections.com.au/open");
|
||||
// ourClient = ourCtx.newRestfulGenericClient("https://fhir.orionhealth.com/blaze/fhir");
|
||||
// ourClient = ourCtx.newRestfulGenericClient("http://spark.furore.com/fhir");
|
||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue