Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
71dfed282c
|
@ -34,6 +34,7 @@ import org.thymeleaf.cache.ICacheEntryValidity;
|
|||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.context.ITemplateContext;
|
||||
import org.thymeleaf.engine.AttributeName;
|
||||
import org.thymeleaf.messageresolver.IMessageResolver;
|
||||
import org.thymeleaf.model.IProcessableElementTag;
|
||||
import org.thymeleaf.processor.IProcessor;
|
||||
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
|
||||
|
@ -65,6 +66,8 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
|||
private HashMap<String, String> myNameToNarrativeTemplate;
|
||||
private TemplateEngine myProfileTemplateEngine;
|
||||
|
||||
private IMessageResolver resolver;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -166,11 +169,21 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
|||
|
||||
};
|
||||
myProfileTemplateEngine.setDialect(dialect);
|
||||
if (this.resolver != null) {
|
||||
myProfileTemplateEngine.setMessageResolver(this.resolver);
|
||||
}
|
||||
}
|
||||
|
||||
myInitialized = true;
|
||||
}
|
||||
|
||||
public void setMessageResolver(IMessageResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
if (myProfileTemplateEngine != null && resolver != null) {
|
||||
myProfileTemplateEngine.setMessageResolver(resolver);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to <code>true</code> (which is the default), most whitespace will be trimmed from the generated narrative
|
||||
* before it is returned.
|
||||
|
|
|
@ -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;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
|
@ -11,9 +17,9 @@ import java.util.List;
|
|||
* 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.
|
||||
|
@ -22,23 +28,15 @@ import java.util.List;
|
|||
* #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 {
|
||||
|
||||
/**
|
||||
* Retrieve the contents at the given URL and parse them as a resource. This
|
||||
* method could be used as a low level implementation of a read/vread/search
|
||||
* operation.
|
||||
*
|
||||
* @param theResourceType
|
||||
* The resource type to parse
|
||||
* @param theUrl
|
||||
* The URL to load
|
||||
*
|
||||
* @param theResourceType The resource type to parse
|
||||
* @param theUrl The URL to load
|
||||
* @return The parsed resource
|
||||
*/
|
||||
<T extends IBaseResource> T fetchResourceFromUrl(Class<T> theResourceType, String theUrl);
|
||||
|
@ -49,6 +47,17 @@ public interface IRestfulClient {
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -76,25 +85,12 @@ public interface IRestfulClient {
|
|||
*/
|
||||
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"
|
||||
* enabled. Note that this is a non-standard parameter, not all servers will
|
||||
* support it.
|
||||
*
|
||||
* @param thePrettyPrint
|
||||
* The pretty print flag to use in the request (default is <code>false</code>)
|
||||
*
|
||||
* @param thePrettyPrint The pretty print flag to use in the request (default is <code>false</code>)
|
||||
*/
|
||||
void setPrettyPrint(Boolean thePrettyPrint);
|
||||
|
||||
|
@ -109,4 +105,8 @@ public interface IRestfulClient {
|
|||
*/
|
||||
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
||||
|
||||
/**
|
||||
* Configures what style of _format parameter should be used in requests
|
||||
*/
|
||||
void setFormatParamStyle(RequestFormatParamStyleEnum theRequestFormatParamStyle);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public interface IOperationUntyped {
|
|||
* @param theParameters The parameters to use as input. May also be <code>null</code> if the operation
|
||||
* does not require any input parameters.
|
||||
*/
|
||||
<T extends IBaseParameters> IOperationUntypedWithInput<T> withParameters(T theParameters);
|
||||
<T extends IBaseParameters> IOperationUntypedWithInputAndPartialOutput<T> withParameters(T theParameters);
|
||||
|
||||
/**
|
||||
* The operation does not require any input parameters
|
||||
|
|
|
@ -38,6 +38,8 @@ public interface IOperationUntypedWithInputAndPartialOutput<T extends IBaseParam
|
|||
IOperationUntypedWithInputAndPartialOutput<T> andParameter(String theName, IBase theValue);
|
||||
|
||||
/**
|
||||
* Adds a URL parameter to the request.
|
||||
*
|
||||
* Use chained method calls to construct a Parameters input. This form is a convenience
|
||||
* in order to allow simple method chaining to be used to build up a parameters
|
||||
* resource for the input of an operation without needing to manually construct one.
|
||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.rest.client.impl;
|
|||
* 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.
|
||||
|
@ -20,49 +20,11 @@ package ca.uhn.fhir.rest.client.impl;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
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.context.*;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
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.api.*;
|
||||
import ca.uhn.fhir.rest.client.api.*;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
|
||||
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.server.exceptions.BaseServerResponseException;
|
||||
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 {
|
||||
|
||||
|
@ -86,16 +60,17 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseClient.class);
|
||||
|
||||
private final IHttpClient myClient;
|
||||
private final RestfulClientFactory myFactory;
|
||||
private final String myUrlBase;
|
||||
private boolean myDontValidateConformance;
|
||||
private EncodingEnum myEncoding = null; // default unspecified (will be XML)
|
||||
private final RestfulClientFactory myFactory;
|
||||
private List<IClientInterceptor> myInterceptors = new ArrayList<IClientInterceptor>();
|
||||
private boolean myKeepResponses = false;
|
||||
private IHttpResponse myLastResponse;
|
||||
private String myLastResponseBody;
|
||||
private Boolean myPrettyPrint = false;
|
||||
private SummaryEnum mySummary;
|
||||
private final String myUrlBase;
|
||||
private RequestFormatParamStyleEnum myRequestFormatParamStyle = RequestFormatParamStyleEnum.SHORT;
|
||||
|
||||
BaseClient(IHttpClient theClient, String theUrlBase, RestfulClientFactory theFactory) {
|
||||
super();
|
||||
|
@ -121,10 +96,12 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
protected Map<String, List<String>> createExtraParams() {
|
||||
HashMap<String, List<String>> retVal = new LinkedHashMap<String, List<String>>();
|
||||
|
||||
if (getEncoding() == EncodingEnum.XML) {
|
||||
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||
} else if (getEncoding() == EncodingEnum.JSON) {
|
||||
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||
if (myRequestFormatParamStyle == RequestFormatParamStyleEnum.SHORT) {
|
||||
if (getEncoding() == EncodingEnum.XML) {
|
||||
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||
} else if (getEncoding() == EncodingEnum.JSON) {
|
||||
retVal.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||
}
|
||||
}
|
||||
|
||||
if (isPrettyPrint()) {
|
||||
|
@ -150,6 +127,17 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
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}
|
||||
*/
|
||||
|
@ -192,10 +180,21 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
return mySummary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSummary(SummaryEnum theSummary) {
|
||||
mySummary = theSummary;
|
||||
}
|
||||
|
||||
public String getUrlBase() {
|
||||
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) {
|
||||
return invokeClient(theContext, binding, clientInvocation, false);
|
||||
}
|
||||
|
@ -219,10 +218,12 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
Map<String, List<String>> params = createExtraParams();
|
||||
|
||||
if (clientInvocation instanceof HttpGetClientInvocation) {
|
||||
if (theEncoding == EncodingEnum.XML) {
|
||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||
} else if (theEncoding == EncodingEnum.JSON) {
|
||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||
if (myRequestFormatParamStyle == RequestFormatParamStyleEnum.SHORT) {
|
||||
if (theEncoding == EncodingEnum.XML) {
|
||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("xml"));
|
||||
} else if (theEncoding == EncodingEnum.JSON) {
|
||||
params.put(Constants.PARAM_FORMAT, Collections.singletonList("json"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +253,7 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
addToCacheControlHeader(b, Constants.CACHE_CONTROL_NO_CACHE, theCacheControlDirective.isNoCache());
|
||||
addToCacheControlHeader(b, Constants.CACHE_CONTROL_NO_STORE, theCacheControlDirective.isNoStore());
|
||||
if (theCacheControlDirective.getMaxResults() != null) {
|
||||
addToCacheControlHeader(b, Constants.CACHE_CONTROL_MAX_RESULTS+"="+ Integer.toString(theCacheControlDirective.getMaxResults().intValue()), true);
|
||||
addToCacheControlHeader(b, Constants.CACHE_CONTROL_MAX_RESULTS + "=" + Integer.toString(theCacheControlDirective.getMaxResults().intValue()), true);
|
||||
}
|
||||
if (b.length() > 0) {
|
||||
httpRequest.addHeader(Constants.HEADER_CACHE_CONTROL, b.toString());
|
||||
|
@ -397,6 +398,13 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
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
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (myKeepResponses) {
|
||||
myLastResponse = response;
|
||||
|
@ -438,55 +457,12 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
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
|
||||
public void unregisterInterceptor(IClientInterceptor theInterceptor) {
|
||||
Validate.notNull(theInterceptor, "Interceptor can not be null");
|
||||
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> {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1276,7 +1276,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseParameters> IOperationUntypedWithInput<T> withNoParameters(Class<T> theOutputParameterType) {
|
||||
public <T extends IBaseParameters> IOperationUntypedWithInputAndPartialOutput<T> withNoParameters(Class<T> theOutputParameterType) {
|
||||
Validate.notNull(theOutputParameterType, "theOutputParameterType may not be null");
|
||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theOutputParameterType);
|
||||
if (def == null) {
|
||||
|
@ -1307,9 +1307,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public IOperationUntypedWithInput withParameters(IBaseParameters theParameters) {
|
||||
public IOperationUntypedWithInputAndPartialOutput withParameters(IBaseParameters theParameters) {
|
||||
Validate.notNull(theParameters, "theParameters can not be null");
|
||||
myParameters = theParameters;
|
||||
myParametersDef = myContext.getResourceDefinition(theParameters.getClass());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1445,7 +1446,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
OutcomeResponseHandler binding = new OutcomeResponseHandler(myPrefer);
|
||||
|
||||
Map<String, List<String>> params = new HashMap<String, List<String>>();
|
||||
Map<String, List<String>> params = new HashMap<>();
|
||||
return invoke(params, binding, invocation);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
* #L%
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
@ -104,8 +105,11 @@ public class JaxRsResponse extends RestfulResponse<JaxRsRequest> {
|
|||
|
||||
private ResponseBuilder buildResponse(int statusCode) {
|
||||
ResponseBuilder response = Response.status(statusCode);
|
||||
for (Entry<String, String> header : getHeaders().entrySet()) {
|
||||
response.header(header.getKey(), header.getValue());
|
||||
for (Entry<String, List<String>> header : getHeaders().entrySet()) {
|
||||
final String key = header.getKey();
|
||||
for (String value : header.getValue()) {
|
||||
response.header(key, value);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.jaxrs.server.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -10,6 +11,7 @@ import java.util.Set;
|
|||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -108,10 +110,24 @@ public class JaxRsResponseTest {
|
|||
assertEquals("application/xml+fhir; charset=UTF-8", result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addMultipleHeaderValues() throws IOException {
|
||||
response.addHeader("Authorization", "Basic");
|
||||
response.addHeader("Authorization", "Bearer");
|
||||
response.addHeader("Cache-Control", "no-cache, no-store");
|
||||
|
||||
final IBaseBinary binary = new Binary();
|
||||
binary.setContentType("abc");
|
||||
binary.setContent(new byte[] { 1 });
|
||||
final Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theSummaryMode, 200, false, false, this.request);
|
||||
|
||||
assertThat(result.getHeaders().get("Authorization"), Matchers.contains("Basic", "Bearer"));
|
||||
assertThat(result.getHeaders().get("Cache-Control"), Matchers.contains("no-cache, no-store"));
|
||||
}
|
||||
|
||||
private Patient createPatient() {
|
||||
Patient theResource = new Patient();
|
||||
theResource.setId(new IdDt(15L));
|
||||
return theResource;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.jpa.config;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.query.criteria.LiteralHandlingMode;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
||||
|
|
|
@ -23,9 +23,9 @@ import java.util.*;
|
|||
* 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.
|
||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* 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.
|
||||
|
@ -43,10 +43,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import ca.uhn.fhir.util.*;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.http.NameValuePair;
|
||||
|
@ -86,17 +83,6 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
public static boolean isPlaceholder(IIdType theId) {
|
||||
if (theId != null && theId.getValue() != null) {
|
||||
return theId.getValue().startsWith("urn:oid:") || theId.getValue().startsWith("urn:uuid:");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String toStatusString(int theStatusCode) {
|
||||
return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
|
||||
}
|
||||
|
||||
private void populateEntryWithOperationOutcome(BaseServerResponseException caughtEx, BUNDLEENTRY nextEntry) {
|
||||
myVersionAdapter.populateEntryWithOperationOutcome(caughtEx, nextEntry);
|
||||
}
|
||||
|
@ -164,7 +150,6 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
return defaultString(theId.getValue()).startsWith(URN_PREFIX);
|
||||
}
|
||||
|
||||
|
||||
public void setDao(BaseHapiFhirDao theDao) {
|
||||
myDao = theDao;
|
||||
}
|
||||
|
@ -188,6 +173,40 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
}
|
||||
}
|
||||
|
||||
public BUNDLE collection(final RequestDetails theRequestDetails, BUNDLE theRequest) {
|
||||
String transactionType = myVersionAdapter.getBundleType(theRequest);
|
||||
|
||||
if (!org.hl7.fhir.r4.model.Bundle.BundleType.COLLECTION.toCode().equals(transactionType)) {
|
||||
throw new InvalidRequestException("Can not process collection Bundle of type: " + transactionType);
|
||||
}
|
||||
|
||||
ourLog.info("Beginning storing collection with {} resources", myVersionAdapter.getEntries(theRequest).size());
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
||||
BUNDLE resp = myVersionAdapter.createBundle(org.hl7.fhir.r4.model.Bundle.BundleType.BATCHRESPONSE.toCode());
|
||||
|
||||
List<IBaseResource> resources = new ArrayList<>();
|
||||
for (final BUNDLEENTRY nextRequestEntry : myVersionAdapter.getEntries(theRequest)) {
|
||||
IBaseResource resource = myVersionAdapter.getResource(nextRequestEntry);
|
||||
resources.add(resource);
|
||||
}
|
||||
|
||||
BUNDLE transactionBundle = myVersionAdapter.createBundle("transaction");
|
||||
for (IBaseResource next : resources) {
|
||||
BUNDLEENTRY entry = myVersionAdapter.addEntry(transactionBundle);
|
||||
myVersionAdapter.setResource(entry, next);
|
||||
myVersionAdapter.setRequestVerb(entry, "PUT");
|
||||
myVersionAdapter.setRequestUrl(entry, next.getIdElement().toUnqualifiedVersionless().getValue());
|
||||
}
|
||||
|
||||
transaction(theRequestDetails, transactionBundle);
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
private BUNDLE batch(final RequestDetails theRequestDetails, BUNDLE theRequest) {
|
||||
ourLog.info("Beginning batch with {} resources", myVersionAdapter.getEntries(theRequest).size());
|
||||
long start = System.currentTimeMillis();
|
||||
|
@ -255,6 +274,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
validateDependencies();
|
||||
|
||||
String transactionType = myVersionAdapter.getBundleType(theRequest);
|
||||
|
||||
if (org.hl7.fhir.r4.model.Bundle.BundleType.BATCH.toCode().equals(transactionType)) {
|
||||
return batch(theRequestDetails, theRequest);
|
||||
}
|
||||
|
@ -846,18 +866,10 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
String getEntryRequestIfNoneMatch(BUNDLEENTRY theEntry);
|
||||
|
||||
void setResponseOutcome(BUNDLEENTRY theEntry, IBaseOperationOutcome theOperationOutcome);
|
||||
}
|
||||
|
||||
private static class BaseServerResponseExceptionHolder {
|
||||
private BaseServerResponseException myException;
|
||||
void setRequestVerb(BUNDLEENTRY theEntry, String theVerb);
|
||||
|
||||
public BaseServerResponseException getException() {
|
||||
return myException;
|
||||
}
|
||||
|
||||
public void setException(BaseServerResponseException myException) {
|
||||
this.myException = myException;
|
||||
}
|
||||
void setRequestUrl(BUNDLEENTRY theEntry, String theUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -963,4 +975,27 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
|
||||
}
|
||||
|
||||
private static class BaseServerResponseExceptionHolder {
|
||||
private BaseServerResponseException myException;
|
||||
|
||||
public BaseServerResponseException getException() {
|
||||
return myException;
|
||||
}
|
||||
|
||||
public void setException(BaseServerResponseException myException) {
|
||||
this.myException = myException;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPlaceholder(IIdType theId) {
|
||||
if (theId != null && theId.getValue() != null) {
|
||||
return theId.getValue().startsWith("urn:oid:") || theId.getValue().startsWith("urn:uuid:");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String toStatusString(int theStatusCode) {
|
||||
return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ import java.util.Map;
|
|||
* 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.
|
||||
|
|
|
@ -150,4 +150,14 @@ public class TransactionProcessorVersionAdapterDstu3 implements TransactionProce
|
|||
theEntry.getResponse().setOutcome((Resource) theOperationOutcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestVerb(Bundle.BundleEntryComponent theEntry, String theVerb) {
|
||||
theEntry.getRequest().setMethod(Bundle.HTTPVerb.fromCode(theVerb));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestUrl(Bundle.BundleEntryComponent theEntry, String theUrl) {
|
||||
theEntry.getRequest().setUrl(theUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao.r4;
|
|||
* 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.
|
||||
|
@ -23,12 +23,12 @@ package ca.uhn.fhir.jpa.dao.r4;
|
|||
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.OperationOutcome;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.OperationOutcome;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
@ -150,4 +150,14 @@ public class TransactionProcessorVersionAdapterR4 implements TransactionProcesso
|
|||
theEntry.getResponse().setOutcome((Resource) theOperationOutcome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestVerb(Bundle.BundleEntryComponent theEntry, String theVerb) {
|
||||
theEntry.getRequest().setMethod(Bundle.HTTPVerb.fromCode(theVerb));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequestUrl(Bundle.BundleEntryComponent theEntry, String theUrl) {
|
||||
theEntry.getRequest().setUrl(theUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@ package ca.uhn.fhir.jpa.dao.dstu3;
|
|||
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.GZipUtil;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.parser.LenientErrorHandler;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -322,6 +324,20 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testProcessCollectionAsBatch() throws IOException {
|
||||
byte[] inputBytes = IOUtils.toByteArray(getClass().getResourceAsStream("/dstu3/Reilly_Libby_73.json.gz"));
|
||||
String input = GZipUtil.decompress(inputBytes);
|
||||
Bundle bundle = myFhirCtx.newJsonParser().setParserErrorHandler(new LenientErrorHandler()).parseResource(Bundle.class, input);
|
||||
ourLog.info("Bundle has {} resources", bundle);
|
||||
|
||||
Bundle output = mySystemDao.transaction(mySrd, bundle);
|
||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(output));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #410
|
||||
*/
|
||||
|
@ -3040,7 +3056,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
|
||||
@Test
|
||||
public void testTransactionWithReplacement() {
|
||||
byte[] bytes = new byte[] {0, 1, 2, 3, 4};
|
||||
byte[] bytes = new byte[]{0, 1, 2, 3, 4};
|
||||
|
||||
Binary binary = new Binary();
|
||||
binary.setId(IdType.newRandomUuid());
|
||||
|
|
Binary file not shown.
|
@ -21,9 +21,7 @@ package ca.uhn.fhir.rest.server;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.*;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
|
@ -35,7 +33,7 @@ public abstract class RestfulResponse<T extends RequestDetails> implements IRest
|
|||
|
||||
private IIdType myOperationResourceId;
|
||||
private IPrimitiveType<Date> myOperationResourceLastUpdated;
|
||||
private ConcurrentHashMap<String, String> theHeaders = new ConcurrentHashMap<String, String>();
|
||||
private Map<String, List<String>> theHeaders = new HashMap<>();
|
||||
private T theRequestDetails;
|
||||
|
||||
public RestfulResponse(T requestDetails) {
|
||||
|
@ -44,14 +42,14 @@ public abstract class RestfulResponse<T extends RequestDetails> implements IRest
|
|||
|
||||
@Override
|
||||
public void addHeader(String headerKey, String headerValue) {
|
||||
this.getHeaders().put(headerKey, headerValue);
|
||||
this.getHeaders().computeIfAbsent(headerKey, k -> new ArrayList<>()).add(headerValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the http headers
|
||||
* @return the headers
|
||||
*/
|
||||
public ConcurrentHashMap<String, String> getHeaders() {
|
||||
public Map<String, List<String>> getHeaders() {
|
||||
return theHeaders;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
|
|||
* 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.
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.IOException;
|
|||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
|
@ -75,8 +76,18 @@ public class ServletRestfulResponse extends RestfulResponse<ServletRequestDetail
|
|||
private void addHeaders() {
|
||||
HttpServletResponse theHttpResponse = getRequestDetails().getServletResponse();
|
||||
getRequestDetails().getServer().addHeadersToResponse(theHttpResponse);
|
||||
for (Entry<String, String> header : getHeaders().entrySet()) {
|
||||
theHttpResponse.setHeader(header.getKey(), header.getValue());
|
||||
for (Entry<String, List<String>> header : getHeaders().entrySet()) {
|
||||
final String key = header.getKey();
|
||||
boolean first = true;
|
||||
for (String value : header.getValue()) {
|
||||
// existing headers should be overridden
|
||||
if (first) {
|
||||
theHttpResponse.setHeader(key, value);
|
||||
first = false;
|
||||
} else {
|
||||
theHttpResponse.addHeader(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.MockSettings;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.CALLS_REAL_METHODS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.withSettings;
|
||||
|
||||
/**
|
||||
* Unit tests of {@link RestfulResponse}.
|
||||
*/
|
||||
public class RestfulResponseTest {
|
||||
@Test
|
||||
public void addMultipleHeaderValues() {
|
||||
@SuppressWarnings("unchecked")
|
||||
final RestfulResponse<?> restfulResponse =
|
||||
mock(RestfulResponse.class, withSettings()
|
||||
.useConstructor((RequestDetails) null).defaultAnswer(CALLS_REAL_METHODS));
|
||||
|
||||
restfulResponse.addHeader("Authorization", "Basic");
|
||||
restfulResponse.addHeader("Authorization", "Bearer");
|
||||
restfulResponse.addHeader("Cache-Control", "no-cache, no-store");
|
||||
|
||||
assertEquals(2, restfulResponse.getHeaders().size());
|
||||
assertThat(restfulResponse.getHeaders().get("Authorization"), Matchers.contains("Basic", "Bearer"));
|
||||
assertThat(restfulResponse.getHeaders().get("Cache-Control"), Matchers.contains("no-cache, no-store"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package ca.uhn.fhir.rest.server.servlet;
|
||||
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* Unit tests of {@link ServletRestfulResponse}.
|
||||
*/
|
||||
public class ServletRestfulResponseTest {
|
||||
@Mock
|
||||
private RestfulServer server;
|
||||
|
||||
@Mock
|
||||
private ServletOutputStream servletOutputStream;
|
||||
|
||||
@Mock
|
||||
private HttpServletResponse servletResponse;
|
||||
|
||||
private ServletRequestDetails requestDetails;
|
||||
|
||||
private ServletRestfulResponse response;
|
||||
|
||||
@Rule
|
||||
public MockitoRule mockitoRule = MockitoJUnit.rule();
|
||||
|
||||
@Before
|
||||
public void init() throws IOException {
|
||||
Mockito.when(servletResponse.getOutputStream()).thenReturn(servletOutputStream);
|
||||
|
||||
requestDetails = new ServletRequestDetails();
|
||||
requestDetails.setServer(server);
|
||||
requestDetails.setServletResponse(servletResponse);
|
||||
response = new ServletRestfulResponse(requestDetails);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addMultipleHeaderValues() throws IOException {
|
||||
final ServletRestfulResponse response = new ServletRestfulResponse(requestDetails);
|
||||
response.addHeader("Authorization", "Basic");
|
||||
response.addHeader("Authorization", "Bearer");
|
||||
response.addHeader("Cache-Control", "no-cache, no-store");
|
||||
|
||||
response.getResponseWriter(200, "Status", "text/plain", "UTF-8", false);
|
||||
|
||||
final InOrder orderVerifier = Mockito.inOrder(servletResponse);
|
||||
orderVerifier.verify(servletResponse).setHeader(eq("Authorization"), eq("Basic"));
|
||||
orderVerifier.verify(servletResponse).addHeader(eq("Authorization"), eq("Bearer"));
|
||||
verify(servletResponse).setHeader(eq("Cache-Control"), eq("no-cache, no-store"));
|
||||
}
|
||||
}
|
|
@ -2651,6 +2651,11 @@ public class GenericClientDstu2Test {
|
|||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFormatParamStyle(RequestFormatParamStyleEnum theRequestFormatParamStyle) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public EncodingEnum getEncoding() {
|
||||
// TODO Auto-generated method stub
|
||||
|
|
|
@ -5,7 +5,12 @@ import static org.junit.Assert.assertThat;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections.Transformer;
|
||||
import org.apache.commons.collections.map.LazyMap;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
||||
import org.hl7.fhir.dstu3.model.Coding;
|
||||
|
@ -28,6 +33,8 @@ import org.junit.AfterClass;
|
|||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.thymeleaf.messageresolver.StandardMessageResolver;
|
||||
import org.thymeleaf.templateresource.ITemplateResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
@ -77,6 +84,52 @@ public class DefaultThymeleafNarrativeGeneratorDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTranslations() throws DataFormatException {
|
||||
CustomThymeleafNarrativeGenerator customGen = new CustomThymeleafNarrativeGenerator("classpath:/testnarrative.properties");
|
||||
customGen.setIgnoreFailures(false);
|
||||
customGen.setIgnoreMissingTemplates(false);
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
ctx.setNarrativeGenerator(customGen);
|
||||
|
||||
Patient value = new Patient();
|
||||
|
||||
value.addIdentifier().setSystem("urn:names").setValue("123456");
|
||||
value.addName().setFamily("blow").addGiven("joe").addGiven((String) null).addGiven("john");
|
||||
//@formatter:off
|
||||
value.addAddress()
|
||||
.addLine("123 Fake Street").addLine("Unit 1")
|
||||
.setCity("Toronto").setState("ON").setCountry("Canada");
|
||||
//@formatter:on
|
||||
|
||||
value.setBirthDate(new Date());
|
||||
|
||||
Transformer transformer = new Transformer() {
|
||||
|
||||
@Override
|
||||
public Object transform(Object input) {
|
||||
return "UNTRANSLATED:" + input;
|
||||
}};
|
||||
|
||||
Map translations = new HashMap<>();
|
||||
translations.put("some_text", "Some beautiful proze");
|
||||
|
||||
customGen.setMessageResolver(new StandardMessageResolver() {
|
||||
@Override
|
||||
protected Map<String, String> resolveMessagesForTemplate(String template,
|
||||
ITemplateResource templateResource, Locale locale) {
|
||||
return LazyMap.decorate(translations, transformer);
|
||||
}
|
||||
});
|
||||
|
||||
Narrative narrative = new Narrative();
|
||||
customGen.generateNarrative(ctx, value, narrative);
|
||||
String output = narrative.getDiv().getValueAsString();
|
||||
ourLog.info(output);
|
||||
assertThat(output, StringContains.containsString("Some beautiful proze"));
|
||||
assertThat(output, StringContains.containsString("UNTRANSLATED:other_text"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateDiagnosticReport() throws DataFormatException {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<div>
|
||||
<p th:text="#{some_text}">Some Text</p>
|
||||
<p th:text="#{other_text}">Some Text</p>
|
||||
</div>
|
|
@ -0,0 +1,2 @@
|
|||
patient.class=org.hl7.fhir.dstu3.model.Patient
|
||||
patient.narrative=classpath:/TestPatient.html
|
|
@ -1,17 +1,13 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
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.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RequestFormatParamStyleEnum;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.util.RandomServerPortProvider;
|
||||
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.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
|
@ -20,9 +16,7 @@ import org.junit.AfterClass;
|
|||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -40,8 +34,9 @@ public class ClientHeadersR4Test {
|
|||
private static Server ourServer;
|
||||
private static String ourServerBase;
|
||||
private static HashMap<String, List<String>> ourHeaders;
|
||||
private static IGenericClient ourClient;
|
||||
private static HashMap<String, String[]> ourParams;
|
||||
private static String ourMethod;
|
||||
private IGenericClient myClient;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
@ -49,34 +44,125 @@ public class ClientHeadersR4Test {
|
|||
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
|
||||
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();
|
||||
resp1.setActive(true);
|
||||
|
||||
MethodOutcome resp = ourClient.create().resource(resp1).execute();
|
||||
MethodOutcome resp = myClient.create().resource(resp1).execute();
|
||||
|
||||
assertNotNull(resp);
|
||||
assertEquals(1, ourHeaders.get(Constants.HEADER_CONTENT_TYPE).size());
|
||||
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
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
@ -94,7 +180,6 @@ public class ClientHeadersR4Test {
|
|||
|
||||
ourServerBase = "http://localhost:" + myPort + "/fhir/context";
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,41 +1,45 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
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.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
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 java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
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.*;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.junit.*;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.client.api.*;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class OperationClientR4Test {
|
||||
|
||||
|
@ -48,13 +52,6 @@ public class OperationClientR4Test {
|
|||
private ArgumentCaptor<HttpUriRequest> capt;
|
||||
private IGenericClient ourGenClient;
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
ourCtx = FhirContext.forR4();
|
||||
|
@ -64,7 +61,7 @@ public class OperationClientR4Test {
|
|||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
|
||||
ourHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
|
||||
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setName("FOO");
|
||||
final String retVal = ourCtx.newXmlParser().encodeResourceToString(outParams);
|
||||
|
@ -75,7 +72,7 @@ public class OperationClientR4Test {
|
|||
when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
public InputStream answer(InvocationOnMock theInvocation) {
|
||||
return new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
@ -95,10 +92,10 @@ public class OperationClientR4Test {
|
|||
.execute();
|
||||
Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val"));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
|
||||
|
||||
HttpPost value = (HttpPost) capt.getAllValues().get(0);
|
||||
String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent(), Charsets.UTF_8);
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
String requestBody = IOUtils.toString(value.getEntity().getContent(), Charsets.UTF_8);
|
||||
IOUtils.closeQuietly(value.getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$nonrepeating", value.getURI().toASCIIString());
|
||||
|
@ -110,7 +107,7 @@ public class OperationClientR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testNonRepeatingGenericUsingUrl() throws Exception {
|
||||
public void testNonRepeatingGenericUsingUrl() {
|
||||
ourGenClient
|
||||
.operation()
|
||||
.onServer()
|
||||
|
@ -121,14 +118,31 @@ public class OperationClientR4Test {
|
|||
.execute();
|
||||
Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val"));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
|
||||
|
||||
HttpGet value = (HttpGet) capt.getAllValues().get(0);
|
||||
assertEquals("http://foo/$nonrepeating?valstr=str&valtok=sys2%7Cval2", value.getURI().toASCIIString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonRepeatingGenericUsingUrl2() {
|
||||
ourGenClient
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("nonrepeating")
|
||||
.withParameters(new Parameters())
|
||||
.andSearchParameter("valstr", new StringParam("str"))
|
||||
.andSearchParameter("valtok", new TokenParam("sys2", "val2"))
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val"));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
|
||||
HttpGet value = (HttpGet) capt.getAllValues().get(0);
|
||||
assertEquals("http://foo/$nonrepeating?valstr=str&valtok=sys2%7Cval2", value.getURI().toASCIIString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationOnInstanceWithIncompleteInstanceId() throws Exception {
|
||||
public void testOperationOnInstanceWithIncompleteInstanceId() {
|
||||
try {
|
||||
ourGenClient
|
||||
.operation()
|
||||
|
@ -146,10 +160,10 @@ public class OperationClientR4Test {
|
|||
public void testNonRepeatingUsingParameters() throws Exception {
|
||||
Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val"));
|
||||
assertEquals("FOO", response.getParameter().get(0).getName());
|
||||
|
||||
|
||||
HttpPost value = (HttpPost) capt.getAllValues().get(0);
|
||||
String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent(), Charsets.UTF_8);
|
||||
IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent());
|
||||
String requestBody = IOUtils.toString(value.getEntity().getContent(), Charsets.UTF_8);
|
||||
IOUtils.closeQuietly(value.getEntity().getContent());
|
||||
ourLog.info(requestBody);
|
||||
Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody);
|
||||
assertEquals("http://foo/$nonrepeating", value.getURI().toASCIIString());
|
||||
|
@ -160,48 +174,52 @@ public class OperationClientR4Test {
|
|||
assertEquals("sys|val", ((StringType) request.getParameter().get(1).getValue()).getValue());
|
||||
}
|
||||
|
||||
|
||||
public interface IOpClient extends IBasicClient {
|
||||
public interface IOpClient extends IBasicClient {
|
||||
|
||||
@Operation(name = "$andlist", idempotent = true)
|
||||
public Parameters andlist(
|
||||
//@formatter:off
|
||||
@OperationParam(name="valstr", max=10) StringAndListParam theValStr,
|
||||
@OperationParam(name="valtok", max=10) TokenAndListParam theValTok
|
||||
//@formatter:on
|
||||
Parameters andlist(
|
||||
//@formatter:off
|
||||
@OperationParam(name = "valstr", max = 10) StringAndListParam theValStr,
|
||||
@OperationParam(name = "valtok", max = 10) TokenAndListParam theValTok
|
||||
//@formatter:on
|
||||
);
|
||||
|
||||
@Operation(name = "$andlist-withnomax", idempotent = true)
|
||||
public Parameters andlistWithNoMax(
|
||||
//@formatter:off
|
||||
@OperationParam(name="valstr") StringAndListParam theValStr,
|
||||
@OperationParam(name="valtok") TokenAndListParam theValTok
|
||||
//@formatter:on
|
||||
Parameters andlistWithNoMax(
|
||||
//@formatter:off
|
||||
@OperationParam(name = "valstr") StringAndListParam theValStr,
|
||||
@OperationParam(name = "valtok") TokenAndListParam theValTok
|
||||
//@formatter:on
|
||||
);
|
||||
|
||||
@Operation(name = "$nonrepeating", idempotent = true)
|
||||
public Parameters nonrepeating(
|
||||
//@formatter:off
|
||||
@OperationParam(name="valstr") StringParam theValStr,
|
||||
@OperationParam(name="valtok") TokenParam theValTok
|
||||
//@formatter:on
|
||||
Parameters nonrepeating(
|
||||
//@formatter:off
|
||||
@OperationParam(name = "valstr") StringParam theValStr,
|
||||
@OperationParam(name = "valtok") TokenParam theValTok
|
||||
//@formatter:on
|
||||
);
|
||||
|
||||
@Operation(name = "$orlist", idempotent = true)
|
||||
public Parameters orlist(
|
||||
//@formatter:off
|
||||
@OperationParam(name="valstr", max=10) List<StringOrListParam> theValStr,
|
||||
@OperationParam(name="valtok", max=10) List<TokenOrListParam> theValTok
|
||||
//@formatter:on
|
||||
Parameters orlist(
|
||||
//@formatter:off
|
||||
@OperationParam(name = "valstr", max = 10) List<StringOrListParam> theValStr,
|
||||
@OperationParam(name = "valtok", max = 10) List<TokenOrListParam> theValTok
|
||||
//@formatter:on
|
||||
);
|
||||
|
||||
@Operation(name = "$orlist-withnomax", idempotent = true)
|
||||
public Parameters orlistWithNoMax(
|
||||
//@formatter:off
|
||||
@OperationParam(name="valstr") List<StringOrListParam> theValStr,
|
||||
@OperationParam(name="valtok") List<TokenOrListParam> theValTok
|
||||
//@formatter:on
|
||||
Parameters orlistWithNoMax(
|
||||
//@formatter:off
|
||||
@OperationParam(name = "valstr") List<StringOrListParam> theValStr,
|
||||
@OperationParam(name = "valtok") List<TokenOrListParam> theValTok
|
||||
//@formatter:on
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
}
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -433,6 +433,7 @@
|
|||
</developer>
|
||||
<developer>
|
||||
<id>RuthAlk</id>
|
||||
<name>Ruth Alkema</name>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>Tastelezz</id>
|
||||
|
@ -473,6 +474,10 @@
|
|||
<developer>
|
||||
<id>jbalbien</id>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>volsch</id>
|
||||
<name>Volker Schmidt</name>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
|
|
|
@ -164,6 +164,19 @@
|
|||
now possible to disallow this action, to only allow alphanumeric IDs (the default
|
||||
and only option previously) or allow any IDs including alphanumeric.
|
||||
</action>
|
||||
<action type="add" issue="1103" dev="ruthakm">
|
||||
It is now possible to use your own IMessageResolver instance in the narrative
|
||||
generator. Thanks to Ruth Alkema for the pull request!
|
||||
</action>
|
||||
<action type="fix" issue="1071" dev="volsch">
|
||||
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!
|
||||
</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 version="3.5.0" date="2018-09-17">
|
||||
|
|
Loading…
Reference in New Issue