client changes

This commit is contained in:
leif stawnyczy 2024-07-30 13:50:31 -04:00
parent 8d1529276b
commit baf3933fbf
13 changed files with 905 additions and 78 deletions

View File

@ -42,21 +42,32 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
public interface IGenericClient extends IRestfulClient {
public enum ClientType {
PRESERVED,
DEPRECATED
}
/**
* Fetch the capability statement for the server
*/
IFetchConformanceUntyped capabilities();
IFetchConformanceUntyped capabilities(ClientType theClientType);
/**
* Fluent method for the "create" operation, which creates a new resource instance on the server
*/
ICreate create();
ICreate create(ClientType theClientType);
/**
* Fluent method for the "delete" operation, which performs a logical delete on a server resource
*/
IDelete delete();
IDelete delete(ClientType theClientType);
/**
* Retrieves the server's conformance statement
*
@ -64,6 +75,8 @@ public interface IGenericClient extends IRestfulClient {
*/
IFetchConformanceUntyped fetchConformance();
IFetchConformanceUntyped fetchConformance(ClientType theClientType);
/**
* Force the client to fetch the server's conformance statement and validate that it is appropriate for this client.
*
@ -79,6 +92,8 @@ public interface IGenericClient extends IRestfulClient {
*/
IHistory history();
IHistory history(ClientType theClientType);
/**
* Loads the previous/next bundle of resources from a paged set, using the link specified in the "link type=next" tag within the atom bundle.
*/
@ -92,21 +107,29 @@ public interface IGenericClient extends IRestfulClient {
*/
IMeta meta();
IMeta meta(ClientType theClientType);
/**
* Implementation of the FHIR "extended operations" action
*/
IOperation operation();
IOperation operation(ClientType theClientType);
/**
* Fluent method for the "patch" operation, which performs a logical patch on a server resource
*/
IPatch patch();
IPatch patch(ClientType theClientType);
/**
* Fluent method for "read" and "vread" methods.
*/
IRead read();
IRead read(ClientType theClientType);
/**
* Implementation of the "instance read" method.
*
@ -159,6 +182,8 @@ public interface IGenericClient extends IRestfulClient {
*/
<T extends IBaseBundle> IUntypedQuery<T> search();
<T extends IBaseBundle> IUntypedQuery<T> search(ClientType theClientType);
/**
* If set to <code>true</code>, the client will log all requests and all responses. This is probably not a good production setting since it will result in a lot of extra logging, but it can be
* useful for troubleshooting.
@ -177,6 +202,8 @@ public interface IGenericClient extends IRestfulClient {
*/
ITransaction transaction();
ITransaction transaction(ClientType theClientType);
/**
* Remove an intercaptor that was previously registered using {@link IRestfulClient#registerInterceptor(Object)}
*/
@ -188,6 +215,8 @@ public interface IGenericClient extends IRestfulClient {
*/
IUpdate update();
IUpdate update(ClientType theClientType);
/**
* Implementation of the "instance update" method.
*
@ -219,6 +248,8 @@ public interface IGenericClient extends IRestfulClient {
*/
IValidate validate();
IValidate validate(ClientType theClientType);
/**
* Implementation of the "type validate" method.
*

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.client.api;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.param.HttpClientRequestParameters;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import java.util.List;
@ -66,5 +67,8 @@ public interface IHttpClient {
* @param theEncoding the request encoding
* @return the http request to be executed
*/
@Deprecated
IHttpRequest createGetRequest(FhirContext theContext, EncodingEnum theEncoding);
IHttpRequest createRequest(HttpClientRequestParameters theParameters);
}

View File

@ -0,0 +1,125 @@
package ca.uhn.fhir.rest.param;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import jakarta.annotation.Nonnull;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import java.util.List;
import java.util.Map;
public class HttpClientRequestParameters {
private FhirContext myFhirContext;
private EncodingEnum myEncodingEnum;
private RequestTypeEnum myRequestTypeEnum;
private Map<String, List<String>> myParams;
private String myContentType;
private String myContents;
private IBaseBinary myBaseBinary;
private String myUrl;
// only for non-get requests
private String myStringContents;
private byte[] myByteContents;
private Map<String, List<String>> myFormParams;
public HttpClientRequestParameters(String theUrl, @Nonnull RequestTypeEnum theRequestTypeEnum) {
myUrl = theUrl;
myRequestTypeEnum = theRequestTypeEnum;
}
public FhirContext getFhirContext() {
return myFhirContext;
}
public void setFhirContext(FhirContext theFhirContext) {
myFhirContext = theFhirContext;
}
public EncodingEnum getEncodingEnum() {
return myEncodingEnum;
}
public void setEncodingEnum(EncodingEnum theEncodingEnum) {
myEncodingEnum = theEncodingEnum;
}
public RequestTypeEnum getRequestTypeEnum() {
return myRequestTypeEnum;
}
public void setRequestTypeEnum(RequestTypeEnum theRequestTypeEnum) {
myRequestTypeEnum = theRequestTypeEnum;
}
public Map<String, List<String>> getParams() {
return myParams;
}
public void setParams(Map<String, List<String>> theParams) {
myParams = theParams;
}
public String getContentType() {
return myContentType;
}
public void setContentType(String theContentType) {
myContentType = theContentType;
}
public String getContents() {
return myContents;
}
public void setContents(String theContents) {
myContents = theContents;
}
public IBaseBinary getBaseBinary() {
return myBaseBinary;
}
public void setBaseBinary(IBaseBinary theBaseBinary) {
myBaseBinary = theBaseBinary;
}
public String getUrl() {
return myUrl;
}
public String getStringContents() {
return myStringContents;
}
public void setStringContents(String theStringContents) {
myStringContents = theStringContents;
}
public byte[] getByteContents() {
return myByteContents;
}
public void setByteContents(byte[] theByteContents) {
myByteContents = theByteContents;
}
public Map<String, List<String>> getFormParams() {
return myFormParams;
}
public void setFormParams(Map<String, List<String>> theFormParams) {
myFormParams = theFormParams;
}
}

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.api.Header;
import ca.uhn.fhir.rest.client.api.IHttpClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.param.HttpClientRequestParameters;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
@ -46,6 +47,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* A Http Client based on Apache. This is an adapter around the class
* {@link org.apache.http.client.HttpClient HttpClient}
@ -67,9 +70,27 @@ public class ApacheHttpClient extends BaseHttpClient implements IHttpClient {
this.myClient = theClient;
}
private HttpRequestBase constructRequestBase(HttpEntity theEntity) {
String url = myUrl.toString();
switch (myRequestType) {
private HttpEntity getEntityFromParameters(HttpClientRequestParameters theParameters) {
if (isNotBlank(theParameters.getContents())) {
return new ByteArrayEntity(theParameters.getContents().getBytes(Constants.CHARSET_UTF8));
} else if (theParameters.getByteContents() != null) {
return new ByteArrayEntity(theParameters.getByteContents());
} else if (theParameters.getFormParams() != null
&& !theParameters.getFormParams().isEmpty()) {
return entityFromFormParams(theParameters.getFormParams());
}
// could be a get request
return null;
}
private HttpRequestBase constructRequestBase(HttpClientRequestParameters theParameters, HttpEntity theEntity) {
RequestTypeEnum requestTypeEnum = theParameters.getRequestTypeEnum();
if (requestTypeEnum == null) {
requestTypeEnum = myRequestType;
}
assert requestTypeEnum != null : "Request type required";
String url = theParameters.getUrl();
switch (requestTypeEnum) {
case DELETE:
return new HttpDelete(url);
case PATCH:
@ -92,6 +113,11 @@ public class ApacheHttpClient extends BaseHttpClient implements IHttpClient {
}
}
private HttpRequestBase constructRequestBase(HttpEntity theEntity) {
HttpClientRequestParameters parameters = new HttpClientRequestParameters(myUrl.toString(), myRequestType);
return constructRequestBase(parameters, theEntity);
}
private UrlEncodedFormEntity createFormEntity(List<NameValuePair> parameters) {
try {
return new UrlEncodedFormEntity(parameters, "UTF-8");
@ -100,6 +126,18 @@ public class ApacheHttpClient extends BaseHttpClient implements IHttpClient {
}
}
@Override
public IHttpRequest createRequest(HttpClientRequestParameters theParameters) {
HttpRequestBase request = constructRequestBase(theParameters, getEntityFromParameters(theParameters));
return new ApacheHttpRequest(myClient, request);
}
// @Override
// public IHttpRequest createHttpRequest(CreateHttpRequestParameters theCreateHttpRequestParameters) {
// HttpRequestBase request = constructRequestBase(theCreateHttpRequestParameters);
// return new ApacheHttpRequest(myClient, request);
// }
@Override
protected IHttpRequest createHttpRequest() {
return createHttpRequest((HttpEntity) null);
@ -123,6 +161,11 @@ public class ApacheHttpClient extends BaseHttpClient implements IHttpClient {
@Override
protected IHttpRequest createHttpRequest(Map<String, List<String>> theParams) {
UrlEncodedFormEntity entity = entityFromFormParams(theParams);
return createHttpRequest(entity);
}
private UrlEncodedFormEntity entityFromFormParams(Map<String, List<String>> theParams) {
List<NameValuePair> parameters = new ArrayList<>();
for (Entry<String, List<String>> nextParam : theParams.entrySet()) {
List<String> value = nextParam.getValue();
@ -132,7 +175,7 @@ public class ApacheHttpClient extends BaseHttpClient implements IHttpClient {
}
UrlEncodedFormEntity entity = createFormEntity(parameters);
return createHttpRequest(entity);
return entity;
}
@Override

View File

@ -29,6 +29,7 @@ import ca.uhn.fhir.rest.client.api.IHttpClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.client.method.MethodUtil;
import ca.uhn.fhir.rest.param.HttpClientRequestParameters;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import java.util.List;
@ -39,7 +40,7 @@ public abstract class BaseHttpClient implements IHttpClient {
private final List<Header> myHeaders;
private final Map<String, List<String>> myIfNoneExistParams;
private final String myIfNoneExistString;
protected final RequestTypeEnum myRequestType;
protected RequestTypeEnum myRequestType;
protected final StringBuilder myUrl;
/**
@ -108,11 +109,19 @@ public abstract class BaseHttpClient implements IHttpClient {
@Override
public IHttpRequest createGetRequest(FhirContext theContext, EncodingEnum theEncoding) {
IHttpRequest retVal = createHttpRequest();
IHttpRequest retVal = createRequest(new HttpClientRequestParameters(myUrl.toString(), RequestTypeEnum.GET));
addHeadersToRequest(retVal, theEncoding, theContext);
return retVal;
}
// @Override
// public IHttpRequest createRequest(HttpClientRequestParameters theParameters) {
//
// }
// protected abstract IHttpRequest createHttpRequest(CreateHttpRequestParameters theCreateHttpRequestParameters);
@Deprecated
protected abstract IHttpRequest createHttpRequest();
protected abstract IHttpRequest createHttpRequest(byte[] theContent);

View File

@ -51,6 +51,8 @@ import ca.uhn.fhir.rest.client.method.HttpGetClientInvocation;
import ca.uhn.fhir.rest.client.method.IClientResponseHandler;
import ca.uhn.fhir.rest.client.method.IClientResponseHandlerHandlesBinary;
import ca.uhn.fhir.rest.client.method.MethodUtil;
import ca.uhn.fhir.rest.client.model.AsHttpRequestParams;
import ca.uhn.fhir.rest.client.model.InvokeClientParameters;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.system.HapiSystemProperties;
@ -88,7 +90,7 @@ public abstract class BaseClient implements IRestfulClient {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseClient.class);
private final IHttpClient myClient;
protected IHttpClient myClient;
private final RestfulClientFactory myFactory;
private final String myUrlBase;
private boolean myDontValidateConformance;
@ -267,6 +269,32 @@ public abstract class BaseClient implements IRestfulClient {
CacheControlDirective theCacheControlDirective,
String theCustomAcceptHeader,
Map<String, List<String>> theCustomHeaders) {
return this.invokeClient(new InvokeClientParameters<T>()
.setContext(theContext)
.setBinding(binding)
.setClientInvocation(clientInvocation)
.setEncoding(theEncoding)
.setPrettyPrint(thePrettyPrint)
.setTheLogRequestAndResponse(theLogRequestAndResponse)
.setSummaryMode(theSummaryMode)
.setSubsetElements(theSubsetElements)
.setCacheControlDirective(theCacheControlDirective)
.setCustomAcceptHeader(theCustomAcceptHeader)
.setCustomHeaders(theCustomHeaders));
}
protected <T> T invokeClient(InvokeClientParameters<T> theParameters) {
FhirContext theContext = theParameters.getContext();
IClientResponseHandler<T> binding = theParameters.getBinding();
BaseHttpClientInvocation clientInvocation = theParameters.getClientInvocation();
EncodingEnum theEncoding = theParameters.getEncoding();
Boolean thePrettyPrint = theParameters.getPrettyPrint();
boolean theLogRequestAndResponse = theParameters.isTheLogRequestAndResponse();
SummaryEnum theSummaryMode = theParameters.getSummaryMode();
Set<String> theSubsetElements = theParameters.getSubsetElements();
CacheControlDirective theCacheControlDirective = theParameters.getCacheControlDirective();
String theCustomAcceptHeader = theParameters.getCustomAcceptHeader();
Map<String, List<String>> theCustomHeaders = theParameters.getCustomHeaders();
if (!myDontValidateConformance) {
myFactory.validateServerBaseIfConfiguredToDoSo(myUrlBase, myClient, this);
@ -299,7 +327,7 @@ public abstract class BaseClient implements IRestfulClient {
params.put(Constants.PARAM_PRETTY, Collections.singletonList(Constants.PARAM_PRETTY_VALUE_TRUE));
}
if (theSubsetElements != null && theSubsetElements.isEmpty() == false) {
if (theSubsetElements != null && !theSubsetElements.isEmpty()) {
params.put(
Constants.PARAM_ELEMENTS, Collections.singletonList(StringUtils.join(theSubsetElements, ',')));
}
@ -309,8 +337,15 @@ public abstract class BaseClient implements IRestfulClient {
encoding = theEncoding;
}
httpRequest = clientInvocation.asHttpRequest(myUrlBase, params, encoding, thePrettyPrint);
AsHttpRequestParams asHttpRequestParams = new AsHttpRequestParams()
.setExtraParams(params)
.setUrlBase(myUrlBase)
.setPrettyPrint(thePrettyPrint)
.setEncodingEnum(encoding)
.setClient(myClient);
httpRequest = clientInvocation.asHttpRequest(asHttpRequestParams);
// httpRequest = clientInvocation.asHttpRequest(myUrlBase, params, encoding, thePrettyPrint);
//
if (isNotBlank(theCustomAcceptHeader)) {
httpRequest.removeHeaders(Constants.HEADER_ACCEPT);
httpRequest.addHeader(Constants.HEADER_ACCEPT, theCustomAcceptHeader);

View File

@ -26,6 +26,9 @@ import ca.uhn.fhir.rest.client.api.Header;
import ca.uhn.fhir.rest.client.api.IHttpClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
import ca.uhn.fhir.rest.client.model.AsHttpRequestParams;
import ca.uhn.fhir.rest.client.model.CreateRequestParameters;
import ca.uhn.fhir.rest.param.HttpClientRequestParameters;
import ca.uhn.fhir.util.UrlUtil;
import java.util.ArrayList;
@ -58,27 +61,55 @@ public abstract class BaseHttpClientInvocation {
* The encoding to use for any serialized content sent to the
* server
*/
@Deprecated
public abstract IHttpRequest asHttpRequest(
String theUrlBase,
Map<String, List<String>> theExtraParams,
EncodingEnum theEncoding,
Boolean thePrettyPrint);
// TODO implement
public IHttpRequest asHttpRequest(AsHttpRequestParams theParams) {
return asHttpRequest(
theParams.getUrlBase(),
theParams.getExtraParams(),
theParams.getEncodingEnum(),
theParams.getPrettyPrint());
}
/**
* Use {@link #createHttpRequest(CreateRequestParameters)}
*/
@Deprecated
protected IHttpRequest createHttpRequest(String theUrl, EncodingEnum theEncoding, RequestTypeEnum theRequestType) {
return createHttpRequest(new CreateRequestParameters()
.setUrl(theUrl)
.setEncodingEnum(theEncoding)
.setRequestTypeEnum(theRequestType));
}
/**
* Create an HTTP request for the given url, encoding and request-type
*
* @param theUrl
* The complete FHIR url to which the http request will be sent
* @param theEncoding
* The encoding to use for any serialized content sent to the
* server
* @param theRequestType
* the type of HTTP request (GET, DELETE, ..)
*/
protected IHttpRequest createHttpRequest(String theUrl, EncodingEnum theEncoding, RequestTypeEnum theRequestType) {
IHttpClient httpClient = getRestfulClientFactory()
.getHttpClient(new StringBuilder(theUrl), null, null, theRequestType, myHeaders);
return httpClient.createGetRequest(getContext(), theEncoding);
protected IHttpRequest createHttpRequest(CreateRequestParameters theParameters) {
IHttpClient httpClient;
if (theParameters.getClient() != null) {
httpClient = theParameters.getClient();
} else {
httpClient = getRestfulClientFactory()
.getHttpClient(
new StringBuilder(theParameters.getUrl()),
null,
null,
theParameters.getRequestTypeEnum(),
myHeaders);
}
// todo
HttpClientRequestParameters clientRequestParameters =
new HttpClientRequestParameters(theParameters.getUrl(), RequestTypeEnum.GET);
clientRequestParameters.setEncodingEnum(theParameters.getEncodingEnum());
return httpClient.createRequest(clientRequestParameters);
// return httpClient.createGetRequest(getContext(), theParameters.getEncodingEnum());
}
/**

View File

@ -69,6 +69,8 @@ import ca.uhn.fhir.rest.client.method.SearchMethodBinding;
import ca.uhn.fhir.rest.client.method.SortParameter;
import ca.uhn.fhir.rest.client.method.TransactionMethodBinding;
import ca.uhn.fhir.rest.client.method.ValidateMethodBindingDstu2Plus;
import ca.uhn.fhir.rest.client.model.AsHttpRequestParams;
import ca.uhn.fhir.rest.client.model.InvokeClientParameters;
import ca.uhn.fhir.rest.gclient.IBaseQuery;
import ca.uhn.fhir.rest.gclient.IClientExecutable;
import ca.uhn.fhir.rest.gclient.ICreate;
@ -179,7 +181,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
private static final String I18N_INCOMPLETE_URI_FOR_READ = GenericClient.class.getName() + ".incompleteUriForRead";
private static final String I18N_NO_VERSION_ID_FOR_VREAD = GenericClient.class.getName() + ".noVersionIdForVread";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClient.class);
private FhirContext myContext;
private final FhirContext myContext;
private IHttpRequest myLastRequest;
private boolean myLogRequestAndResponse;
@ -194,17 +196,41 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IFetchConformanceUntyped capabilities() {
return new FetchConformanceInternal();
return capabilities(ClientType.DEPRECATED);
}
@Override
public IFetchConformanceUntyped capabilities(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new FetchConformanceInternal(myClient);
}
return new FetchConformanceInternal(null);
}
@Override
public ICreate create() {
return new CreateInternal();
return create(ClientType.DEPRECATED);
}
@Override
public ICreate create(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new CreateInternal(myClient);
}
return new CreateInternal(null);
}
@Override
public IDelete delete() {
return new DeleteInternal();
return delete(ClientType.DEPRECATED);
}
@Override
public IDelete delete(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new DeleteInternal(myClient);
}
return new DeleteInternal(null);
}
private <T extends IBaseResource> T doReadOrVRead(
@ -240,8 +266,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
}
if (isKeepResponses()) {
myLastRequest = invocation.asHttpRequest(
getServerBase(), createExtraParams(theCustomAcceptHeaderValue), getEncoding(), isPrettyPrint());
AsHttpRequestParams params = new AsHttpRequestParams()
.setExtraParams(createExtraParams(theCustomAcceptHeaderValue))
.setUrlBase(getServerBase())
.setClient(myClient)
.setEncodingEnum(getEncoding())
.setPrettyPrint(isPrettyPrint());
// myLastRequest = invocation.asHttpRequest(
// getServerBase(), createExtraParams(theCustomAcceptHeaderValue), getEncoding(), isPrettyPrint());
myLastRequest = invocation.asHttpRequest(params);
}
if (theIfVersionMatches != null) {
@ -253,18 +286,29 @@ public class GenericClient extends BaseClient implements IGenericClient {
new ResourceResponseHandler<>(theType, (Class<? extends IBaseResource>) null, id, allowHtmlResponse);
if (theNotModifiedHandler == null) {
return invokeClient(
myContext,
binding,
invocation,
theEncoding,
thePrettyPrint,
myLogRequestAndResponse,
theSummary,
theSubsetElements,
null,
theCustomAcceptHeaderValue,
theCustomHeaders);
// return invokeClient(
// myContext,
// binding,
// invocation,
// theEncoding,
// thePrettyPrint,
// myLogRequestAndResponse,
// theSummary,
// theSubsetElements,
// null,
// theCustomAcceptHeaderValue,
// theCustomHeaders);
return invokeClient(new InvokeClientParameters<T>()
.setContext(myContext)
.setBinding(binding)
.setClientInvocation(invocation)
.setEncoding(theEncoding)
.setPrettyPrint(thePrettyPrint)
.setTheLogRequestAndResponse(myLogRequestAndResponse)
.setSummaryMode(theSummary)
.setSubsetElements(theSubsetElements)
.setCustomAcceptHeader(theCustomAcceptHeaderValue)
.setCustomHeaders(theCustomHeaders));
}
try {
return invokeClient(
@ -286,7 +330,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IFetchConformanceUntyped fetchConformance() {
return new FetchConformanceInternal();
return fetchConformance(ClientType.DEPRECATED);
}
@Override
public IFetchConformanceUntyped fetchConformance(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new FetchConformanceInternal(myClient);
}
return new FetchConformanceInternal(null);
}
@Override
@ -319,7 +371,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IHistory history() {
return new HistoryInternal();
return history(ClientType.DEPRECATED);
}
@Override
public IHistory history(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new HistoryInternal(myClient);
}
return new HistoryInternal(null);
}
/**
@ -345,22 +405,55 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IMeta meta() {
return new MetaInternal();
return meta(ClientType.DEPRECATED);
}
@Override
public IMeta meta(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new MetaInternal(myClient);
}
return new MetaInternal(null);
}
@Override
public IOperation operation() {
return new OperationInternal();
return operation(ClientType.DEPRECATED);
}
@Override
public IOperation operation(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new OperationInternal(myClient);
}
return new OperationInternal(null);
}
@Override
public IPatch patch() {
return new PatchInternal();
return patch(ClientType.DEPRECATED);
}
@Override
public IPatch patch(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED && myClient != null) {
return new PatchInternal(myClient);
}
return new PatchInternal(null);
}
@Override
public IRead read() {
return new ReadInternal();
return read(ClientType.DEPRECATED);
}
@Override
public IRead read(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED && myClient != null) {
return new ReadInternal(myClient);
}
// deprecated
return new ReadInternal(null);
}
@Override
@ -392,10 +485,19 @@ public class GenericClient extends BaseClient implements IGenericClient {
return read(def.getImplementingClass(), id);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public IUntypedQuery search(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new SearchInternal<>(myClient);
}
return new SearchInternal<>(null);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public IUntypedQuery search() {
return new SearchInternal();
return search(ClientType.DEPRECATED);
}
private String toResourceName(Class<? extends IBaseResource> theType) {
@ -404,12 +506,28 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public ITransaction transaction() {
return new TransactionInternal();
return transaction(ClientType.DEPRECATED);
}
@Override
public ITransaction transaction(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new TransactionInternal(myClient);
}
return new TransactionInternal(null);
}
@Override
public IUpdate update() {
return new UpdateInternal();
return update(ClientType.DEPRECATED);
}
@Override
public IUpdate update(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new UpdateInternal(myClient);
}
return new UpdateInternal(null);
}
@Override
@ -432,7 +550,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IValidate validate() {
return new ValidateInternal();
return validate(ClientType.DEPRECATED);
}
@Override
public IValidate validate(ClientType theClientType) {
if (theClientType == ClientType.PRESERVED) {
return new ValidateInternal(myClient);
}
return new ValidateInternal(null);
}
@Override
@ -484,6 +610,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
private boolean myQueryLogRequestAndResponse;
private Set<String> mySubsetElements;
private final IHttpClient myPreservedClient;
public BaseClientExecutable(IHttpClient theClient) {
myPreservedClient = theClient;
}
public String getCustomAcceptHeaderValue() {
return myCustomAcceptHeaderValue;
}
@ -582,18 +714,19 @@ public class GenericClient extends BaseClient implements IGenericClient {
myLastRequest = theInvocation.asHttpRequest(getServerBase(), theParams, getEncoding(), myPrettyPrint);
}
Z resp = invokeClient(
myContext,
theHandler,
theInvocation,
myParamEncoding,
myPrettyPrint,
myQueryLogRequestAndResponse || myLogRequestAndResponse,
mySummaryMode,
mySubsetElements,
myCacheControlDirective,
myCustomAcceptHeaderValue,
myCustomHeaderValues);
InvokeClientParameters<Z> params = new InvokeClientParameters<Z>()
.setContext(myContext)
.setBinding(theHandler)
.setClientInvocation(theInvocation)
.setEncoding(myParamEncoding)
.setPrettyPrint(myPrettyPrint)
.setTheLogRequestAndResponse(myQueryLogRequestAndResponse || myLogRequestAndResponse)
.setSummaryMode(mySummaryMode)
.setSubsetElements(mySubsetElements)
.setCacheControlDirective(myCacheControlDirective)
.setCustomAcceptHeader(myCustomAcceptHeaderValue)
.setCustomHeaders(myCustomHeaderValues);
Z resp = invokeClient(params);
return resp;
}
@ -643,7 +776,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
EXEC extends IClientExecutable<?, OUTPUT>, QUERY extends IBaseQuery<QUERY>, OUTPUT>
extends BaseClientExecutable<EXEC, OUTPUT> implements IBaseQuery<QUERY> {
private Map<String, List<String>> myParams = new LinkedHashMap<>();
private final Map<String, List<String>> myParams = new LinkedHashMap<>();
public BaseSearch(IHttpClient theClient) {
super(theClient);
}
@Override
public QUERY and(ICriterion<?> theCriterion) {
@ -710,6 +847,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private String myResourceBody;
private String mySearchUrl;
public CreateInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public ICreateWithQuery conditional() {
myConditional = true;
@ -780,6 +921,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private String mySearchUrl;
private DeleteCascadeModeEnum myCascadeMode;
public DeleteInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public MethodOutcome execute() {
@ -888,6 +1033,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
implements IFetchConformanceUntyped, IFetchConformanceTyped {
private RuntimeResourceDefinition myType;
public FetchConformanceInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public Object execute() {
ResourceResponseHandler binding = new ResourceResponseHandler(myType.getImplementingClass());
@ -918,6 +1067,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
private PagingHttpMethodEnum myPagingHttpMethod = PagingHttpMethodEnum.GET;
public GetPageInternal(String theUrl, Class<? extends IBaseBundle> theBundleType) {
super(null);
myUrl = theUrl;
myBundleType = theBundleType;
}
@ -947,6 +1097,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private Class<? extends IBaseResource> myType;
private DateRangeParam myAt;
public HistoryInternal(IHttpClient theClient) {
super(theClient);
}
@SuppressWarnings("unchecked")
@Override
public IHistoryTyped andReturnBundle(Class theType) {
@ -1129,6 +1283,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private String myOnType;
private MetaOperation myOperation;
public MetaInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public IMetaAddOrDeleteUnsourced add() {
myOperation = MetaOperation.ADD;
@ -1303,6 +1461,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private boolean myUseHttpGet;
private boolean myReturnMethodOutcome;
public OperationInternal(IHttpClient theClient) {
super(theClient);
}
@SuppressWarnings("unchecked")
private void addParam(String theName, IBase theValue) {
BaseRuntimeChildDefinition parameterChild = myParametersDef.getChildByName("parameter");
@ -1716,6 +1878,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private class PatchInternal extends BaseSearch<IPatchExecutable, IPatchWithQueryTyped, MethodOutcome>
implements IPatch, IPatchWithBody, IPatchExecutable, IPatchWithQuery, IPatchWithQueryTyped {
public PatchInternal(IHttpClient theClient) {
super(theClient);
}
private boolean myConditional;
private IIdType myId;
private String myPatchBody;
@ -1845,6 +2011,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private ICallable myNotModifiedHandler;
private RuntimeResourceDefinition myType;
public ReadInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public Object execute() { // AAA
if (myId.hasVersionIdPart()) {
@ -2038,7 +2208,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
private List<TokenParam> myTags = new ArrayList<>();
private SearchTotalModeEnum myTotalMode;
public SearchInternal() {
public SearchInternal(IHttpClient theClient) {
super(theClient);
myResourceType = null;
myResourceName = null;
mySearchUrl = null;
@ -2348,20 +2519,37 @@ public class GenericClient extends BaseClient implements IGenericClient {
private EncodingEnum myRawBundleEncoding;
private List<? extends IBaseResource> myResources;
public TransactionExecutable(IBaseBundle theBundle) {
myBaseBundle = theBundle;
public TransactionExecutable(IHttpClient theClient, IBaseBundle theBundle) {
this(theClient, null, theBundle, null);
}
public TransactionExecutable(List<? extends IBaseResource> theResources) {
myResources = theResources;
public TransactionExecutable(IHttpClient theClient, List<? extends IBaseResource> theResources) {
this(theClient, null, null, theResources);
}
public TransactionExecutable(String theBundle) {
myRawBundle = theBundle;
myRawBundleEncoding = EncodingEnum.detectEncodingNoDefault(myRawBundle);
if (myRawBundleEncoding == null) {
throw new IllegalArgumentException(Msg.code(1395)
+ myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType"));
public TransactionExecutable(IHttpClient theClient, String theStrBundle) {
this(theClient, theStrBundle, null, null);
}
public TransactionExecutable(
IHttpClient theClient,
String theStrBundle,
IBaseBundle theBundle,
List<? extends IBaseResource> theResources) {
super(theClient);
if (theBundle != null) {
myBaseBundle = theBundle;
}
if (theStrBundle != null) {
myRawBundle = theStrBundle;
myRawBundleEncoding = EncodingEnum.detectEncodingNoDefault(myRawBundle);
if (myRawBundleEncoding == null) {
throw new IllegalArgumentException(Msg.code(1395)
+ myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType"));
}
}
if (theResources != null) {
myResources = theResources;
}
}
@ -2402,16 +2590,22 @@ public class GenericClient extends BaseClient implements IGenericClient {
private final class TransactionInternal implements ITransaction {
private IHttpClient myClient;
public TransactionInternal(IHttpClient theClient) {
myClient = theClient;
}
@Override
public ITransactionTyped<String> withBundle(String theBundle) {
Validate.notBlank(theBundle, "theBundle must not be null");
return new TransactionExecutable<String>(theBundle);
return new TransactionExecutable<String>(myClient, theBundle);
}
@Override
public <T extends IBaseBundle> ITransactionTyped<T> withBundle(T theBundle) {
Validate.notNull(theBundle, "theBundle must not be null");
return new TransactionExecutable<T>(theBundle);
return new TransactionExecutable<T>(myClient, theBundle);
}
@Override
@ -2432,7 +2626,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
}
return new TransactionExecutable<>(theResources);
return new TransactionExecutable<>(myClient, theResources);
}
}
@ -2447,6 +2641,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private String mySearchUrl;
private boolean myIsHistoryRewrite;
public UpdateInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public IUpdateTyped historyRewrite() {
myIsHistoryRewrite = true;
@ -2563,6 +2761,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
implements IValidate, IValidateUntyped {
private IBaseResource myResource;
public ValidateInternal(IHttpClient theClient) {
super(theClient);
}
@Override
public MethodOutcome execute() {
BaseHttpClientInvocation invocation =

View File

@ -25,6 +25,8 @@ import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.UrlSourceEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.client.model.AsHttpRequestParams;
import ca.uhn.fhir.rest.client.model.CreateRequestParameters;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.lang3.StringUtils;
@ -87,6 +89,18 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
Map<String, List<String>> theExtraParams,
EncodingEnum theEncoding,
Boolean thePrettyPrint) {
return asHttpRequest(new AsHttpRequestParams()
.setUrlBase(theUrlBase)
.setExtraParams(theExtraParams)
.setPrettyPrint(thePrettyPrint)
.setEncodingEnum(theEncoding));
}
@Override
public IHttpRequest asHttpRequest(AsHttpRequestParams theAsHttpRequestParams) {
String theUrlBase = theAsHttpRequestParams.getUrlBase();
Map<String, List<String>> theExtraParams = theAsHttpRequestParams.getExtraParams();
EncodingEnum theEncoding = theAsHttpRequestParams.getEncodingEnum();
StringBuilder b = new StringBuilder();
if (!myUrlPath.contains("://")) {
@ -110,7 +124,14 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
appendExtraParamsWithQuestionMark(theExtraParams, b, first);
IHttpRequest retVal = super.createHttpRequest(b.toString(), theEncoding, RequestTypeEnum.GET);
// TODO - pass client down here
CreateRequestParameters createRequestParameters = new CreateRequestParameters()
.setRequestTypeEnum(RequestTypeEnum.GET)
.setEncodingEnum(theEncoding)
.setUrl(b.toString())
.setClient(theAsHttpRequestParams.getClient());
IHttpRequest retVal = super.createHttpRequest(createRequestParameters);
// IHttpRequest retVal = super.createHttpRequest(b.toString(), theEncoding, RequestTypeEnum.GET);
retVal.setUrlSource(myUrlSource);
return retVal;

View File

@ -0,0 +1,77 @@
package ca.uhn.fhir.rest.client.model;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.client.api.IHttpClient;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AsHttpRequestParams {
private String myUrlBase;
private Map<String, List<String>> myExtraParams;
private EncodingEnum myEncodingEnum;
private Boolean myPrettyPrint;
private IHttpClient myClient;
public String getUrlBase() {
return myUrlBase;
}
public AsHttpRequestParams setUrlBase(String theUrlBase) {
myUrlBase = theUrlBase;
return this;
}
public Map<String, List<String>> getExtraParams() {
if (myExtraParams == null) {
myExtraParams = new HashMap<>();
}
return myExtraParams;
}
public void addExtraParam(String theKey, String theValue) {
Map<String, List<String>> extraParams = getExtraParams();
if (!extraParams.containsKey(theKey)) {
extraParams.put(theKey, new ArrayList<>());
}
extraParams.get(theKey).add(theValue);
}
public AsHttpRequestParams setExtraParams(Map<String, List<String>> theExtraParams) {
myExtraParams = theExtraParams;
return this;
}
public EncodingEnum getEncodingEnum() {
return myEncodingEnum;
}
public AsHttpRequestParams setEncodingEnum(EncodingEnum theEncodingEnum) {
myEncodingEnum = theEncodingEnum;
return this;
}
public Boolean getPrettyPrint() {
return myPrettyPrint;
}
public AsHttpRequestParams setPrettyPrint(Boolean thePrettyPrint) {
myPrettyPrint = thePrettyPrint;
return this;
}
public IHttpClient getClient() {
return myClient;
}
public AsHttpRequestParams setClient(IHttpClient theClient) {
myClient = theClient;
return this;
}
}

View File

@ -0,0 +1,43 @@
package ca.uhn.fhir.rest.client.model;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import org.apache.http.HttpEntity;
@Deprecated
public class CreateHttpRequestParameters {
/**
* GET, DELETE, etc...
* This is the minimum info needed to make a request
*/
private final RequestTypeEnum myRequestTypeEnum;
private HttpEntity myEntity;
private String myUrl;
public CreateHttpRequestParameters(RequestTypeEnum theRequestTypeEnum) {
myRequestTypeEnum = theRequestTypeEnum;
}
public RequestTypeEnum getRequestTypeEnum() {
return myRequestTypeEnum;
}
public HttpEntity getEntity() {
return myEntity;
}
public CreateHttpRequestParameters setEntity(HttpEntity theEntity) {
myEntity = theEntity;
return this;
}
public String getUrl() {
return myUrl;
}
public CreateHttpRequestParameters setUrl(String theUrl) {
myUrl = theUrl;
return this;
}
}

View File

@ -0,0 +1,60 @@
package ca.uhn.fhir.rest.client.model;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.api.IHttpClient;
public class CreateRequestParameters {
/**
* The complete FHIR url to which the http request will be sent
*/
private String myUrl;
/**
* The encoding to use for any serialized content sent to the
* server
*/
private EncodingEnum myEncodingEnum;
/**
* the type of HTTP request (GET, DELETE, ..)
*/
private RequestTypeEnum myRequestTypeEnum;
private IHttpClient myClient;
public String getUrl() {
return myUrl;
}
public CreateRequestParameters setUrl(String theUrl) {
myUrl = theUrl;
return this;
}
public EncodingEnum getEncodingEnum() {
return myEncodingEnum;
}
public CreateRequestParameters setEncodingEnum(EncodingEnum theEncodingEnum) {
myEncodingEnum = theEncodingEnum;
return this;
}
public RequestTypeEnum getRequestTypeEnum() {
return myRequestTypeEnum;
}
public CreateRequestParameters setRequestTypeEnum(RequestTypeEnum theRequestTypeEnum) {
myRequestTypeEnum = theRequestTypeEnum;
return this;
}
public IHttpClient getClient() {
return myClient;
}
public CreateRequestParameters setClient(IHttpClient theClient) {
myClient = theClient;
return this;
}
}

View File

@ -0,0 +1,146 @@
package ca.uhn.fhir.rest.client.model;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.client.method.IClientResponseHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class InvokeClientParameters<T> {
private FhirContext myContext;
private IClientResponseHandler<T> myBinding;
private BaseHttpClientInvocation myClientInvocation;
private EncodingEnum myEncoding;
private Boolean myPrettyPrint;
private boolean theLogRequestAndResponse;
private SummaryEnum mySummaryMode;
private Set<String> mySubsetElements;
private CacheControlDirective myCacheControlDirective;
private String myCustomAcceptHeader;
private Map<String, List<String>> myCustomHeaders;
public FhirContext getContext() {
return myContext;
}
public InvokeClientParameters<T> setContext(FhirContext theContext) {
myContext = theContext;
return this;
}
public IClientResponseHandler<T> getBinding() {
return myBinding;
}
public InvokeClientParameters<T> setBinding(IClientResponseHandler<T> theBinding) {
myBinding = theBinding;
return this;
}
public BaseHttpClientInvocation getClientInvocation() {
return myClientInvocation;
}
public InvokeClientParameters<T> setClientInvocation(BaseHttpClientInvocation theClientInvocation) {
myClientInvocation = theClientInvocation;
return this;
}
public EncodingEnum getEncoding() {
return myEncoding;
}
public InvokeClientParameters<T> setEncoding(EncodingEnum theEncoding) {
myEncoding = theEncoding;
return this;
}
public Boolean getPrettyPrint() {
return myPrettyPrint;
}
public InvokeClientParameters<T> setPrettyPrint(Boolean thePrettyPrint) {
myPrettyPrint = thePrettyPrint;
return this;
}
public boolean isTheLogRequestAndResponse() {
return theLogRequestAndResponse;
}
public InvokeClientParameters<T> setTheLogRequestAndResponse(boolean theTheLogRequestAndResponse) {
theLogRequestAndResponse = theTheLogRequestAndResponse;
return this;
}
public SummaryEnum getSummaryMode() {
return mySummaryMode;
}
public InvokeClientParameters<T> setSummaryMode(SummaryEnum theSummaryMode) {
mySummaryMode = theSummaryMode;
return this;
}
public Set<String> getSubsetElements() {
if (mySubsetElements == null) {
mySubsetElements = new HashSet<>();
}
return mySubsetElements;
}
public InvokeClientParameters<T> setSubsetElements(Set<String> theSubsetElements) {
mySubsetElements = theSubsetElements;
return this;
}
public void addSubsetElements(String theEl) {
getSubsetElements().add(theEl);
}
public CacheControlDirective getCacheControlDirective() {
return myCacheControlDirective;
}
public InvokeClientParameters<T> setCacheControlDirective(CacheControlDirective theCacheControlDirective) {
myCacheControlDirective = theCacheControlDirective;
return this;
}
public String getCustomAcceptHeader() {
return myCustomAcceptHeader;
}
public InvokeClientParameters<T> setCustomAcceptHeader(String theCustomAcceptHeader) {
myCustomAcceptHeader = theCustomAcceptHeader;
return this;
}
public Map<String, List<String>> getCustomHeaders() {
if (myCustomHeaders == null) {
myCustomHeaders = new HashMap<>();
}
return myCustomHeaders;
}
public InvokeClientParameters<T> setCustomHeaders(Map<String, List<String>> theCustomHeaders) {
myCustomHeaders = theCustomHeaders;
return this;
}
public void addCustomHeader(String theKey, String theValue) {
Map<String, List<String>> headers = getCustomHeaders();
if (!headers.containsKey(theKey)) {
headers.put(theKey, new ArrayList<>());
}
headers.get(theKey).add(theValue);
}
}