Merge branch 'hugosoares-master'
This commit is contained in:
commit
5ba2248573
|
@ -24,15 +24,41 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.context.IRuntimeDatatypeDefinition;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
@ -45,13 +71,84 @@ import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.UriDt;
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.api.*;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.PatchTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.SortSpec;
|
||||||
|
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
||||||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
||||||
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
import ca.uhn.fhir.rest.gclient.*;
|
import ca.uhn.fhir.rest.gclient.IClientExecutable;
|
||||||
import ca.uhn.fhir.rest.method.*;
|
import ca.uhn.fhir.rest.gclient.ICreate;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ICreateTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ICreateWithQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ICreateWithQueryTyped;
|
||||||
|
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.IDeleteWithQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IDeleteWithQueryTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IFetchConformanceTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IFetchConformanceUntyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IGetPage;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IGetPageTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IGetPageUntyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IGetTags;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IHistory;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IHistoryTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IHistoryUntyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IMeta;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IMetaAddOrDeleteSourced;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IMetaAddOrDeleteUnsourced;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IMetaGetUnsourced;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperation;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperationProcessMsg;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperationProcessMsgMode;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperationUnnamed;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperationUntyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInput;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IParam;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IPatch;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IPatchExecutable;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IPatchWithBody;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IPatchWithQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IPatchWithQueryTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IRead;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IReadExecutable;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IReadIfNoneMatch;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IReadTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ISort;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ITransaction;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ITransactionTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IUntypedQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IUpdate;
|
||||||
|
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;
|
||||||
|
import ca.uhn.fhir.rest.method.HttpGetClientInvocation;
|
||||||
|
import ca.uhn.fhir.rest.method.HttpSimpleGetClientInvocation;
|
||||||
|
import ca.uhn.fhir.rest.method.IClientResponseHandler;
|
||||||
|
import ca.uhn.fhir.rest.method.MethodUtil;
|
||||||
|
import ca.uhn.fhir.rest.method.OperationMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.ReadMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.SearchStyleEnum;
|
||||||
|
import ca.uhn.fhir.rest.method.SortParameter;
|
||||||
|
import ca.uhn.fhir.rest.method.TransactionMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu1;
|
||||||
|
import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu2Plus;
|
||||||
import ca.uhn.fhir.rest.param.DateParam;
|
import ca.uhn.fhir.rest.param.DateParam;
|
||||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
|
@ -87,7 +184,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public IBaseConformance conformance() {
|
public IBaseConformance conformance() {
|
||||||
if (myContext.getVersion().getVersion().isRi()) {
|
if (myContext.getVersion().getVersion().isRi()) {
|
||||||
|
@ -112,7 +209,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return new CreateInternal();
|
return new CreateInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //overide deprecated method
|
@Deprecated // overide deprecated method
|
||||||
@Override
|
@Override
|
||||||
public MethodOutcome create(IBaseResource theResource) {
|
public MethodOutcome create(IBaseResource theResource) {
|
||||||
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(theResource, myContext);
|
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(theResource, myContext);
|
||||||
|
@ -135,7 +232,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return new DeleteInternal();
|
return new DeleteInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public MethodOutcome delete(final Class<? extends IBaseResource> theType, IdDt theId) {
|
public MethodOutcome delete(final Class<? extends IBaseResource> theType, IdDt theId) {
|
||||||
HttpDeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), theId.withResourceType(toResourceName(theType)));
|
HttpDeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), theId.withResourceType(toResourceName(theType)));
|
||||||
|
@ -149,7 +246,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public MethodOutcome delete(Class<? extends IBaseResource> theType, String theId) {
|
public MethodOutcome delete(Class<? extends IBaseResource> theType, String theId) {
|
||||||
return delete(theType, new IdDt(theId));
|
return delete(theType, new IdDt(theId));
|
||||||
|
@ -248,7 +345,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return new HistoryInternal();
|
return new HistoryInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public <T extends IBaseResource> Bundle history(final Class<T> theType, IdDt theIdDt, DateTimeDt theSince, Integer theLimit) {
|
public <T extends IBaseResource> Bundle history(final Class<T> theType, IdDt theIdDt, DateTimeDt theSince, Integer theLimit) {
|
||||||
String resourceName = theType != null ? toResourceName(theType) : null;
|
String resourceName = theType != null ? toResourceName(theType) : null;
|
||||||
|
@ -264,7 +361,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public <T extends IBaseResource> Bundle history(Class<T> theType, String theId, DateTimeDt theSince, Integer theLimit) {
|
public <T extends IBaseResource> Bundle history(Class<T> theType, String theId, DateTimeDt theSince, Integer theLimit) {
|
||||||
return history(theType, new IdDt(theId), theSince, theLimit);
|
return history(theType, new IdDt(theId), theSince, theLimit);
|
||||||
|
@ -414,7 +511,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
myLastRequest = theLastRequest;
|
myLastRequest = theLastRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public void setLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
public void setLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
||||||
myLogRequestAndResponse = theLogRequestAndResponse;
|
myLogRequestAndResponse = theLogRequestAndResponse;
|
||||||
|
@ -429,7 +526,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return new TransactionInternal();
|
return new TransactionInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public List<IBaseResource> transaction(List<IBaseResource> theResources) {
|
public List<IBaseResource> transaction(List<IBaseResource> theResources) {
|
||||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(theResources, myContext);
|
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(theResources, myContext);
|
||||||
|
@ -576,7 +673,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
protected SummaryEnum mySummaryMode;
|
protected SummaryEnum mySummaryMode;
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public T andLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
public T andLogRequestAndResponse(boolean theLogRequestAndResponse) {
|
||||||
|
@ -1214,7 +1311,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return nextOrPrevious(PREVIOUS, theBundle);
|
return nextOrPrevious(PREVIOUS, theBundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public IGetPageTyped url(String thePageUrl) {
|
public IGetPageTyped url(String thePageUrl) {
|
||||||
return new GetPageInternal(thePageUrl);
|
return new GetPageInternal(thePageUrl);
|
||||||
|
@ -1371,7 +1468,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private class OperationInternal extends BaseClientExecutable implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput, IOperationUntypedWithInputAndPartialOutput {
|
private class OperationInternal extends BaseClientExecutable
|
||||||
|
implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput, IOperationUntypedWithInputAndPartialOutput, IOperationProcessMsg, IOperationProcessMsgMode {
|
||||||
|
|
||||||
private IIdType myId;
|
private IIdType myId;
|
||||||
private String myOperationName;
|
private String myOperationName;
|
||||||
|
@ -1380,6 +1478,50 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
private Class<? extends IBaseResource> myType;
|
private Class<? extends IBaseResource> myType;
|
||||||
private boolean myUseHttpGet;
|
private boolean myUseHttpGet;
|
||||||
private Class myReturnResourceType;
|
private Class myReturnResourceType;
|
||||||
|
private IBaseBundle myMsgBundle;
|
||||||
|
private String myResponseUrl;
|
||||||
|
private Boolean myIsAsync;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public IOperationProcessMsgMode setMessageBundle(IBaseBundle theMsgBundle) {
|
||||||
|
|
||||||
|
Validate.notNull(theMsgBundle, "theMsgBundle must not be null");
|
||||||
|
/*
|
||||||
|
* Validate.isTrue(theMsgBundle.getType().getValueAsEnum() == BundleTypeEnum.MESSAGE);
|
||||||
|
* Validate.isTrue(theMsgBundle.getEntries().size() > 0);
|
||||||
|
* Validate.notNull(theMsgBundle.getEntries().get(0).getResource(), "Message Bundle first entry must be a MessageHeader resource");
|
||||||
|
* Validate.isTrue(theMsgBundle.getEntries().get(0).getResource().getResourceName().equals("MessageHeader"), "Message Bundle first entry must be a MessageHeader resource");
|
||||||
|
*/
|
||||||
|
myMsgBundle = theMsgBundle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IOperationProcessMsg setResponseUrlParam(String responseUrl) {
|
||||||
|
Validate.notEmpty(responseUrl, "responseUrl must not be null");
|
||||||
|
Validate.matchesPattern(responseUrl, "^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]", "responseUrl must be a valid URL");
|
||||||
|
myResponseUrl = responseUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IOperationProcessMsgMode asynchronous(Class theResponseClass) {
|
||||||
|
myIsAsync = true;
|
||||||
|
Validate.notNull(theResponseClass, "theReturnType must not be null");
|
||||||
|
Validate.isTrue(IBaseResource.class.isAssignableFrom(theResponseClass), "theReturnType must be a class which extends from IBaseResource");
|
||||||
|
myReturnResourceType = theResponseClass;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IOperationProcessMsgMode synchronous(Class theResponseClass) {
|
||||||
|
myIsAsync = false;
|
||||||
|
Validate.notNull(theResponseClass, "theReturnType must not be null");
|
||||||
|
Validate.isTrue(IBaseResource.class.isAssignableFrom(theResponseClass), "theReturnType must be a class which extends from IBaseResource");
|
||||||
|
myReturnResourceType = theResponseClass;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void addParam(String theName, IBase theValue) {
|
private void addParam(String theName, IBase theValue) {
|
||||||
|
@ -1411,6 +1553,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IOperationProcessMsg processMessage() {
|
||||||
|
myOperationName = Constants.EXTOP_PROCESS_MESSAGE;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private void addParam(String theName, IQueryParameterType theValue) {
|
private void addParam(String theName, IQueryParameterType theValue) {
|
||||||
IPrimitiveType<?> stringType = ParametersUtil.createString(myContext, theValue.getValueAsQueryToken(myContext));
|
IPrimitiveType<?> stringType = ParametersUtil.createString(myContext, theValue.getValueAsQueryToken(myContext));
|
||||||
addParam(theName, stringType);
|
addParam(theName, stringType);
|
||||||
|
@ -1434,6 +1582,26 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Object execute() {
|
public Object execute() {
|
||||||
|
if (myOperationName != null && myOperationName.equals(Constants.EXTOP_PROCESS_MESSAGE)) {
|
||||||
|
Map<String, List<String>> urlParams = new LinkedHashMap<String, List<String>>();
|
||||||
|
// Set Url parameter Async and Response-Url
|
||||||
|
if (myIsAsync != null) {
|
||||||
|
urlParams.put(Constants.PARAM_ASYNC, Arrays.asList(String.valueOf(myIsAsync)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myResponseUrl != null && isNotBlank(myResponseUrl)) {
|
||||||
|
urlParams.put(Constants.PARAM_RESPONSE_URL, Arrays.asList(String.valueOf(myResponseUrl)));
|
||||||
|
}
|
||||||
|
// If is $process-message operation
|
||||||
|
BaseHttpClientInvocation invocation = OperationMethodBinding.createProcessMsgInvocation(myContext, myOperationName, myMsgBundle, urlParams);
|
||||||
|
|
||||||
|
ResourceResponseHandler handler = new ResourceResponseHandler();
|
||||||
|
handler.setPreferResponseTypes(getPreferResponseTypes(myType));
|
||||||
|
|
||||||
|
Object retVal = invoke(null, handler, invocation);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
String resourceName;
|
String resourceName;
|
||||||
String id;
|
String id;
|
||||||
if (myType != null) {
|
if (myType != null) {
|
||||||
|
@ -1597,10 +1765,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
private final class OutcomeResponseHandler implements IClientResponseHandler<MethodOutcome> {
|
private final class OutcomeResponseHandler implements IClientResponseHandler<MethodOutcome> {
|
||||||
private PreferReturnEnum myPrefer;
|
private PreferReturnEnum myPrefer;
|
||||||
// private final String myResourceName;
|
// private final String myResourceName;
|
||||||
|
|
||||||
private OutcomeResponseHandler(String theResourceName) {
|
private OutcomeResponseHandler(String theResourceName) {
|
||||||
// myResourceName = theResourceName;
|
// myResourceName = theResourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OutcomeResponseHandler(String theResourceName, PreferReturnEnum thePrefer) {
|
private OutcomeResponseHandler(String theResourceName, PreferReturnEnum thePrefer) {
|
||||||
|
@ -1854,7 +2022,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public IBase execute() {
|
public IBase execute() {
|
||||||
|
|
||||||
|
@ -1911,11 +2079,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
if (rootSs == null) {
|
if (rootSs == null) {
|
||||||
rootSs = nextSortSpec;
|
rootSs = nextSortSpec;
|
||||||
} else {
|
} else {
|
||||||
//FIXME lastSs is null never set
|
// FIXME lastSs is null never set
|
||||||
//TODO unused assignment
|
// TODO unused assignment
|
||||||
lastSs.setChain(nextSortSpec);
|
lastSs.setChain(nextSortSpec);
|
||||||
}
|
}
|
||||||
//TODO unused assignment
|
// TODO unused assignment
|
||||||
lastSs = nextSortSpec;
|
lastSs = nextSortSpec;
|
||||||
}
|
}
|
||||||
if (rootSs != null) {
|
if (rootSs != null) {
|
||||||
|
@ -1991,7 +2159,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated //override deprecated method
|
@Deprecated // override deprecated method
|
||||||
@Override
|
@Override
|
||||||
public IQuery limitTo(int theLimitTo) {
|
public IQuery limitTo(int theLimitTo) {
|
||||||
return count(theLimitTo);
|
return count(theLimitTo);
|
||||||
|
@ -2325,7 +2493,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPatchWithQueryTyped where(ICriterion<?> theCriterion) {
|
public IPatchWithQueryTyped where(ICriterion<?> theCriterion) {
|
||||||
myCriterionList.add((ICriterionInternal) theCriterion);
|
myCriterionList.add((ICriterionInternal) theCriterion);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.rest.gclient;
|
package ca.uhn.fhir.rest.gclient;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR - Core Library
|
* HAPI FHIR - Core Library
|
||||||
|
@ -19,9 +21,42 @@ package ca.uhn.fhir.rest.gclient;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface IOperation extends IBaseOn<IOperationUnnamed> {
|
public interface IOperation extends IBaseOn<IOperationUnnamed> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This operation is called <b><a href="https://www.hl7.org/fhir/messaging.html">$process-message</a></b> as defined by FHIR
|
||||||
|
* DSTU2.<br><br>
|
||||||
|
* Usage :<br>
|
||||||
|
* <code>
|
||||||
|
* <pre>
|
||||||
|
* Bundle response = client
|
||||||
|
* .operation()
|
||||||
|
* .onServer()
|
||||||
|
* .processMessage()
|
||||||
|
* .setResponseUrlParam("http://myserver/fhir")
|
||||||
|
* .setMessageBundle(msgBundle)
|
||||||
|
* .synchronous(Bundle.class)
|
||||||
|
* .execute();
|
||||||
|
*
|
||||||
|
* //if you want to send an async message
|
||||||
|
*
|
||||||
|
* OperationOutcome response = client
|
||||||
|
* .operation()
|
||||||
|
* .onServer()
|
||||||
|
* .processMessage()
|
||||||
|
* .setResponseUrlParam("http://myserver/fhir")
|
||||||
|
* .setMessageBundle(msgBundle)
|
||||||
|
* .asynchronous(OperationOutcome.class)
|
||||||
|
* .execute();
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* @see <a href="https://www.hl7.org/fhir/messaging.html">2.4 Messaging
|
||||||
|
* using FHIR Resources</a>
|
||||||
|
*
|
||||||
|
* @return An interface that defines the operation related to sending
|
||||||
|
* Messages to a Messaging Server
|
||||||
|
*/
|
||||||
|
IOperationProcessMsg processMessage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package ca.uhn.fhir.rest.gclient;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author HGS
|
||||||
|
*/
|
||||||
|
public interface IOperationProcessMsg{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Message Bundle to POST to the messaging server.<br>
|
||||||
|
* After this call you must choose either the method synchronous or asynchronous to set the processing mode.
|
||||||
|
*
|
||||||
|
* @param <R>
|
||||||
|
* @param theMsgBundle A Bundle of type message
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
<R extends IBaseResource> IOperationProcessMsgMode<R> setMessageBundle(IBaseBundle theMsgBundle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An optional query parameter indicating that responses from the receiving server should be sent to this url
|
||||||
|
*
|
||||||
|
* @param respondToUri The receiving endpoint to witch server response messages should be sent.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IOperationProcessMsg setResponseUrlParam(String respondToUri);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package ca.uhn.fhir.rest.gclient;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2017 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 IOperationProcessMsgMode<T extends IBaseResource> extends IClientExecutable<IOperationProcessMsgMode<T>, T> {
|
||||||
|
|
||||||
|
<R extends IBaseResource> IOperationProcessMsgMode<R> asynchronous(Class<R> theResponseClass);
|
||||||
|
|
||||||
|
<R extends IBaseResource> IOperationProcessMsgMode<R> synchronous(Class<R> theResponseClass);
|
||||||
|
}
|
|
@ -24,5 +24,4 @@ package ca.uhn.fhir.rest.gclient;
|
||||||
public interface IOperationUnnamed {
|
public interface IOperationUnnamed {
|
||||||
|
|
||||||
IOperationUntyped named(String theName);
|
IOperationUntyped named(String theName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.method;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -33,6 +33,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
@ -75,7 +76,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
private List<ReturnType> myReturnParams;
|
private List<ReturnType> myReturnParams;
|
||||||
private final ReturnTypeEnum myReturnType;
|
private final ReturnTypeEnum myReturnType;
|
||||||
|
|
||||||
protected OperationMethodBinding(Class<?> theReturnResourceType, Class<? extends IBaseResource> theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider, boolean theIdempotent, String theOperationName, Class<? extends IBaseResource> theOperationType,
|
protected OperationMethodBinding(Class<?> theReturnResourceType, Class<? extends IBaseResource> theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider,
|
||||||
|
boolean theIdempotent, String theOperationName, Class<? extends IBaseResource> theOperationType,
|
||||||
OperationParam[] theReturnParams, BundleTypeEnum theBundleType) {
|
OperationParam[] theReturnParams, BundleTypeEnum theBundleType) {
|
||||||
super(theReturnResourceType, theMethod, theContext, theProvider);
|
super(theReturnResourceType, theMethod, theContext, theProvider);
|
||||||
|
|
||||||
|
@ -104,7 +106,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBlank(theOperationName)) {
|
if (isBlank(theOperationName)) {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' on type " + theMethod.getDeclaringClass().getName() + " is annotated with @" + Operation.class.getSimpleName() + " but this annotation has no name defined");
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' on type " + theMethod.getDeclaringClass().getName() + " is annotated with @" + Operation.class.getSimpleName()
|
||||||
|
+ " but this annotation has no name defined");
|
||||||
}
|
}
|
||||||
if (theOperationName.startsWith("$") == false) {
|
if (theOperationName.startsWith("$") == false) {
|
||||||
theOperationName = "$" + theOperationName;
|
theOperationName = "$" + theOperationName;
|
||||||
|
@ -112,7 +115,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
myName = theOperationName;
|
myName = theOperationName;
|
||||||
|
|
||||||
if (theContext.getVersion().getVersion().isEquivalentTo(FhirVersionEnum.DSTU1)) {
|
if (theContext.getVersion().getVersion().isEquivalentTo(FhirVersionEnum.DSTU1)) {
|
||||||
throw new ConfigurationException("@" + Operation.class.getSimpleName() + " methods are not supported on servers for FHIR version " + theContext.getVersion().getVersion().name() + " - Found one on class " + theMethod.getDeclaringClass().getName());
|
throw new ConfigurationException("@" + Operation.class.getSimpleName() + " methods are not supported on servers for FHIR version " + theContext.getVersion().getVersion().name()
|
||||||
|
+ " - Found one on class " + theMethod.getDeclaringClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theReturnTypeFromRp != null) {
|
if (theReturnTypeFromRp != null) {
|
||||||
|
@ -126,7 +130,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theMethod.getReturnType().isAssignableFrom(Bundle.class)) {
|
if (theMethod.getReturnType().isAssignableFrom(Bundle.class)) {
|
||||||
throw new ConfigurationException("Can not return a DSTU1 bundle from an @" + Operation.class.getSimpleName() + " method. Found in method " + theMethod.getName() + " defined in type " + theMethod.getDeclaringClass().getName());
|
throw new ConfigurationException("Can not return a DSTU1 bundle from an @" + Operation.class.getSimpleName() + " method. Found in method " + theMethod.getName() + " defined in type "
|
||||||
|
+ theMethod.getDeclaringClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theMethod.getReturnType().equals(IBundleProvider.class)) {
|
if (theMethod.getReturnType().equals(IBundleProvider.class)) {
|
||||||
|
@ -172,8 +177,10 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationMethodBinding(Class<?> theReturnResourceType, Class<? extends IBaseResource> theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider, Operation theAnnotation) {
|
public OperationMethodBinding(Class<?> theReturnResourceType, Class<? extends IBaseResource> theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider,
|
||||||
this(theReturnResourceType, theReturnTypeFromRp, theMethod, theContext, theProvider, theAnnotation.idempotent(), theAnnotation.name(), theAnnotation.type(), theAnnotation.returnParameters(), theAnnotation.bundleType());
|
Operation theAnnotation) {
|
||||||
|
this(theReturnResourceType, theReturnTypeFromRp, theMethod, theContext, theProvider, theAnnotation.idempotent(), theAnnotation.name(), theAnnotation.type(), theAnnotation.returnParameters(),
|
||||||
|
theAnnotation.bundleType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
|
@ -321,7 +328,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
myDescription = theDescription;
|
myDescription = theDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseHttpClientInvocation createOperationInvocation(FhirContext theContext, String theResourceName, String theId, String theOperationName, IBaseParameters theInput, boolean theUseHttpGet) {
|
public static BaseHttpClientInvocation createOperationInvocation(FhirContext theContext, String theResourceName, String theId, String theOperationName, IBaseParameters theInput,
|
||||||
|
boolean theUseHttpGet) {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
if (theResourceName != null) {
|
if (theResourceName != null) {
|
||||||
b.append(theResourceName);
|
b.append(theResourceName);
|
||||||
|
@ -361,7 +369,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(value instanceof IPrimitiveType)) {
|
if (!(value instanceof IPrimitiveType)) {
|
||||||
throw new IllegalArgumentException("Can not invoke operation as HTTP GET when it has parameters with a composite (non priitive) datatype as the value. Found value: " + value.getClass().getName());
|
throw new IllegalArgumentException(
|
||||||
|
"Can not invoke operation as HTTP GET when it has parameters with a composite (non priitive) datatype as the value. Found value: " + value.getClass().getName());
|
||||||
}
|
}
|
||||||
IPrimitiveType<?> primitive = (IPrimitiveType<?>) value;
|
IPrimitiveType<?> primitive = (IPrimitiveType<?>) value;
|
||||||
params.get(nextName).add(primitive.getValueAsString());
|
params.get(nextName).add(primitive.getValueAsString());
|
||||||
|
@ -369,6 +378,23 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
return new HttpGetClientInvocation(theContext, params, b.toString());
|
return new HttpGetClientInvocation(theContext, params, b.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BaseHttpClientInvocation createProcessMsgInvocation(FhirContext theContext, String theOperationName, IBaseBundle theInput, Map<String, List<String>> urlParams) {
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
|
||||||
|
if (b.length() > 0) {
|
||||||
|
b.append('/');
|
||||||
|
}
|
||||||
|
if (!theOperationName.startsWith("$")) {
|
||||||
|
b.append("$");
|
||||||
|
}
|
||||||
|
b.append(theOperationName);
|
||||||
|
|
||||||
|
BaseHttpClientInvocation.appendExtraParamsWithQuestionMark(urlParams, b, b.indexOf("?") == -1);
|
||||||
|
|
||||||
|
return new HttpPostClientInvocation(theContext, theInput, b.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class ReturnType {
|
public static class ReturnType {
|
||||||
private int myMax;
|
private int myMax;
|
||||||
private int myMin;
|
private int myMin;
|
||||||
|
|
|
@ -146,6 +146,9 @@ public class Constants {
|
||||||
public static final String PARAM_TAGS = "_tags";
|
public static final String PARAM_TAGS = "_tags";
|
||||||
public static final String PARAM_TEXT = "_text";
|
public static final String PARAM_TEXT = "_text";
|
||||||
public static final String PARAM_VALIDATE = "_validate";
|
public static final String PARAM_VALIDATE = "_validate";
|
||||||
|
public static final String PARAM_ASYNC = "async"; //Used in messaging
|
||||||
|
public static final String PARAM_RESPONSE_URL = "response-url"; //Used in messaging
|
||||||
|
public static final String EXTOP_PROCESS_MESSAGE = "$process-message"; //Used in messaging
|
||||||
public static final String PARAMQUALIFIER_MISSING = ":missing";
|
public static final String PARAMQUALIFIER_MISSING = ":missing";
|
||||||
public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
|
public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
|
||||||
public static final String PARAMQUALIFIER_MISSING_TRUE = "true";
|
public static final String PARAMQUALIFIER_MISSING_TRUE = "true";
|
||||||
|
|
|
@ -190,7 +190,7 @@
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>${argLine} -Dfile.encoding=UTF-8 -Xmx712m</argLine>
|
<argLine>-Dfile.encoding=UTF-8 -Xmx712m</argLine>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
package ca.uhn.fhir.rest.client;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import org.apache.commons.io.input.ReaderInputStream;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.ProtocolVersion;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.message.BasicHeader;
|
||||||
|
import org.apache.http.message.BasicStatusLine;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.MessageHeader;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.ResponseTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
|
||||||
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class MessageClientDstu2Test {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MessageClientDstu2Test.class);
|
||||||
|
private FhirContext ourCtx;
|
||||||
|
private HttpClient myHttpClient;
|
||||||
|
|
||||||
|
private HttpResponse myHttpResponse;
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
ourCtx = FhirContext.forDstu2();
|
||||||
|
|
||||||
|
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||||
|
ourCtx.setRestfulClientFactory(new ApacheRestfulClientFactory(ourCtx));
|
||||||
|
ourCtx.getRestfulClientFactory().setConnectionRequestTimeout(10000);
|
||||||
|
ourCtx.getRestfulClientFactory().setConnectTimeout(10000);
|
||||||
|
ourCtx.getRestfulClientFactory().setPoolMaxPerRoute(100);
|
||||||
|
ourCtx.getRestfulClientFactory().setPoolMaxTotal(100);
|
||||||
|
|
||||||
|
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||||
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
|
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||||
|
|
||||||
|
System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendMessageAsync() throws Exception {
|
||||||
|
OperationOutcome oo = new OperationOutcome();
|
||||||
|
oo.addIssue().setDiagnostics("FOOBAR");
|
||||||
|
final String msg = ourCtx.newJsonParser().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_JSON + "; 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.getRestfulClientFactory().newGenericClient("http://192.168.4.93:83/fhirServer");
|
||||||
|
|
||||||
|
client.setEncoding(EncodingEnum.JSON);
|
||||||
|
|
||||||
|
// Create the input message to pass to the server
|
||||||
|
final Bundle msgBundle = getMessageBundle(
|
||||||
|
"myEvent", "Test Event",
|
||||||
|
"MySource", "http://myServer/fhir/", "MyDestination", "http://myDestinationServer/fhir/");
|
||||||
|
|
||||||
|
// Invoke $process-message
|
||||||
|
OperationOutcome response = client
|
||||||
|
.operation()
|
||||||
|
.processMessage()
|
||||||
|
.setResponseUrlParam("http://myserver/fhir")
|
||||||
|
.setMessageBundle(msgBundle)
|
||||||
|
.asynchronous(OperationOutcome.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
//System.out.println(response);
|
||||||
|
assertEquals("http://192.168.4.93:83/fhirServer/$process-message?async=true&response-url=http%3A%2F%2Fmyserver%2Ffhir&_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
|
assertEquals("POST", capt.getAllValues().get(0).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, 0));
|
||||||
|
//assertNotNull(response.getOperationOutcome());
|
||||||
|
assertEquals("FOOBAR", ((OperationOutcome) response).getIssueFirstRep().getDiagnosticsElement().getValue());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendMessage() throws Exception {
|
||||||
|
final Bundle msgBundleResponse = getMessageBundle(
|
||||||
|
"myEvent", "Test Event",
|
||||||
|
"MySource", "http://myServer/fhir/", "MyDestination", "http://myDestinationServer/fhir/");
|
||||||
|
((MessageHeader) msgBundleResponse.getEntryFirstRep().getResource()).getResponse().setCode(ResponseTypeEnum.OK);
|
||||||
|
final String msg = ourCtx.newJsonParser().encodeResourceToString(msgBundleResponse);
|
||||||
|
|
||||||
|
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<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||||
|
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.getRestfulClientFactory().newGenericClient("http://192.168.4.93:83/fhirServer");
|
||||||
|
|
||||||
|
client.setEncoding(EncodingEnum.JSON);
|
||||||
|
|
||||||
|
// Create the input message to pass to the server
|
||||||
|
final Bundle msgBundle = getMessageBundle(
|
||||||
|
"myEvent", "Test Event",
|
||||||
|
"MySource", "http://myServer/fhir/", "MyDestination", "http://myDestinationServer/fhir/");
|
||||||
|
|
||||||
|
// Invoke $process-message
|
||||||
|
Bundle response = client
|
||||||
|
.operation()
|
||||||
|
.processMessage()
|
||||||
|
.setMessageBundle(msgBundle)
|
||||||
|
.synchronous(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
//System.out.println(response);
|
||||||
|
assertEquals("http://192.168.4.93:83/fhirServer/$process-message?async=false&_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
|
assertEquals("POST", capt.getAllValues().get(0).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, 0));
|
||||||
|
//assertNotNull(response.getOperationOutcome());
|
||||||
|
assertEquals("MessageHeader", ((Bundle) response).getEntryFirstRep().getResource().getResourceName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Criar um FHIR Message Bundle pre-preenchido com os parametros
|
||||||
|
*
|
||||||
|
* @param eventCode
|
||||||
|
* @param eventDisplay
|
||||||
|
* @param sourceName
|
||||||
|
* @param sourceEnpoint
|
||||||
|
* @param destinationName
|
||||||
|
* @param destinationEndpoint
|
||||||
|
* @return Message Bundle
|
||||||
|
*/
|
||||||
|
public static Bundle getMessageBundle(String eventCode, String eventDisplay, String sourceName, String sourceEnpoint, String destinationName, String destinationEndpoint) {
|
||||||
|
/*
|
||||||
|
Init Bundle
|
||||||
|
*/
|
||||||
|
Bundle msgBundle = new Bundle();
|
||||||
|
msgBundle.getMeta().setLastUpdated(new Date());
|
||||||
|
msgBundle.setType(BundleTypeEnum.MESSAGE); //Document Type
|
||||||
|
msgBundle.setId(UUID.randomUUID().toString()); // Random ID
|
||||||
|
/*
|
||||||
|
Init MessageHeader
|
||||||
|
*/
|
||||||
|
MessageHeader msh = new MessageHeader();
|
||||||
|
msh.setId(UUID.randomUUID().toString());
|
||||||
|
msh.setTimestampWithMillisPrecision(new Date());
|
||||||
|
msh.getEvent().setSystem("http://mybServer/fhir/events");
|
||||||
|
msh.getEvent().setCode(eventCode);
|
||||||
|
msh.getEvent().setDisplay(eventDisplay);
|
||||||
|
msh.getSource().setName(sourceName);
|
||||||
|
msh.getSource().setEndpoint(sourceEnpoint);
|
||||||
|
msh.getDestinationFirstRep().setName(destinationName);
|
||||||
|
msh.getDestinationFirstRep().setEndpoint(destinationEndpoint);
|
||||||
|
Bundle.Entry entry = new Bundle.Entry();
|
||||||
|
entry.setFullUrl("http://mybase/fhirServer/Bundle/" + msh.getId().getValue());
|
||||||
|
entry.setResource(msh);
|
||||||
|
msgBundle.addEntry(entry);
|
||||||
|
return msgBundle;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue