mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-02-18 10:55:22 +00:00
Allow client defined parameter style for _format param
This commit is contained in:
parent
3ae5f9a3b7
commit
82ec721c99
@ -0,0 +1,14 @@
|
|||||||
|
package ca.uhn.fhir.rest.api;
|
||||||
|
|
||||||
|
public enum RequestFormatParamStyleEnum {
|
||||||
|
/**
|
||||||
|
* Do not include a _format parameter on requests
|
||||||
|
*/
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "xml" or "json"
|
||||||
|
*/
|
||||||
|
SHORT
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,11 @@
|
|||||||
package ca.uhn.fhir.rest.client.api;
|
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.api.RequestFormatParamStyleEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22,12 +28,6 @@ import java.util.List;
|
|||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
|
||||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
|
||||||
|
|
||||||
public interface IRestfulClient {
|
public interface IRestfulClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,10 +35,8 @@ public interface IRestfulClient {
|
|||||||
* method could be used as a low level implementation of a read/vread/search
|
* method could be used as a low level implementation of a read/vread/search
|
||||||
* operation.
|
* operation.
|
||||||
*
|
*
|
||||||
* @param theResourceType
|
* @param theResourceType The resource type to parse
|
||||||
* The resource type to parse
|
* @param theUrl The URL to load
|
||||||
* @param theUrl
|
|
||||||
* The URL to load
|
|
||||||
* @return The parsed resource
|
* @return The parsed resource
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T fetchResourceFromUrl(Class<T> theResourceType, String theUrl);
|
<T extends IBaseResource> T fetchResourceFromUrl(Class<T> theResourceType, String theUrl);
|
||||||
@ -49,6 +47,17 @@ public interface IRestfulClient {
|
|||||||
*/
|
*/
|
||||||
EncodingEnum getEncoding();
|
EncodingEnum getEncoding();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that the client should use the given encoding to do its
|
||||||
|
* queries. This means that the client will append the "_format" param
|
||||||
|
* to GET methods (read/search/etc), and will add an appropriate header for
|
||||||
|
* write methods.
|
||||||
|
*
|
||||||
|
* @param theEncoding The encoding to use in the request, or <code>null</code> not specify
|
||||||
|
* an encoding (which generally implies the use of XML). The default is <code>null</code>.
|
||||||
|
*/
|
||||||
|
void setEncoding(EncodingEnum theEncoding);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the FHIR context associated with this client
|
* Returns the FHIR context associated with this client
|
||||||
*/
|
*/
|
||||||
@ -76,25 +85,12 @@ public interface IRestfulClient {
|
|||||||
*/
|
*/
|
||||||
void registerInterceptor(IClientInterceptor theInterceptor);
|
void registerInterceptor(IClientInterceptor theInterceptor);
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies that the client should use the given encoding to do its
|
|
||||||
* queries. This means that the client will append the "_format" param
|
|
||||||
* to GET methods (read/search/etc), and will add an appropriate header for
|
|
||||||
* write methods.
|
|
||||||
*
|
|
||||||
* @param theEncoding
|
|
||||||
* The encoding to use in the request, or <code>null</code> not specify
|
|
||||||
* an encoding (which generally implies the use of XML). The default is <code>null</code>.
|
|
||||||
*/
|
|
||||||
void setEncoding(EncodingEnum theEncoding);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies that the client should request that the server respond with "pretty printing"
|
* Specifies that the client should request that the server respond with "pretty printing"
|
||||||
* enabled. Note that this is a non-standard parameter, not all servers will
|
* enabled. Note that this is a non-standard parameter, not all servers will
|
||||||
* support it.
|
* support it.
|
||||||
*
|
*
|
||||||
* @param thePrettyPrint
|
* @param thePrettyPrint The pretty print flag to use in the request (default is <code>false</code>)
|
||||||
* The pretty print flag to use in the request (default is <code>false</code>)
|
|
||||||
*/
|
*/
|
||||||
void setPrettyPrint(Boolean thePrettyPrint);
|
void setPrettyPrint(Boolean thePrettyPrint);
|
||||||
|
|
||||||
@ -109,4 +105,8 @@ public interface IRestfulClient {
|
|||||||
*/
|
*/
|
||||||
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures what style of _format parameter should be used in requests
|
||||||
|
*/
|
||||||
|
void setFormatParamStyle(RequestFormatParamStyleEnum theRequestFormatParamStyle);
|
||||||
}
|
}
|
||||||
|
@ -20,49 +20,11 @@ package ca.uhn.fhir.rest.client.impl;
|
|||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import ca.uhn.fhir.context.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
|
||||||
import ca.uhn.fhir.util.XmlDetectionUtil;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
|
||||||
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.BaseRuntimeChildDefinition;
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
|
||||||
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.Constants;
|
import ca.uhn.fhir.rest.api.*;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.client.api.*;
|
||||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IClientInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IHttpResponse;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
|
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
|
||||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
|
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
|
||||||
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
||||||
@ -72,7 +34,19 @@ import ca.uhn.fhir.rest.client.method.IClientResponseHandlerHandlesBinary;
|
|||||||
import ca.uhn.fhir.rest.client.method.MethodUtil;
|
import ca.uhn.fhir.rest.client.method.MethodUtil;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
import ca.uhn.fhir.util.XmlUtil;
|
import ca.uhn.fhir.util.XmlDetectionUtil;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public abstract class BaseClient implements IRestfulClient {
|
public abstract class BaseClient implements IRestfulClient {
|
||||||
|
|
||||||
@ -86,16 +60,17 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseClient.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseClient.class);
|
||||||
|
|
||||||
private final IHttpClient myClient;
|
private final IHttpClient myClient;
|
||||||
|
private final RestfulClientFactory myFactory;
|
||||||
|
private final String myUrlBase;
|
||||||
private boolean myDontValidateConformance;
|
private boolean myDontValidateConformance;
|
||||||
private EncodingEnum myEncoding = null; // default unspecified (will be XML)
|
private EncodingEnum myEncoding = null; // default unspecified (will be XML)
|
||||||
private final RestfulClientFactory myFactory;
|
|
||||||
private List<IClientInterceptor> myInterceptors = new ArrayList<IClientInterceptor>();
|
private List<IClientInterceptor> myInterceptors = new ArrayList<IClientInterceptor>();
|
||||||
private boolean myKeepResponses = false;
|
private boolean myKeepResponses = false;
|
||||||
private IHttpResponse myLastResponse;
|
private IHttpResponse myLastResponse;
|
||||||
private String myLastResponseBody;
|
private String myLastResponseBody;
|
||||||
private Boolean myPrettyPrint = false;
|
private Boolean myPrettyPrint = false;
|
||||||
private SummaryEnum mySummary;
|
private SummaryEnum mySummary;
|
||||||
private final String myUrlBase;
|
private RequestFormatParamStyleEnum myRequestFormatParamStyle = RequestFormatParamStyleEnum.SHORT;
|
||||||
|
|
||||||
BaseClient(IHttpClient theClient, String theUrlBase, RestfulClientFactory theFactory) {
|
BaseClient(IHttpClient theClient, String theUrlBase, RestfulClientFactory theFactory) {
|
||||||
super();
|
super();
|
||||||
@ -121,11 +96,13 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
protected Map<String, List<String>> createExtraParams() {
|
protected Map<String, List<String>> createExtraParams() {
|
||||||
HashMap<String, List<String>> retVal = new LinkedHashMap<String, List<String>>();
|
HashMap<String, List<String>> retVal = new LinkedHashMap<String, List<String>>();
|
||||||
|
|
||||||
|
if (myRequestFormatParamStyle == RequestFormatParamStyleEnum.SHORT) {
|
||||||
if (getEncoding() == EncodingEnum.XML) {
|
if (getEncoding() == EncodingEnum.XML) {
|
||||||
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||||
} else if (getEncoding() == EncodingEnum.JSON) {
|
} else if (getEncoding() == EncodingEnum.JSON) {
|
||||||
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isPrettyPrint()) {
|
if (isPrettyPrint()) {
|
||||||
retVal.put(Constants.PARAM_PRETTY, Collections.singletonList(Constants.PARAM_PRETTY_VALUE_TRUE));
|
retVal.put(Constants.PARAM_PRETTY, Collections.singletonList(Constants.PARAM_PRETTY_VALUE_TRUE));
|
||||||
@ -150,6 +127,17 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
return myEncoding;
|
return myEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the encoding that will be used on requests. Default is <code>null</code>, which means the client will not
|
||||||
|
* explicitly request an encoding. (This is perfectly acceptable behaviour according to the FHIR specification. In
|
||||||
|
* this case, the server will choose which encoding to return, and the client can handle either XML or JSON)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setEncoding(EncodingEnum theEncoding) {
|
||||||
|
myEncoding = theEncoding;
|
||||||
|
// return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@ -192,10 +180,21 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
return mySummary;
|
return mySummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSummary(SummaryEnum theSummary) {
|
||||||
|
mySummary = theSummary;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUrlBase() {
|
public String getUrlBase() {
|
||||||
return myUrlBase;
|
return myUrlBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFormatParamStyle(RequestFormatParamStyleEnum theRequestFormatParamStyle) {
|
||||||
|
Validate.notNull(theRequestFormatParamStyle, "theRequestFormatParamStyle must not be null");
|
||||||
|
myRequestFormatParamStyle = theRequestFormatParamStyle;
|
||||||
|
}
|
||||||
|
|
||||||
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation) {
|
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation) {
|
||||||
return invokeClient(theContext, binding, clientInvocation, false);
|
return invokeClient(theContext, binding, clientInvocation, false);
|
||||||
}
|
}
|
||||||
@ -219,12 +218,14 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
Map<String, List<String>> params = createExtraParams();
|
Map<String, List<String>> params = createExtraParams();
|
||||||
|
|
||||||
if (clientInvocation instanceof HttpGetClientInvocation) {
|
if (clientInvocation instanceof HttpGetClientInvocation) {
|
||||||
|
if (myRequestFormatParamStyle == RequestFormatParamStyleEnum.SHORT) {
|
||||||
if (theEncoding == EncodingEnum.XML) {
|
if (theEncoding == EncodingEnum.XML) {
|
||||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
params.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||||
} else if (theEncoding == EncodingEnum.JSON) {
|
} else if (theEncoding == EncodingEnum.JSON) {
|
||||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
params.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (theSummaryMode != null) {
|
if (theSummaryMode != null) {
|
||||||
params.put(Constants.PARAM_SUMMARY, Collections.singletonList(theSummaryMode.getCode()));
|
params.put(Constants.PARAM_SUMMARY, Collections.singletonList(theSummaryMode.getCode()));
|
||||||
@ -397,6 +398,13 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
return myKeepResponses;
|
return myKeepResponses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
|
||||||
|
*/
|
||||||
|
public void setKeepResponses(boolean theKeepResponses) {
|
||||||
|
myKeepResponses = theKeepResponses;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the pretty print flag, which is a request to the server for it to return "pretty printed" responses. Note
|
* Returns the pretty print flag, which is a request to the server for it to return "pretty printed" responses. Note
|
||||||
* that this is currently a non-standard flag (_pretty) which is supported only by HAPI based servers (and any other
|
* that this is currently a non-standard flag (_pretty) which is supported only by HAPI based servers (and any other
|
||||||
@ -406,6 +414,17 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
return Boolean.TRUE.equals(myPrettyPrint);
|
return Boolean.TRUE.equals(myPrettyPrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pretty print flag, which is a request to the server for it to return "pretty printed" responses. Note
|
||||||
|
* that this is currently a non-standard flag (_pretty) which is supported only by HAPI based servers (and any other
|
||||||
|
* servers which might implement it).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setPrettyPrint(Boolean thePrettyPrint) {
|
||||||
|
myPrettyPrint = thePrettyPrint;
|
||||||
|
// return this;
|
||||||
|
}
|
||||||
|
|
||||||
private void keepResponseAndLogIt(boolean theLogRequestAndResponse, IHttpResponse response, String responseString) {
|
private void keepResponseAndLogIt(boolean theLogRequestAndResponse, IHttpResponse response, String responseString) {
|
||||||
if (myKeepResponses) {
|
if (myKeepResponses) {
|
||||||
myLastResponse = response;
|
myLastResponse = response;
|
||||||
@ -438,55 +457,12 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
myDontValidateConformance = theDontValidateConformance;
|
myDontValidateConformance = theDontValidateConformance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the encoding that will be used on requests. Default is <code>null</code>, which means the client will not
|
|
||||||
* explicitly request an encoding. (This is perfectly acceptable behaviour according to the FHIR specification. In
|
|
||||||
* this case, the server will choose which encoding to return, and the client can handle either XML or JSON)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setEncoding(EncodingEnum theEncoding) {
|
|
||||||
myEncoding = theEncoding;
|
|
||||||
// return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
|
|
||||||
*/
|
|
||||||
public void setKeepResponses(boolean theKeepResponses) {
|
|
||||||
myKeepResponses = theKeepResponses;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the pretty print flag, which is a request to the server for it to return "pretty printed" responses. Note
|
|
||||||
* that this is currently a non-standard flag (_pretty) which is supported only by HAPI based servers (and any other
|
|
||||||
* servers which might implement it).
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setPrettyPrint(Boolean thePrettyPrint) {
|
|
||||||
myPrettyPrint = thePrettyPrint;
|
|
||||||
// return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSummary(SummaryEnum theSummary) {
|
|
||||||
mySummary = theSummary;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterInterceptor(IClientInterceptor theInterceptor) {
|
public void unregisterInterceptor(IClientInterceptor theInterceptor) {
|
||||||
Validate.notNull(theInterceptor, "Interceptor can not be null");
|
Validate.notNull(theInterceptor, "Interceptor can not be null");
|
||||||
myInterceptors.remove(theInterceptor);
|
myInterceptors.remove(theInterceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArrayList<Class<? extends IBaseResource>> toTypeList(Class<? extends IBaseResource> thePreferResponseType) {
|
|
||||||
ArrayList<Class<? extends IBaseResource>> preferResponseTypes = null;
|
|
||||||
if (thePreferResponseType != null) {
|
|
||||||
preferResponseTypes = new ArrayList<Class<? extends IBaseResource>>(1);
|
|
||||||
preferResponseTypes.add(thePreferResponseType);
|
|
||||||
}
|
|
||||||
return preferResponseTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final class ResourceResponseHandler<T extends IBaseResource> implements IClientResponseHandler<T> {
|
protected final class ResourceResponseHandler<T extends IBaseResource> implements IClientResponseHandler<T> {
|
||||||
|
|
||||||
private boolean myAllowHtmlResponse;
|
private boolean myAllowHtmlResponse;
|
||||||
@ -568,4 +544,13 @@ public abstract class BaseClient implements IRestfulClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ArrayList<Class<? extends IBaseResource>> toTypeList(Class<? extends IBaseResource> thePreferResponseType) {
|
||||||
|
ArrayList<Class<? extends IBaseResource>> preferResponseTypes = null;
|
||||||
|
if (thePreferResponseType != null) {
|
||||||
|
preferResponseTypes = new ArrayList<Class<? extends IBaseResource>>(1);
|
||||||
|
preferResponseTypes.add(thePreferResponseType);
|
||||||
|
}
|
||||||
|
return preferResponseTypes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
package ca.uhn.fhir.rest.client;
|
package ca.uhn.fhir.rest.client;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.RequestFormatParamStyleEnum;
|
||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.util.RandomServerPortProvider;
|
import ca.uhn.fhir.util.RandomServerPortProvider;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import ca.uhn.fhir.util.VersionUtil;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
@ -20,9 +16,7 @@ import org.junit.AfterClass;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@ -40,8 +34,9 @@ public class ClientHeadersR4Test {
|
|||||||
private static Server ourServer;
|
private static Server ourServer;
|
||||||
private static String ourServerBase;
|
private static String ourServerBase;
|
||||||
private static HashMap<String, List<String>> ourHeaders;
|
private static HashMap<String, List<String>> ourHeaders;
|
||||||
private static IGenericClient ourClient;
|
private static HashMap<String, String[]> ourParams;
|
||||||
private static String ourMethod;
|
private static String ourMethod;
|
||||||
|
private IGenericClient myClient;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
@ -49,34 +44,125 @@ public class ClientHeadersR4Test {
|
|||||||
ourMethod = null;
|
ourMethod = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String expectedUserAgent() {
|
|
||||||
return "HAPI-FHIR/" + VersionUtil.getVersion() + " (FHIR Client; FHIR " + FhirVersionEnum.R4.getFhirVersionString() + "/R4; apache)";
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] extractBodyAsByteArray(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
|
||||||
byte[] body = IOUtils.toByteArray(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent());
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String extractBodyAsString(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
|
||||||
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8");
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithPreferRepresentationServerReturnsResource() throws Exception {
|
public void testReadXml() {
|
||||||
|
myClient
|
||||||
|
.read()
|
||||||
|
.resource("Patient")
|
||||||
|
.withId(123L)
|
||||||
|
.encodedXml()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", ourHeaders.get(Constants.HEADER_ACCEPT).get(0));
|
||||||
|
assertEquals("xml", ourParams.get(Constants.PARAM_FORMAT)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadXmlNoParam() {
|
||||||
|
myClient.setFormatParamStyle(RequestFormatParamStyleEnum.NONE);
|
||||||
|
myClient
|
||||||
|
.read()
|
||||||
|
.resource("Patient")
|
||||||
|
.withId(123L)
|
||||||
|
.encodedXml()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", ourHeaders.get(Constants.HEADER_ACCEPT).get(0));
|
||||||
|
assertEquals(null, ourParams.get(Constants.PARAM_FORMAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadJson() {
|
||||||
|
myClient
|
||||||
|
.read()
|
||||||
|
.resource("Patient")
|
||||||
|
.withId(123L)
|
||||||
|
.encodedJson()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", ourHeaders.get(Constants.HEADER_ACCEPT).get(0));
|
||||||
|
assertEquals("json", ourParams.get(Constants.PARAM_FORMAT)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadJsonNoParam() {
|
||||||
|
myClient.setFormatParamStyle(RequestFormatParamStyleEnum.NONE);
|
||||||
|
myClient
|
||||||
|
.read()
|
||||||
|
.resource("Patient")
|
||||||
|
.withId(123L)
|
||||||
|
.encodedJson()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", ourHeaders.get(Constants.HEADER_ACCEPT).get(0));
|
||||||
|
assertEquals(null, ourParams.get(Constants.PARAM_FORMAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadXmlDisable() {
|
||||||
|
myClient
|
||||||
|
.read()
|
||||||
|
.resource("Patient")
|
||||||
|
.withId(123L)
|
||||||
|
.encodedXml()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", ourHeaders.get(Constants.HEADER_ACCEPT).get(0));
|
||||||
|
assertEquals("xml", ourParams.get(Constants.PARAM_FORMAT)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithPreferRepresentationServerReturnsResource() {
|
||||||
|
|
||||||
final Patient resp1 = new Patient();
|
final Patient resp1 = new Patient();
|
||||||
resp1.setActive(true);
|
resp1.setActive(true);
|
||||||
|
|
||||||
MethodOutcome resp = ourClient.create().resource(resp1).execute();
|
MethodOutcome resp = myClient.create().resource(resp1).execute();
|
||||||
|
|
||||||
assertNotNull(resp);
|
assertNotNull(resp);
|
||||||
assertEquals(1, ourHeaders.get(Constants.HEADER_CONTENT_TYPE).size());
|
assertEquals(1, ourHeaders.get(Constants.HEADER_CONTENT_TYPE).size());
|
||||||
assertEquals("application/fhir+xml; charset=UTF-8", ourHeaders.get(Constants.HEADER_CONTENT_TYPE).get(0));
|
assertEquals("application/fhir+xml; charset=UTF-8", ourHeaders.get(Constants.HEADER_CONTENT_TYPE).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeCreateClient() {
|
||||||
|
myClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
||||||
|
|
||||||
|
if (ourHeaders != null) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
ourHeaders = new HashMap<>();
|
||||||
|
ourParams = new HashMap<>(req.getParameterMap());
|
||||||
|
ourMethod = req.getMethod();
|
||||||
|
Enumeration<String> names = req.getHeaderNames();
|
||||||
|
while (names.hasMoreElements()) {
|
||||||
|
String nextName = names.nextElement();
|
||||||
|
ourHeaders.put(nextName, new ArrayList<>());
|
||||||
|
Enumeration<String> values = req.getHeaders(nextName);
|
||||||
|
while (values.hasMoreElements()) {
|
||||||
|
ourHeaders.get(nextName).add(values.nextElement());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.setStatus(200);
|
||||||
|
|
||||||
|
if (req.getMethod().equals("GET")) {
|
||||||
|
resp.setContentType("application/json");
|
||||||
|
resp.getWriter().append("{\"resourceType\":\"Patient\"}");
|
||||||
|
resp.getWriter().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
@ -94,7 +180,6 @@ public class ClientHeadersR4Test {
|
|||||||
|
|
||||||
ourServerBase = "http://localhost:" + myPort + "/fhir/context";
|
ourServerBase = "http://localhost:" + myPort + "/fhir/context";
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
|
||||||
|
|
||||||
ServletHolder servletHolder = new ServletHolder();
|
ServletHolder servletHolder = new ServletHolder();
|
||||||
servletHolder.setServlet(new TestServlet());
|
servletHolder.setServlet(new TestServlet());
|
||||||
@ -105,29 +190,4 @@ public class ClientHeadersR4Test {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestServlet extends HttpServlet {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
|
|
||||||
if (ourHeaders != null) {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
ourHeaders = new HashMap<>();
|
|
||||||
ourMethod = req.getMethod();
|
|
||||||
Enumeration<String> names = req.getHeaderNames();
|
|
||||||
while (names.hasMoreElements()) {
|
|
||||||
String nextName = names.nextElement();
|
|
||||||
ourHeaders.put(nextName, new ArrayList<String>());
|
|
||||||
Enumeration<String> values = req.getHeaders(nextName);
|
|
||||||
while (values.hasMoreElements()) {
|
|
||||||
ourHeaders.get(nextName).add(values.nextElement());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.setStatus(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,12 @@
|
|||||||
<action type="fix" issue="1071" dev="volsch">
|
<action type="fix" issue="1071" dev="volsch">
|
||||||
When restful reponses tried to return multiple instances of the same response header,
|
When restful reponses tried to return multiple instances of the same response header,
|
||||||
some instances were discarded. Thanks to Volker Schmidt for the pull request!
|
some instances were discarded. Thanks to Volker Schmidt for the pull request!
|
||||||
</action>"
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
The REST client now allows for configurable behaviour as to whether a
|
||||||
|
<![CDATA[<code>_format</code>]]>
|
||||||
|
parameter should be included in requests.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
|
|
||||||
<release version="3.5.0" date="2018-09-17">
|
<release version="3.5.0" date="2018-09-17">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user