mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-03-25 01:18:37 +00:00
Support $validate operatioh in DSTU2 client
This commit is contained in:
parent
7086508ead
commit
81bfc28147
@ -12,10 +12,12 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome.Issue;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
@ -99,6 +101,29 @@ public class GenericClientExample {
|
||||
IdDt id = outcome.getId();
|
||||
// END SNIPPET: createConditional
|
||||
}
|
||||
{
|
||||
// START SNIPPET: validate
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("http://hospital.com").setValue("123445");
|
||||
patient.addName().addFamily("Smith").addGiven("John");
|
||||
|
||||
// Validate the resource
|
||||
MethodOutcome outcome = client.validate()
|
||||
.resource(patient)
|
||||
.execute();
|
||||
|
||||
// The returned object will contain an operation outcome resource
|
||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||
|
||||
// If the OperationOutcome has any issues with a severity of ERROR or SEVERE,
|
||||
// the validation failed.
|
||||
for (Issue nextIssue : oo.getIssue()) {
|
||||
if (nextIssue.getSeverityElement().getValueAsEnum().ordinal() >= IssueSeverityEnum.ERROR.ordinal()) {
|
||||
System.out.println("We failed validation!");
|
||||
}
|
||||
}
|
||||
// END SNIPPET: validate
|
||||
}
|
||||
{
|
||||
// START SNIPPET: update
|
||||
Patient patient = new Patient();
|
||||
|
@ -175,10 +175,12 @@ public abstract class BaseClient implements IRestfulClient {
|
||||
} 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;
|
||||
|
@ -104,6 +104,8 @@ import ca.uhn.fhir.rest.gclient.IUpdateExecutable;
|
||||
import ca.uhn.fhir.rest.gclient.IUpdateTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IUpdateWithQuery;
|
||||
import ca.uhn.fhir.rest.gclient.IUpdateWithQueryTyped;
|
||||
import ca.uhn.fhir.rest.gclient.IValidate;
|
||||
import ca.uhn.fhir.rest.gclient.IValidateUntyped;
|
||||
import ca.uhn.fhir.rest.method.DeleteMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.HistoryMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.HttpDeleteClientInvocation;
|
||||
@ -117,6 +119,7 @@ import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.SearchStyleEnum;
|
||||
import ca.uhn.fhir.rest.method.TransactionMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu1;
|
||||
import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu2;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
||||
@ -146,13 +149,13 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
super(theHttpClient, theServerBase, theFactory);
|
||||
myContext = theContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BaseConformance conformance() {
|
||||
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||
throw new IllegalArgumentException("Must call conformance(" + IBaseConformance.class.getSimpleName() + ") instead of conformance() for HL7.org structures");
|
||||
}
|
||||
|
||||
|
||||
HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation();
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
|
||||
@ -166,21 +169,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceConformanceCheck() {
|
||||
super.forceConformanceCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICreate create() {
|
||||
return new CreateInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirContext getFhirContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome create(IResource theResource) {
|
||||
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(theResource, myContext);
|
||||
@ -221,19 +214,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return delete(theType, new IdDt(theId));
|
||||
}
|
||||
|
||||
// public IResource read(UriDt url) {
|
||||
// return read(inferResourceClass(url), url);
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public <T extends IResource> T read(final Class<T> theType, UriDt url) {
|
||||
// return (T) invoke(theType, url, new ResourceResponseHandler<T>(theType));
|
||||
// }
|
||||
//
|
||||
// public Bundle search(UriDt url) {
|
||||
// return search(inferResourceClass(url), url);
|
||||
// }
|
||||
|
||||
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IdDt theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches) {
|
||||
String resName = toResourceName(theType);
|
||||
IdDt id = theId;
|
||||
@ -277,6 +257,34 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFetchConformanceUntyped fetchConformance() {
|
||||
return new FetchConformanceInternal();
|
||||
}
|
||||
|
||||
// public IResource read(UriDt url) {
|
||||
// return read(inferResourceClass(url), url);
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public <T extends IResource> T read(final Class<T> theType, UriDt url) {
|
||||
// return (T) invoke(theType, url, new ResourceResponseHandler<T>(theType));
|
||||
// }
|
||||
//
|
||||
// public Bundle search(UriDt url) {
|
||||
// return search(inferResourceClass(url), url);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void forceConformanceCheck() {
|
||||
super.forceConformanceCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirContext getFhirContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
public HttpRequestBase getLastRequest() {
|
||||
return myLastRequest;
|
||||
}
|
||||
@ -349,15 +357,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
}
|
||||
|
||||
public boolean isLogRequestAndResponse() {
|
||||
return myLogRequestAndResponse;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public <T extends IBaseResource> T read(final Class<T> theType, IdDt theId) {
|
||||
// return doReadOrVRead(theType, theId, false, null, null);
|
||||
// }
|
||||
|
||||
public boolean isLogRequestAndResponse() {
|
||||
return myLogRequestAndResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPage loadPage() {
|
||||
return new LoadPageInternal();
|
||||
@ -366,8 +374,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
@Override
|
||||
public IOperation operation() {
|
||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) == false) {
|
||||
throw new IllegalStateException("Operations are only supported in FHIR DSTU2 and later. This client was created using a context configured for "
|
||||
+ myContext.getVersion().getVersion().name());
|
||||
throw new IllegalStateException("Operations are only supported in FHIR DSTU2 and later. This client was created using a context configured for " + myContext.getVersion().getVersion().name());
|
||||
}
|
||||
return new OperationInternal();
|
||||
}
|
||||
@ -377,11 +384,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return new ReadInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFetchConformanceUntyped fetchConformance() {
|
||||
return new FetchConformanceInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseResource> T read(Class<T> theType, String theId) {
|
||||
return read(theType, new IdDt(theId));
|
||||
@ -505,17 +507,20 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return update(new IdDt(theId), theResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IValidate validate() {
|
||||
return new ValidateInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome validate(IResource theResource) {
|
||||
BaseHttpClientInvocation invocation;
|
||||
// if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
||||
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
||||
invocation = ValidateMethodBindingDstu1.createValidateInvocation(theResource, null, myContext);
|
||||
// } else {
|
||||
// invocation = ValidateMethodBindingDstu2.createOperationInvocation(theContext, theResourceName, theId, theOperationName, theInput, theUseHttpGet)
|
||||
// //createValidateInvocation(theResource, null, myContext);
|
||||
// }
|
||||
|
||||
|
||||
} else {
|
||||
invocation = ValidateMethodBindingDstu2.createValidateInvocation(myContext, theResource);
|
||||
}
|
||||
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
|
||||
}
|
||||
@ -611,7 +616,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return encoding.newParser(myContext).parseResource(theResourceBody);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T prettyPrint() {
|
||||
@ -620,7 +624,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private final class BundleResponseHandler implements IClientResponseHandler<Bundle> {
|
||||
|
||||
private Class<? extends IBaseResource> myType;
|
||||
@ -630,8 +634,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);
|
||||
@ -641,15 +644,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
}
|
||||
|
||||
private final class StringResponseHandler implements IClientResponseHandler<String> {
|
||||
|
||||
@Override
|
||||
public String invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
return IOUtils.toString(theResponseReader);
|
||||
}
|
||||
}
|
||||
|
||||
private class CreateInternal extends BaseClientExecutable<ICreateTyped, MethodOutcome> implements ICreate, ICreateTyped, ICreateWithQuery, ICreateWithQueryTyped {
|
||||
|
||||
private CriterionList myCriterionList;
|
||||
@ -851,11 +845,34 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private class FetchConformanceInternal extends BaseClientExecutable implements IFetchConformanceUntyped, IFetchConformanceTyped {
|
||||
private RuntimeResourceDefinition myType;
|
||||
|
||||
@Override
|
||||
public Object execute() {
|
||||
ResourceResponseHandler binding = new ResourceResponseHandler(myType.getImplementingClass(), null);
|
||||
HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation();
|
||||
return invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseConformance> IFetchConformanceTyped<T> ofType(Class<T> theResourceType) {
|
||||
Validate.notNull(theResourceType, "theResourceType must not be null");
|
||||
myType = myContext.getResourceDefinition(theResourceType);
|
||||
if (myType == null) {
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_CANNOT_DETEMINE_RESOURCE_TYPE, theResourceType));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private class GetPageInternal extends BaseClientExecutable<IGetPageTyped<Object>, Object> implements IGetPageTyped<Object> {
|
||||
|
||||
private String myUrl;
|
||||
private Class<? extends IBaseBundle> myBundleType;
|
||||
private String myUrl;
|
||||
|
||||
public GetPageInternal(String theUrl) {
|
||||
myUrl = theUrl;
|
||||
@ -1042,28 +1059,38 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private final class LoadPageInternal implements IGetPage, IGetPageUntyped {
|
||||
|
||||
private static final String PREVIOUS = "previous";
|
||||
private static final String PREV = "prev";
|
||||
private static final String PREVIOUS = "previous";
|
||||
private String myPageUrl;
|
||||
|
||||
@Override
|
||||
public <T extends IBaseBundle> IGetPageTyped andReturnBundle(Class<T> theBundleType) {
|
||||
Validate.notNull(theBundleType, "theBundleType must not be null");
|
||||
return new GetPageInternal(myPageUrl, theBundleType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageTyped andReturnDstu1Bundle() {
|
||||
return new GetPageInternal(myPageUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageUntyped byUrl(String thePageUrl) {
|
||||
if (isBlank(thePageUrl)) {
|
||||
throw new IllegalArgumentException("thePagingUrl must not be blank or null");
|
||||
}
|
||||
myPageUrl = thePageUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageTyped next(Bundle theBundle) {
|
||||
return new GetPageInternal(theBundle.getLinkNext().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageTyped previous(Bundle theBundle) {
|
||||
return new GetPageInternal(theBundle.getLinkPrevious().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageTyped url(String thePageUrl) {
|
||||
return new GetPageInternal(thePageUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseBundle> IGetPageTyped<T> next(T theBundle) {
|
||||
return nextOrPrevious("next", theBundle);
|
||||
@ -1081,13 +1108,13 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
if (rel == null || rel.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String relation = ((IPrimitiveType<?>)rel.get(0)).getValueAsString();
|
||||
String relation = ((IPrimitiveType<?>) rel.get(0)).getValueAsString();
|
||||
if (theWantRel.equals(relation) || (theWantRel == PREVIOUS && PREV.equals(relation))) {
|
||||
List<IBase> urls = linkDef.getChildByName("url").getAccessor().getValues(nextLink);
|
||||
if (urls == null || urls.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String url = ((IPrimitiveType<?>)urls.get(0)).getValueAsString();
|
||||
String url = ((IPrimitiveType<?>) urls.get(0)).getValueAsString();
|
||||
if (isBlank(url)) {
|
||||
continue;
|
||||
}
|
||||
@ -1096,30 +1123,20 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "noPagingLinkFoundInBundle", theWantRel));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IGetPageTyped previous(Bundle theBundle) {
|
||||
return new GetPageInternal(theBundle.getLinkPrevious().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseBundle> IGetPageTyped<T> previous(T theBundle) {
|
||||
return nextOrPrevious(PREVIOUS, theBundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageUntyped byUrl(String thePageUrl) {
|
||||
if (isBlank(thePageUrl)) {
|
||||
throw new IllegalArgumentException("thePagingUrl must not be blank or null");
|
||||
}
|
||||
myPageUrl = thePageUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGetPageTyped andReturnDstu1Bundle() {
|
||||
return new GetPageInternal(myPageUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseBundle> IGetPageTyped andReturnBundle(Class<T> theBundleType) {
|
||||
Validate.notNull(theBundleType, "theBundleType must not be null");
|
||||
return new GetPageInternal(myPageUrl, theBundleType);
|
||||
public IGetPageTyped url(String thePageUrl) {
|
||||
return new GetPageInternal(thePageUrl);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1197,11 +1214,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Override
|
||||
public IOperationUntypedWithInput withParameters(IBaseParameters theParameters) {
|
||||
Validate.notNull(theParameters, "theParameters can not be null");
|
||||
myParameters = theParameters;
|
||||
public IOperationUntypedWithInput useHttpGet() {
|
||||
myUseHttpGet = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1214,16 +1229,17 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type: " + theOutputParameterType.getName());
|
||||
}
|
||||
if (!"Parameters".equals(def.getName())) {
|
||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName()
|
||||
+ " is a resource named: " + def.getName());
|
||||
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName() + " is a resource named: " + def.getName());
|
||||
}
|
||||
myParameters = (IBaseParameters) def.newInstance();
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Override
|
||||
public IOperationUntypedWithInput useHttpGet() {
|
||||
myUseHttpGet = true;
|
||||
public IOperationUntypedWithInput withParameters(IBaseParameters theParameters) {
|
||||
Validate.notNull(theParameters, "theParameters can not be null");
|
||||
myParameters = theParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1232,8 +1248,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
private final class OperationOutcomeResponseHandler implements IClientResponseHandler<BaseOperationOutcome> {
|
||||
|
||||
@Override
|
||||
public BaseOperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
public BaseOperationOutcome 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;
|
||||
@ -1261,8 +1276,7 @@ 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);
|
||||
if (theResponseStatusCode == Constants.STATUS_HTTP_201_CREATED) {
|
||||
response.setCreated(true);
|
||||
@ -1402,8 +1416,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||
BaseServerResponseException {
|
||||
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||
Class<? extends IBaseResource> bundleType = myContext.getResourceDefinition("Bundle").getImplementingClass();
|
||||
ResourceResponseHandler<IBaseResource> handler = new ResourceResponseHandler<IBaseResource>((Class<IBaseResource>) bundleType, null);
|
||||
@ -1448,14 +1461,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
private String myCompartmentName;
|
||||
private CriterionList myCriterion = new CriterionList();
|
||||
private List<Include> myInclude = new ArrayList<Include>();
|
||||
private List<Include> myRevInclude = new ArrayList<Include>();
|
||||
private Integer myParamLimit;
|
||||
private String myResourceId;
|
||||
private String myResourceName;
|
||||
private Class<? extends IBaseResource> myResourceType;
|
||||
private Class<? extends IBaseBundle> myReturnBundleType;
|
||||
private List<Include> myRevInclude = new ArrayList<Include>();
|
||||
private SearchStyleEnum mySearchStyle;
|
||||
private List<SortInternal> mySort = new ArrayList<SortInternal>();
|
||||
private Class<? extends IBaseBundle> myReturnBundleType;
|
||||
|
||||
public SearchInternal() {
|
||||
myResourceType = null;
|
||||
@ -1496,8 +1509,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
|
||||
if (myReturnBundleType == null && myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||
throw new IllegalArgumentException("When using the client with HL7.org structures, you must specify "
|
||||
+ "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
|
||||
throw new IllegalArgumentException("When using the client with HL7.org structures, you must specify " + "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
|
||||
}
|
||||
|
||||
IClientResponseHandler<? extends IBase> binding;
|
||||
@ -1548,6 +1560,21 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClientExecutable returnBundle(Class theClass) {
|
||||
if (theClass == null) {
|
||||
throw new NullPointerException("theClass must not be null");
|
||||
}
|
||||
myReturnBundleType = theClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery revInclude(Include theInclude) {
|
||||
myRevInclude.add(theInclude);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void setType(Class<? extends IBaseResource> theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
RuntimeResourceDefinition definition = myContext.getResourceDefinition(theResourceType);
|
||||
@ -1585,21 +1612,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQuery revInclude(Include theInclude) {
|
||||
myRevInclude.add(theInclude);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClientExecutable returnBundle(Class theClass) {
|
||||
if (theClass == null) {
|
||||
throw new NullPointerException("theClass must not be null");
|
||||
}
|
||||
myReturnBundleType = theClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@ -1644,11 +1656,18 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
}
|
||||
|
||||
private final class StringResponseHandler implements IClientResponseHandler<String> {
|
||||
|
||||
@Override
|
||||
public String invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
return IOUtils.toString(theResponseReader);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@ -1660,24 +1679,24 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
private final class TransactionExecutable<T> extends BaseClientExecutable<ITransactionTyped<T>, T> implements ITransactionTyped<T> {
|
||||
|
||||
private Bundle myBundle;
|
||||
private List<? extends IBaseResource> myResources;
|
||||
private IBaseBundle myBaseBundle;
|
||||
private Bundle myBundle;
|
||||
private String myRawBundle;
|
||||
private EncodingEnum myRawBundleEncoding;
|
||||
private List<? extends IBaseResource> myResources;
|
||||
|
||||
public TransactionExecutable(Bundle theResources) {
|
||||
myBundle = theResources;
|
||||
}
|
||||
|
||||
public TransactionExecutable(List<? extends IBaseResource> theResources) {
|
||||
myResources = theResources;
|
||||
}
|
||||
|
||||
public TransactionExecutable(IBaseBundle theBundle) {
|
||||
myBaseBundle = theBundle;
|
||||
}
|
||||
|
||||
public TransactionExecutable(List<? extends IBaseResource> theResources) {
|
||||
myResources = theResources;
|
||||
}
|
||||
|
||||
public TransactionExecutable(String theBundle) {
|
||||
myRawBundle = theBundle;
|
||||
myRawBundleEncoding = MethodUtil.detectEncodingNoDefault(myRawBundle);
|
||||
@ -1729,9 +1748,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITransactionTyped<List<IBaseResource>> withResources(List<? extends IBaseResource> theResources) {
|
||||
Validate.notNull(theResources, "theResources must not be null");
|
||||
return new TransactionExecutable<List<IBaseResource>>(theResources);
|
||||
public ITransactionTyped<String> withBundle(String theBundle) {
|
||||
Validate.notBlank(theBundle, "theBundle must not be null");
|
||||
return new TransactionExecutable<String>(theBundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1741,9 +1760,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITransactionTyped<String> withBundle(String theBundle) {
|
||||
Validate.notBlank(theBundle, "theBundle must not be null");
|
||||
return new TransactionExecutable<String>(theBundle);
|
||||
public ITransactionTyped<List<IBaseResource>> withResources(List<? extends IBaseResource> theResources) {
|
||||
Validate.notNull(theResources, "theResources must not be null");
|
||||
return new TransactionExecutable<List<IBaseResource>>(theResources);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1856,32 +1875,42 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private class FetchConformanceInternal extends BaseClientExecutable implements IFetchConformanceUntyped, IFetchConformanceTyped {
|
||||
private RuntimeResourceDefinition myType;
|
||||
private class ValidateInternal extends BaseClientExecutable<IValidateUntyped, MethodOutcome> implements IValidate, IValidateUntyped {
|
||||
private IBaseResource myResource;
|
||||
|
||||
@Override
|
||||
public Object execute() {
|
||||
ResourceResponseHandler binding = new ResourceResponseHandler(myType.getImplementingClass(), null);
|
||||
HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation();
|
||||
return invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
|
||||
public MethodOutcome execute() {
|
||||
BaseHttpClientInvocation invocation = ValidateMethodBindingDstu2.createValidateInvocation(myContext, myResource);
|
||||
ResourceResponseHandler<BaseOperationOutcome> handler = new ResourceResponseHandler<BaseOperationOutcome>(null, null);
|
||||
BaseOperationOutcome outcome = invoke(null, handler, invocation);
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
retVal.setOperationOutcome(outcome);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IValidateUntyped resource(IBaseResource theResource) {
|
||||
Validate.notNull(theResource, "theResource must not be null");
|
||||
myResource = theResource;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseConformance> IFetchConformanceTyped<T> ofType(Class<T> theResourceType) {
|
||||
Validate.notNull(theResourceType, "theResourceType must not be null");
|
||||
myType = myContext.getResourceDefinition(theResourceType);
|
||||
if (myType == null) {
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_CANNOT_DETEMINE_RESOURCE_TYPE, theResourceType));
|
||||
public IValidateUntyped resource(String theResourceRaw) {
|
||||
Validate.notBlank(theResourceRaw, "theResourceRaw must not be null or blank");
|
||||
myResource = parseResourceBody(theResourceRaw);
|
||||
|
||||
EncodingEnum enc = MethodUtil.detectEncodingNoDefault(theResourceRaw);
|
||||
if (enc==null) {
|
||||
throw new IllegalArgumentException("Could not detect encoding (XML/JSON) in string. Is this a valid FHIR resource?");
|
||||
}
|
||||
switch (enc) {
|
||||
case XML:
|
||||
encodedXml();
|
||||
break;
|
||||
case JSON:
|
||||
encodedJson();
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ import ca.uhn.fhir.rest.gclient.IRead;
|
||||
import ca.uhn.fhir.rest.gclient.ITransaction;
|
||||
import ca.uhn.fhir.rest.gclient.IUntypedQuery;
|
||||
import ca.uhn.fhir.rest.gclient.IUpdate;
|
||||
import ca.uhn.fhir.rest.gclient.IValidate;
|
||||
|
||||
public interface IGenericClient extends IRestfulClient {
|
||||
|
||||
@ -238,6 +239,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||
/**
|
||||
* Register a new interceptor for this client. An interceptor can be used to add additional logging, or add security headers, or pre-process responses, etc.
|
||||
*/
|
||||
@Override
|
||||
void registerInterceptor(IClientInterceptor theInterceptor);
|
||||
|
||||
IUntypedQuery search();
|
||||
@ -278,6 +280,11 @@ public interface IGenericClient extends IRestfulClient {
|
||||
*/
|
||||
ITransaction transaction();
|
||||
|
||||
/**
|
||||
* Validate a resource
|
||||
*/
|
||||
IValidate validate();
|
||||
|
||||
/**
|
||||
* Implementation of the "transaction" method.
|
||||
*
|
||||
@ -293,6 +300,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||
/**
|
||||
* Remove an intercaptor that was previously registered using {@link IRestfulClient#registerInterceptor(IClientInterceptor)}
|
||||
*/
|
||||
@Override
|
||||
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,37 @@
|
||||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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 org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
public interface IValidate {
|
||||
|
||||
/**
|
||||
* Use a resource as validate input
|
||||
*/
|
||||
IValidateUntyped resource(IBaseResource theResource);
|
||||
|
||||
/**
|
||||
* Use a raw resource as validate input
|
||||
*/
|
||||
IValidateUntyped resource(String theRawResource);
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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 IValidateUntyped extends IClientExecutable<IValidateUntyped, MethodOutcome> {
|
||||
|
||||
// nothing for now
|
||||
|
||||
}
|
@ -66,14 +66,16 @@ public class ValidateMethodBindingDstu2 extends OperationMethodBinding {
|
||||
}
|
||||
|
||||
|
||||
public static BaseHttpClientInvocation createValidationMethodBinding(FhirContext theContext, IBaseResource theResource) {
|
||||
public static BaseHttpClientInvocation createValidateInvocation(FhirContext theContext, IBaseResource theResource) {
|
||||
IBaseParameters parameters = (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance();
|
||||
|
||||
OperationParameter.addParameterToParameters(theContext, parameters, theResource, "resource");
|
||||
|
||||
String resourceName = theContext.getResourceDefinition(theResource).getName();
|
||||
String resourceId = theResource.getIdElement().getIdPart();
|
||||
return createOperationInvocation(theContext, resourceName, resourceId, Constants.EXTOP_VALIDATE, parameters, false);
|
||||
|
||||
BaseHttpClientInvocation retVal = createOperationInvocation(theContext, resourceName, resourceId, Constants.EXTOP_VALIDATE, parameters, false);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
|
||||
@ -182,14 +181,6 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
||||
oo.getIssue().add((Issue) next);
|
||||
}
|
||||
|
||||
if (oo.getIssue().size() > 0) {
|
||||
/*
|
||||
* It is also possible to pass an OperationOutcome resource to the UnprocessableEntityException if you want to return a custom populated OperationOutcome. Otherwise, a simple one is
|
||||
* created using the string supplied below.
|
||||
*/
|
||||
throw new UnprocessableEntityException("Validation failed", oo);
|
||||
}
|
||||
|
||||
// This method returns a MethodOutcome object
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.INFORMATION).setDetails("Validation succeeded");
|
||||
|
@ -69,7 +69,7 @@ public class GenericClientTest {
|
||||
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
|
||||
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
@ -291,7 +291,7 @@ public class GenericClientTest {
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
MethodOutcome outcome = client.create(p1);
|
||||
MethodOutcome outcome = client.create().resource(p1).execute();
|
||||
assertEquals("44", outcome.getId().getIdPart());
|
||||
assertEquals("22", outcome.getId().getVersionIdPart());
|
||||
|
||||
@ -1177,7 +1177,7 @@ public class GenericClientTest {
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir", capt.getValue().getURI().toString());
|
||||
assertEquals(bundle.getEntries().get(0).getId(), response.getEntries().get(0).getId());
|
||||
assertEquals(bundle.getEntries().get(0).getResource().getId(), response.getEntries().get(0).getResource().getId());
|
||||
assertEquals(EncodingEnum.XML.getBundleContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
|
||||
}
|
||||
@ -1210,7 +1210,7 @@ public class GenericClientTest {
|
||||
|
||||
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());
|
||||
assertEquals(bundle.getEntries().get(0).getResource().getId(), response.getEntries().get(0).getResource().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,7 +16,6 @@ import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
@ -36,12 +35,14 @@ import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
@ -339,7 +340,7 @@ public class GenericClientDstu2Test {
|
||||
assertEquals("http://example.com/fhir/Patient/123/$SOMEOPERATION?param1=STRINGVALIN1¶m1=STRINGVALIN1b¶m2=STRINGVALIN2", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOperationAsGetWithNoInParameters() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
@ -419,6 +420,48 @@ public class GenericClientDstu2Test {
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithBundleResponseJson() throws Exception {
|
||||
|
||||
final String resp = "{\n" +
|
||||
" \"resourceType\":\"Bundle\",\n" +
|
||||
" \"id\":\"8cef5f2a-0ba9-43a5-be26-c8dde9ff0e19\",\n" +
|
||||
" \"base\":\"http://fhirtest.uhn.ca/baseDstu2\"\n" +
|
||||
"}";
|
||||
|
||||
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_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(resp), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateDt("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateDt("2015-03-01"));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client.operation().onInstance(new IdDt("Patient", "18066")).named("$everything").withParameters(inParams).execute();
|
||||
|
||||
/*
|
||||
* Note that the $everything operation returns a Bundle instead of a Parameters resource. The client operation methods return a Parameters instance however, so HAPI creates a Parameters object
|
||||
* with a single parameter containing the value.
|
||||
*/
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle responseBundle = (ca.uhn.fhir.model.dstu2.resource.Bundle) outParams.getParameter().get(0).getResource();
|
||||
|
||||
// Print the response bundle
|
||||
assertEquals("8cef5f2a-0ba9-43a5-be26-c8dde9ff0e19", responseBundle.getId().getIdPart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithBundleResponseXml() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
@ -464,48 +507,6 @@ public class GenericClientDstu2Test {
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithBundleResponseJson() throws Exception {
|
||||
|
||||
final String resp = "{\n" +
|
||||
" \"resourceType\":\"Bundle\",\n" +
|
||||
" \"id\":\"8cef5f2a-0ba9-43a5-be26-c8dde9ff0e19\",\n" +
|
||||
" \"base\":\"http://fhirtest.uhn.ca/baseDstu2\"\n" +
|
||||
"}";
|
||||
|
||||
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_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(resp), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateDt("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateDt("2015-03-01"));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client.operation().onInstance(new IdDt("Patient", "18066")).named("$everything").withParameters(inParams).execute();
|
||||
|
||||
/*
|
||||
* Note that the $everything operation returns a Bundle instead of a Parameters resource. The client operation methods return a Parameters instance however, so HAPI creates a Parameters object
|
||||
* with a single parameter containing the value.
|
||||
*/
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle responseBundle = (ca.uhn.fhir.model.dstu2.resource.Bundle) outParams.getParameter().get(0).getResource();
|
||||
|
||||
// Print the response bundle
|
||||
assertEquals("8cef5f2a-0ba9-43a5-be26-c8dde9ff0e19", responseBundle.getId().getIdPart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithListOfParameterResponse() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
@ -1020,6 +1021,95 @@ public class GenericClientDstu2Test {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateNonFluent() throws Exception {
|
||||
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().setDetails("FOOBAR");
|
||||
final String msg = ourCtx.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), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addGiven("GIVEN");
|
||||
|
||||
int idx = 0;
|
||||
MethodOutcome response;
|
||||
|
||||
//@formatter:off
|
||||
response = client.validate(p);
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateFluent() throws Exception {
|
||||
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().setDetails("FOOBAR");
|
||||
final String msg = ourCtx.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), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addGiven("GIVEN");
|
||||
|
||||
int idx = 0;
|
||||
MethodOutcome response;
|
||||
|
||||
response = client.validate().resource(p).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
|
||||
response = client.validate().resource(ourCtx.newXmlParser().encodeResourceToString(p)).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate?_format=xml", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
|
||||
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate?_format=json", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"resource\",\"resource\":{\"resourceType\":\"Patient\",\"name\":[{\"given\":[\"GIVEN\"]}]}}]}", extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forDstu2();
|
||||
|
@ -89,6 +89,12 @@
|
||||
or "urn:uuid:" / "urn:oid:" (for DSTU2) this is now correctly passed as
|
||||
the base in resource.getId()
|
||||
</action>
|
||||
<action type="add">
|
||||
Add fluent client method for validate operation, and support the
|
||||
new DSTU2 style extended operation for $validate if the client is
|
||||
in DSTU2 mode. Thanks to Eric from the FHIR Skype Implementers chat for
|
||||
reporting.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.0" date="2015-May-8">
|
||||
<action type="add">
|
||||
|
@ -461,6 +461,23 @@
|
||||
</macro>
|
||||
</subsection>
|
||||
|
||||
<subsection name="Built-In Operations - Validate">
|
||||
<p>
|
||||
The $validate operation asks the server to test a given resource
|
||||
to see if it would be acceptable as a create/update on that server.
|
||||
The client has built-in support for this operation.
|
||||
</p>
|
||||
<p class="doc_info_bubble">
|
||||
If the client is in DSTU1 mode, the method below will invoke the
|
||||
DSTU1 validation style instead.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="validate" />
|
||||
<param name="file" value="examples/src/main/java/example/GenericClientExample.java" />
|
||||
</macro>
|
||||
|
||||
|
||||
</subsection>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user