Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
ed4a506542
|
@ -43,6 +43,7 @@ import org.hl7.fhir.instance.model.api.IBaseBundle;
|
|||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -169,7 +170,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BaseConformance conformance() {
|
||||
public IBaseConformance conformance() {
|
||||
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||
throw new IllegalArgumentException("Must call fetchConformance() instead of conformance() for RI/DSTU3+ structures");
|
||||
}
|
||||
|
@ -183,7 +184,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
Class<BaseConformance> conformance = (Class<BaseConformance>) myContext.getResourceDefinition("Conformance").getImplementingClass();
|
||||
|
||||
ResourceResponseHandler<? extends BaseConformance> binding = new ResourceResponseHandler<BaseConformance>(conformance);
|
||||
BaseConformance resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
|
||||
IBaseConformance resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse);
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
@ -2325,7 +2326,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
public MethodOutcome execute() {
|
||||
BaseHttpClientInvocation invocation = ValidateMethodBindingDstu2.createValidateInvocation(myContext, myResource);
|
||||
ResourceResponseHandler<BaseOperationOutcome> handler = new ResourceResponseHandler<BaseOperationOutcome>(null, null);
|
||||
BaseOperationOutcome outcome = invoke(null, handler, invocation);
|
||||
IBaseOperationOutcome outcome = invoke(null, handler, invocation);
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
retVal.setOperationOutcome(outcome);
|
||||
return retVal;
|
||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.client;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
|
@ -58,7 +59,7 @@ public interface IGenericClient extends IRestfulClient {
|
|||
* @deprecated Use {@link #fetchConformance()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
BaseConformance conformance();
|
||||
IBaseConformance conformance();
|
||||
|
||||
/**
|
||||
* Fluent method for the "create" operation, which creates a new resource instance on the server
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2016 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 java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.Validate;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.param.ResourceParameter;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
|
||||
public class ValidateMethodBindingDstu3 extends OperationMethodBinding {
|
||||
|
||||
public ValidateMethodBindingDstu3(Class<?> theReturnResourceType, Class<? extends IBaseResource> theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider,
|
||||
Validate theAnnotation) {
|
||||
super(theReturnResourceType, theReturnTypeFromRp, theMethod, theContext, theProvider, true, Constants.EXTOP_VALIDATE, theAnnotation.type(), new OperationParam[0], BundleTypeEnum.COLLECTION);
|
||||
|
||||
List<IParameter> newParams = new ArrayList<IParameter>();
|
||||
int idx = 0;
|
||||
for (IParameter next : getParameters()) {
|
||||
if (next instanceof ResourceParameter) {
|
||||
if (IBaseResource.class.isAssignableFrom(((ResourceParameter) next).getResourceType())) {
|
||||
Class<?> parameterType = theMethod.getParameterTypes()[idx];
|
||||
if (String.class.equals(parameterType) || EncodingEnum.class.equals(parameterType)) {
|
||||
newParams.add(next);
|
||||
} else {
|
||||
OperationParameter parameter = new OperationParameter(theContext, Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_RESOURCE, 0, 1);
|
||||
parameter.initializeTypes(theMethod, null, null, parameterType);
|
||||
newParams.add(parameter);
|
||||
}
|
||||
} else {
|
||||
newParams.add(next);
|
||||
}
|
||||
} else {
|
||||
newParams.add(next);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
setParameters(newParams);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static BaseHttpClientInvocation createValidateInvocation(FhirContext theContext, IBaseResource theResource) {
|
||||
IBaseParameters parameters = (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance();
|
||||
ParametersUtil.addParameterToParameters(theContext, parameters, theResource, "resource");
|
||||
|
||||
String resourceName = theContext.getResourceDefinition(theResource).getName();
|
||||
String resourceId = theResource.getIdElement().getIdPart();
|
||||
|
||||
BaseHttpClientInvocation retVal = createOperationInvocation(theContext, resourceName, resourceId, Constants.EXTOP_VALIDATE, parameters, false);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -151,7 +151,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
* </p>
|
||||
*/
|
||||
public void addHeadersToResponse(HttpServletResponse theHttpResponse) {
|
||||
theHttpResponse.addHeader("X-Powered-By", "HAPI FHIR " + VersionUtil.getVersion() + " RESTful Server");
|
||||
theHttpResponse.addHeader("X-Powered-By", "HAPI FHIR " + VersionUtil.getVersion() + " REST Server (FHIR Server; FHIR " + myFhirContext.getVersion().getVersion().name() + ")");
|
||||
}
|
||||
|
||||
private void addLocationHeader(RequestDetails theRequest, HttpServletResponse theResponse, MethodOutcome response, String headerLocation, String resourceName) {
|
||||
|
@ -570,6 +570,12 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
Map<String, String[]> params = null;
|
||||
if (StringUtils.isNotBlank(theRequest.getQueryString())) {
|
||||
completeUrl = requestUrl + "?" + theRequest.getQueryString();
|
||||
/*
|
||||
* By default, we manually parse the request params (the URL params, or the body for
|
||||
* POST form queries) since Java containers can't be trusted to use UTF-8 encoding
|
||||
* when parsing. Specifically Tomcat 7 and Glassfish 4.0 use 8859-1 for some dumb
|
||||
* reason.... grr.....
|
||||
*/
|
||||
if (isIgnoreServerParsedRequestParameters()) {
|
||||
String contentType = theRequest.getHeader(Constants.HEADER_CONTENT_TYPE);
|
||||
if (theRequestType == RequestTypeEnum.POST && isNotBlank(contentType) && contentType.startsWith(Constants.CT_X_FORM_URLENCODED)) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
|
@ -31,12 +33,10 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.text.StrLookup;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
import org.apache.http.util.EncodingUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -58,15 +58,18 @@ import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
|||
* </tr>
|
||||
* <tr>
|
||||
* <td>${idOrResourceName}</td>
|
||||
* <td>The resource ID associated with this request, or the resource name if the request applies to a type but not an instance, or "" otherwise</td>
|
||||
* <td>The resource ID associated with this request, or the resource name if the request applies to a type but not an
|
||||
* instance, or "" otherwise</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${operationName}</td>
|
||||
* <td>If the request is an extended operation (e.g. "$validate") this value will be the operation name, or "" otherwise</td>
|
||||
* <td>If the request is an extended operation (e.g. "$validate") this value will be the operation name, or ""
|
||||
* otherwise</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${operationType}</td>
|
||||
* <td>A code indicating the operation type for this request, e.g. "read", "history-instance", "extended-operation-instance", etc.)</td>
|
||||
* <td>A code indicating the operation type for this request, e.g. "read", "history-instance",
|
||||
* "extended-operation-instance", etc.)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${remoteAddr}</td>
|
||||
|
@ -74,7 +77,8 @@ import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
|||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestHeader.XXXX}</td>
|
||||
* <td>The value of the HTTP request header named XXXX. For example, a substitution variable named "${requestHeader.x-forwarded-for} will yield the value of the first header named "x-forwarded-for
|
||||
* <td>The value of the HTTP request header named XXXX. For example, a substitution variable named
|
||||
* "${requestHeader.x-forwarded-for} will yield the value of the first header named "x-forwarded-for
|
||||
* ", or "" if none.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
|
@ -83,15 +87,18 @@ import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
|||
* </tr>
|
||||
* <tr>
|
||||
* <td>${responseEncodingNoDefault}</td>
|
||||
* <td>The encoding format requested by the client via the _format parameter or the Accept header. Value will be "json" or "xml", or "" if the client did not explicitly request a format</td>
|
||||
* <td>The encoding format requested by the client via the _format parameter or the Accept header. Value will be "json"
|
||||
* or "xml", or "" if the client did not explicitly request a format</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${servletPath}</td>
|
||||
* <td>The part of thre requesting URL that corresponds to the particular Servlet being called (see {@link HttpServletRequest#getServletPath()})</td>
|
||||
* <td>The part of thre requesting URL that corresponds to the particular Servlet being called (see
|
||||
* {@link HttpServletRequest#getServletPath()})</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestBodyFhir}</td>
|
||||
* <td>The complete body of the request if the request has a FHIR content-type (this can be quite large!). Will emit an empty string if the content type is not a FHIR content type</td>
|
||||
* <td>The complete body of the request if the request has a FHIR content-type (this can be quite large!). Will emit an
|
||||
* empty string if the content type is not a FHIR content type</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestUrl}</td>
|
||||
|
@ -122,10 +129,9 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
public String getErrorMessageFormat() {
|
||||
return myErrorMessageFormat;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
|
||||
throws ServletException, IOException {
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws ServletException, IOException {
|
||||
if (myLogExceptions) {
|
||||
// Perform any string substitutions from the message format
|
||||
StrLookup<?> lookup = new MyLookup(theServletRequest, theException, theRequestDetails);
|
||||
|
@ -187,7 +193,8 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the message format itself. See the {@link LoggingInterceptor class documentation} for information on the format
|
||||
* Sets the message format itself. See the {@link LoggingInterceptor class documentation} for information on the
|
||||
* format
|
||||
*/
|
||||
public void setMessageFormat(String theMessageFormat) {
|
||||
Validate.notBlank(theMessageFormat, "Message format can not be null/empty");
|
||||
|
@ -290,16 +297,18 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
return myRequest.getMethod();
|
||||
} else if (theKey.equals("requestBodyFhir")) {
|
||||
String contentType = myRequest.getContentType();
|
||||
int colonIndex = contentType.indexOf(';');
|
||||
if (colonIndex != -1) {
|
||||
contentType = contentType.substring(0, colonIndex);
|
||||
}
|
||||
contentType = contentType.trim();
|
||||
|
||||
EncodingEnum encoding = EncodingEnum.forContentType(contentType);
|
||||
if (encoding != null) {
|
||||
byte[] requestContents = myRequestDetails.loadRequestContents();
|
||||
return new String(requestContents, Charsets.UTF_8);
|
||||
if (isNotBlank(contentType)) {
|
||||
int colonIndex = contentType.indexOf(';');
|
||||
if (colonIndex != -1) {
|
||||
contentType = contentType.substring(0, colonIndex);
|
||||
}
|
||||
contentType = contentType.trim();
|
||||
|
||||
EncodingEnum encoding = EncodingEnum.forContentType(contentType);
|
||||
if (encoding != null) {
|
||||
byte[] requestContents = myRequestDetails.loadRequestContents();
|
||||
return new String(requestContents, Charsets.UTF_8);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -103,8 +103,10 @@ public class ServletRequestDetails extends RequestDetails {
|
|||
String contentEncoding = myServletRequest.getHeader(Constants.HEADER_CONTENT_ENCODING);
|
||||
if ("gzip".equals(contentEncoding)) {
|
||||
ourLog.debug("Uncompressing (GZip) incoming content");
|
||||
GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(requestContents));
|
||||
requestContents = IOUtils.toByteArray(gis);
|
||||
if (requestContents.length > 0) {
|
||||
GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(requestContents));
|
||||
requestContents = IOUtils.toByteArray(gis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,14 +289,17 @@ public class UrlUtil {
|
|||
if (theString == null) {
|
||||
return null;
|
||||
}
|
||||
if (theString.indexOf('%') == -1) {
|
||||
return theString;
|
||||
}
|
||||
try {
|
||||
return URLDecoder.decode(theString, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error("UTF-8 not supported, this shouldn't happen", e);
|
||||
for (int i = 0; i < theString.length(); i++) {
|
||||
char nextChar = theString.charAt(i);
|
||||
if (nextChar == '%' || nextChar == '+') {
|
||||
try {
|
||||
return URLDecoder.decode(theString, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error("UTF-8 not supported, this shouldn't happen", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return theString;
|
||||
}
|
||||
|
||||
public static class UrlParts {
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.6-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||
<version>1.6-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
|
|
|
@ -39,12 +39,16 @@ import javax.ws.rs.core.MediaType;
|
|||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.dstu3.hapi.rest.server.ServerConformanceProvider;
|
||||
import org.hl7.fhir.dstu3.model.Conformance;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
|
@ -56,7 +60,6 @@ import ca.uhn.fhir.rest.server.IResourceProvider;
|
|||
import ca.uhn.fhir.rest.server.IRestfulResponse;
|
||||
import ca.uhn.fhir.rest.server.ResourceBinding;
|
||||
import ca.uhn.fhir.rest.server.RestulfulServerConfiguration;
|
||||
import ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
|
||||
/**
|
||||
|
@ -78,7 +81,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
private RestulfulServerConfiguration serverConfiguration = new RestulfulServerConfiguration();
|
||||
|
||||
/** the conformance. It is created once during startup */
|
||||
private Conformance myConformance;
|
||||
private Conformance myDstu3Conformance;
|
||||
private ca.uhn.fhir.model.dstu2.resource.Conformance myDstu2Conformance;
|
||||
|
||||
/**
|
||||
* Constructor allowing the description, servername and server to be set
|
||||
|
@ -92,6 +96,21 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
serverConfiguration.setServerName(StringUtils.defaultIfEmpty(serverName, ""));
|
||||
serverConfiguration.setServerVersion(StringUtils.defaultIfEmpty(serverVersion, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor allowing the description, servername and server to be set
|
||||
* @param ctx the {@link FhirContext} instance.
|
||||
* @param implementationDescription the implementation description. If null, "" is used
|
||||
* @param serverName the server name. If null, "" is used
|
||||
* @param serverVersion the server version. If null, "" is used
|
||||
*/
|
||||
protected AbstractJaxRsConformanceProvider(FhirContext ctx, String implementationDescription, String serverName, String serverVersion) {
|
||||
super(ctx);
|
||||
serverConfiguration.setFhirContext(ctx);
|
||||
serverConfiguration.setImplementationDescription(StringUtils.defaultIfEmpty(implementationDescription, ""));
|
||||
serverConfiguration.setServerName(StringUtils.defaultIfEmpty(serverName, ""));
|
||||
serverConfiguration.setServerVersion(StringUtils.defaultIfEmpty(serverVersion, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will set the conformance during the postconstruct phase. The
|
||||
|
@ -112,9 +131,15 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
HardcodedServerAddressStrategy hardcodedServerAddressStrategy = new HardcodedServerAddressStrategy();
|
||||
hardcodedServerAddressStrategy.setValue(getBaseForServer());
|
||||
serverConfiguration.setServerAddressStrategy(hardcodedServerAddressStrategy);
|
||||
ServerConformanceProvider serverConformanceProvider = new ServerConformanceProvider(serverConfiguration);
|
||||
serverConformanceProvider.initializeOperations();
|
||||
myConformance = serverConformanceProvider.getServerConformance(null);
|
||||
if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) {
|
||||
ServerConformanceProvider serverConformanceProvider = new ServerConformanceProvider(serverConfiguration);
|
||||
serverConformanceProvider.initializeOperations();
|
||||
myDstu3Conformance = serverConformanceProvider.getServerConformance(null);
|
||||
} else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) {
|
||||
ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider serverConformanceProvider = new ca.uhn.fhir.rest.server.provider.dstu2.ServerConformanceProvider(serverConfiguration);
|
||||
serverConformanceProvider.initializeOperations();
|
||||
myDstu2Conformance = serverConformanceProvider.getServerConformance(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,7 +170,12 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
Builder request = getRequest(RequestTypeEnum.OPTIONS, RestOperationTypeEnum.METADATA);
|
||||
IRestfulResponse response = request.build().getResponse();
|
||||
response.addHeader(Constants.HEADER_CORS_ALLOW_ORIGIN, "*");
|
||||
return (Response) response.returnResponse(ParseAction.create(myConformance), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName());
|
||||
if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) {
|
||||
return (Response) response.returnResponse(ParseAction.create(myDstu3Conformance), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName());
|
||||
} else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) {
|
||||
return (Response) response.returnResponse(ParseAction.create(myDstu2Conformance), Constants.STATUS_HTTP_200_OK, true, null, getResourceType().getSimpleName());
|
||||
}
|
||||
return (Response) response.returnResponse(null, Constants.STATUS_HTTP_500_INTERNAL_ERROR, true, null, getResourceType().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,9 +247,15 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
return count;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<Conformance> getResourceType() {
|
||||
return Conformance.class;
|
||||
public Class<IBaseResource> getResourceType() {
|
||||
if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) {
|
||||
return Class.class.cast(Conformance.class);
|
||||
} else if (super.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) {
|
||||
return Class.class.cast(ca.uhn.fhir.model.dstu2.resource.Conformance.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import javax.ws.rs.QueryParam;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsResponseException;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
|
@ -65,6 +66,19 @@ public abstract class AbstractJaxRsPageProvider extends AbstractJaxRsProvider im
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the ability to set the {@link FhirContext} instance.
|
||||
* @param ctx the {@link FhirContext} instance.
|
||||
*/
|
||||
protected AbstractJaxRsPageProvider(FhirContext ctx) {
|
||||
super(ctx);
|
||||
try {
|
||||
myBinding = new PageMethodBinding(getFhirContext(), PageProvider.class.getMethod("getPage"));
|
||||
} catch (Exception e) {
|
||||
throw new ca.uhn.fhir.context.ConfigurationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseForRequest() {
|
||||
try {
|
||||
|
|
|
@ -53,8 +53,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
*/
|
||||
public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
|
||||
|
||||
/** a static initialization for the fhircontext. Only DSTU2 is supported */
|
||||
private static final FhirContext CTX = FhirContext.forDstu2();
|
||||
private final FhirContext CTX;
|
||||
|
||||
/** the uri info */
|
||||
@Context
|
||||
|
@ -67,7 +66,22 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
|
|||
public FhirContext getFhirContext() {
|
||||
return CTX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default is DSTU2. Use {@link AbstractJaxRsProvider#AbstractJaxRsProvider(FhirContext)} to specify a DSTU3 context.
|
||||
*/
|
||||
protected AbstractJaxRsProvider() {
|
||||
CTX = FhirContext.forDstu2();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ctx the {@link FhirContext} to support.
|
||||
*/
|
||||
protected AbstractJaxRsProvider(FhirContext ctx) {
|
||||
CTX = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the query parameters
|
||||
* @return the query parameters
|
||||
|
|
|
@ -22,8 +22,6 @@ package ca.uhn.fhir.jaxrs.server;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.interceptor.Interceptors;
|
||||
import javax.ws.rs.Consumes;
|
||||
|
@ -37,12 +35,14 @@ import javax.ws.rs.Produces;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsResponseException;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsMethodBindings;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
|
@ -51,7 +51,6 @@ import ca.uhn.fhir.rest.server.Constants;
|
|||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.IRestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
|
||||
/**
|
||||
* This server is the abstract superclass for all resource providers. It exposes
|
||||
|
@ -62,7 +61,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
@Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON,
|
||||
Constants.CT_FHIR_XML })
|
||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||
public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends AbstractJaxRsProvider
|
||||
public abstract class AbstractJaxRsResourceProvider<R extends IBaseResource> extends AbstractJaxRsProvider
|
||||
implements IRestfulServer<JaxRsRequest>, IResourceProvider {
|
||||
|
||||
/** the method bindings for this class */
|
||||
|
@ -73,9 +72,19 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
|||
* being constructed.
|
||||
*/
|
||||
protected AbstractJaxRsResourceProvider() {
|
||||
super();
|
||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the ability to specify the {@link FhirContext}.
|
||||
* @param ctx the {@link FhirContext} instance.
|
||||
*/
|
||||
protected AbstractJaxRsResourceProvider(FhirContext ctx) {
|
||||
super(ctx);
|
||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor takes in an explicit interface class. This subclass
|
||||
* should be identical to the class being constructed but is given
|
||||
|
@ -85,9 +94,24 @@ public abstract class AbstractJaxRsResourceProvider<R extends IResource> extends
|
|||
* @param theProviderClass the interface of the class
|
||||
*/
|
||||
protected AbstractJaxRsResourceProvider(Class<? extends AbstractJaxRsProvider> theProviderClass) {
|
||||
super();
|
||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, theProviderClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor takes in an explicit interface class. This subclass
|
||||
* should be identical to the class being constructed but is given
|
||||
* explicitly in order to avoid issues with proxy classes in a jee
|
||||
* environment.
|
||||
*
|
||||
* @param ctx the {@link FhirContext} instance.
|
||||
* @param theProviderClass the interface of the class
|
||||
*/
|
||||
protected AbstractJaxRsResourceProvider(FhirContext ctx, Class<? extends AbstractJaxRsProvider> theProviderClass) {
|
||||
super(ctx);
|
||||
theBindings = JaxRsMethodBindings.getMethodBindings(this, theProviderClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* The base for request for a resource provider has the following form:</br>
|
||||
* {@link AbstractJaxRsResourceProvider#getBaseForServer()
|
||||
|
|
|
@ -31,7 +31,9 @@ import javax.ws.rs.core.HttpHeaders;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsProvider;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
|
@ -129,18 +131,33 @@ public class JaxRsRequest extends RequestDetails {
|
|||
throw new InvalidRequestException("Don't know how to handle request path: "
|
||||
+ myServer.getUriInfo().getRequestUri().toASCIIString());
|
||||
}
|
||||
|
||||
FhirVersionEnum fhirContextVersion = myServer.getFhirContext().getVersion().getVersion();
|
||||
|
||||
if (StringUtils.isNotBlank(myVersion)) {
|
||||
result.setId(
|
||||
new IdDt(myServer.getBaseForRequest(), UrlUtil.unescape(myId), UrlUtil.unescape(myVersion)));
|
||||
if (FhirVersionEnum.DSTU3.equals(fhirContextVersion)) {
|
||||
result.setId(
|
||||
new IdType(myServer.getBaseForRequest(), UrlUtil.unescape(myId), UrlUtil.unescape(myVersion)));
|
||||
} else if (FhirVersionEnum.DSTU2.equals(fhirContextVersion)) {
|
||||
result.setId(
|
||||
new IdDt(myServer.getBaseForRequest(), UrlUtil.unescape(myId), UrlUtil.unescape(myVersion)));
|
||||
}
|
||||
} else if (StringUtils.isNotBlank(myId)) {
|
||||
result.setId(new IdDt(myServer.getBaseForRequest(), UrlUtil.unescape(myId)));
|
||||
if (FhirVersionEnum.DSTU3.equals(fhirContextVersion)) {
|
||||
result.setId(new IdType(myServer.getBaseForRequest(), UrlUtil.unescape(myId)));
|
||||
} else if (FhirVersionEnum.DSTU2.equals(fhirContextVersion)) {
|
||||
result.setId(new IdDt(myServer.getBaseForRequest(), UrlUtil.unescape(myId)));
|
||||
}
|
||||
}
|
||||
|
||||
if (myRestOperation == RestOperationTypeEnum.UPDATE) {
|
||||
String contentLocation = result.getHeader(Constants.HEADER_CONTENT_LOCATION);
|
||||
if (contentLocation != null) {
|
||||
result.setId(new IdDt(contentLocation));
|
||||
if (FhirVersionEnum.DSTU3.equals(fhirContextVersion)) {
|
||||
result.setId(new IdType(contentLocation));
|
||||
} else if (FhirVersionEnum.DSTU2.equals(fhirContextVersion)) {
|
||||
result.setId(new IdDt(contentLocation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,110 @@
|
|||
package ca.uhn.fhir.jaxrs.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.glassfish.jersey.internal.MapPropertiesDelegate;
|
||||
import org.glassfish.jersey.server.ContainerRequest;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu3;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
public class AbstractJaxRsConformanceProviderDstu3Test {
|
||||
|
||||
private static final String BASEURI = "http://basiuri";
|
||||
private static final String REQUESTURI = BASEURI + "/metadata";
|
||||
AbstractJaxRsConformanceProvider provider;
|
||||
private ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> providers;
|
||||
private ContainerRequest headers;
|
||||
private MultivaluedHashMap<String, String> queryParameters;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// headers
|
||||
headers = new ContainerRequest(new URI(BASEURI), new URI(REQUESTURI), HttpMethod.GET, null,
|
||||
new MapPropertiesDelegate());
|
||||
// uri info
|
||||
queryParameters = new MultivaluedHashMap<String, String>();
|
||||
|
||||
|
||||
providers = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
|
||||
provider = createConformanceProvider(providers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConformance() throws Exception {
|
||||
providers.put(AbstractJaxRsConformanceProvider.class, provider);
|
||||
providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider());
|
||||
Response response = createConformanceProvider(providers).conformance();
|
||||
System.out.println(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConformanceUsingOptions() throws Exception {
|
||||
providers.put(AbstractJaxRsConformanceProvider.class, provider);
|
||||
providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider());
|
||||
Response response = createConformanceProvider(providers).conformanceUsingOptions();
|
||||
System.out.println(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConformanceWithMethods() throws Exception {
|
||||
providers.put(AbstractJaxRsConformanceProvider.class, provider);
|
||||
providers.put(TestJaxRsMockPatientRestProviderDstu3.class, new TestJaxRsMockPatientRestProviderDstu3());
|
||||
Response response = createConformanceProvider(providers).conformance();
|
||||
assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus());
|
||||
assertTrue(response.getEntity().toString().contains("\"type\":\"Patient\""));
|
||||
assertTrue(response.getEntity().toString().contains("\"$someCustomOperation"));
|
||||
System.out.println(response);
|
||||
System.out.println(response.getEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConformanceInXml() throws Exception {
|
||||
queryParameters.put(Constants.PARAM_FORMAT, Arrays.asList(Constants.CT_XML));
|
||||
providers.put(AbstractJaxRsConformanceProvider.class, provider);
|
||||
providers.put(TestJaxRsMockPatientRestProviderDstu3.class, new TestJaxRsMockPatientRestProviderDstu3());
|
||||
Response response = createConformanceProvider(providers).conformance();
|
||||
assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatus());
|
||||
System.out.println(response.getEntity());
|
||||
assertTrue(response.getEntity().toString().contains(" <type value=\"Patient\"/>"));
|
||||
assertTrue(response.getEntity().toString().contains("\"$someCustomOperation"));
|
||||
System.out.println(response.getEntity());
|
||||
}
|
||||
|
||||
private AbstractJaxRsConformanceProvider createConformanceProvider(final ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> providers)
|
||||
throws Exception {
|
||||
AbstractJaxRsConformanceProvider result = new AbstractJaxRsConformanceProvider(FhirContext.forDstu3(), null, null, null) {
|
||||
@Override
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() {
|
||||
return providers;
|
||||
}
|
||||
};
|
||||
// mocks
|
||||
UriInfo uriInfo = mock(UriInfo.class);
|
||||
when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
|
||||
when(uriInfo.getBaseUri()).thenReturn(new URI(BASEURI));
|
||||
when(uriInfo.getRequestUri()).thenReturn(new URI(BASEURI + "/foo"));
|
||||
result.setUriInfo(uriInfo);
|
||||
result.setHeaders(headers);
|
||||
result.setUpPostConstruct();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,443 @@
|
|||
package ca.uhn.fhir.jaxrs.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu3.model.Conformance;
|
||||
import org.hl7.fhir.dstu3.model.DateType;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Identifier;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.Resource;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Matchers;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.client.JaxRsRestfulClientFactory;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsResponseException;
|
||||
import ca.uhn.fhir.jaxrs.server.test.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsConformanceRestProviderDstu3;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPageProviderDstu3;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu3;
|
||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.method.SearchStyleEnum;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class AbstractJaxRsResourceProviderDstu3Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(AbstractJaxRsResourceProviderDstu3Test.class);
|
||||
private static IGenericClient client;
|
||||
|
||||
|
||||
private static final FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static final String PATIENT_NAME = "Van Houte";
|
||||
|
||||
private static int ourPort;
|
||||
private static String serverBase;
|
||||
private static Server jettyServer;
|
||||
private TestJaxRsMockPatientRestProviderDstu3 mock;
|
||||
private ArgumentCaptor<IdType> idCaptor;
|
||||
private ArgumentCaptor<Patient> patientCaptor;
|
||||
|
||||
private void compareResultId(int id, IBaseResource resource) {
|
||||
assertEquals(id, Integer.parseInt(resource.getIdElement().getIdPart()));
|
||||
}
|
||||
|
||||
private void compareResultUrl(String url, IBaseResource resource) {
|
||||
assertEquals(url, resource.getIdElement().getValueAsString().substring(serverBase.length() - 1));
|
||||
}
|
||||
|
||||
private Patient createPatient(long id) {
|
||||
Patient theResource = new Patient();
|
||||
theResource.setId(new IdType(id));
|
||||
return theResource;
|
||||
}
|
||||
|
||||
private List<Patient> createPatients(int firstId, int lastId) {
|
||||
List<Patient> result = new ArrayList<Patient>(lastId - firstId);
|
||||
for (long i = firstId; i <= lastId; i++) {
|
||||
result.add(createPatient(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Find By Id */
|
||||
@Test
|
||||
public void findUsingGenericClientById() {
|
||||
when(mock.find(any(IdType.class))).thenReturn(createPatient(1));
|
||||
Patient result = client.read(Patient.class, "1");
|
||||
compareResultId(1, result);
|
||||
compareResultUrl("/Patient/1", result);
|
||||
reset(mock);
|
||||
when(mock.find(eq(result.getIdElement()))).thenReturn(createPatient(1));
|
||||
result = (Patient) client.read(new UriDt(result.getId()));
|
||||
compareResultId(1, result);
|
||||
compareResultUrl("/Patient/1", result);
|
||||
}
|
||||
|
||||
private Bundle getPatientBundle(int size) {
|
||||
Bundle result = new Bundle();
|
||||
for (long i = 0; i < size; i++) {
|
||||
Patient patient = createPatient(i);
|
||||
BundleEntryComponent entry = new BundleEntryComponent();
|
||||
entry.setResource(patient);
|
||||
result.addEntry(entry);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.mock = TestJaxRsMockPatientRestProviderDstu3.mock;
|
||||
idCaptor = ArgumentCaptor.forClass(IdType.class);
|
||||
patientCaptor = ArgumentCaptor.forClass(Patient.class);
|
||||
reset(mock);
|
||||
}
|
||||
|
||||
/** Conditional Creates */
|
||||
@Test
|
||||
public void testConditionalCreate() throws Exception {
|
||||
Patient toCreate = createPatient(1);
|
||||
MethodOutcome outcome = new MethodOutcome();
|
||||
toCreate.getIdentifier().add(new Identifier().setValue("myIdentifier"));
|
||||
outcome.setResource(toCreate);
|
||||
|
||||
when(mock.create(patientCaptor.capture(), eq("Patient?_format=json&identifier=2"))).thenReturn(outcome);
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
|
||||
MethodOutcome response = client.create().resource(toCreate).conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().identifier("2")).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
|
||||
assertEquals("myIdentifier", patientCaptor.getValue().getIdentifier().get(0).getValue());
|
||||
IBaseResource resource = response.getResource();
|
||||
compareResultId(1, resource);
|
||||
}
|
||||
|
||||
/** Conformance - Server */
|
||||
@Test
|
||||
public void testConformance() {
|
||||
final Conformance conf = client.fetchConformance().ofType(Conformance.class).execute();
|
||||
assertEquals(conf.getRest().get(0).getResource().get(0).getType().toString(), "Patient");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePatient() throws Exception {
|
||||
Patient toCreate = createPatient(1);
|
||||
MethodOutcome outcome = new MethodOutcome();
|
||||
toCreate.getIdentifier().add(new Identifier().setValue("myIdentifier"));
|
||||
outcome.setResource(toCreate);
|
||||
|
||||
when(mock.create(patientCaptor.capture(), isNull(String.class))).thenReturn(outcome);
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
final MethodOutcome response = client.create().resource(toCreate).prefer(PreferReturnEnum.REPRESENTATION)
|
||||
.execute();
|
||||
IBaseResource resource = (IBaseResource) response.getResource();
|
||||
compareResultId(1, resource);
|
||||
assertEquals("myIdentifier", patientCaptor.getValue().getIdentifier().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletePatient() {
|
||||
when(mock.delete(idCaptor.capture())).thenReturn(new MethodOutcome());
|
||||
final BaseOperationOutcome results = client.delete().resourceById("Patient", "1").execute();
|
||||
assertEquals("1", idCaptor.getValue().getIdPart());
|
||||
}
|
||||
|
||||
/** Extended Operations */
|
||||
@Test
|
||||
public void testExtendedOperations() {
|
||||
// prepare mock
|
||||
Parameters resultParameters = new Parameters();
|
||||
resultParameters.addParameter().setName("return").setResource(createPatient(1)).setValue(new StringType("outputValue"));
|
||||
when(mock.someCustomOperation(any(IdType.class), argThat(new StringTypeMatcher(new StringType("myAwesomeDummyValue"))))).thenReturn(resultParameters);
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateType("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateType("2015-03-01"));
|
||||
inParams.addParameter().setName("dummy").setValue(new StringType("myAwesomeDummyValue"));
|
||||
//invoke
|
||||
Parameters outParams = client.operation().onInstance(new IdType("Patient", "1")).named("$someCustomOperation")
|
||||
.withParameters(inParams).execute();
|
||||
//verify
|
||||
assertEquals("outputValue", ((StringType)outParams.getParameter().get(0).getValue()).getValueAsString());
|
||||
}
|
||||
|
||||
class StringTypeMatcher extends ArgumentMatcher<StringType> {
|
||||
private StringType myStringType;
|
||||
|
||||
public StringTypeMatcher(StringType stringType) {
|
||||
myStringType = stringType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object argument) {
|
||||
return myStringType.getValue().equals(((StringType)argument).getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtendedOperationsUsingGet() {
|
||||
// prepare mock
|
||||
Parameters resultParameters = new Parameters();
|
||||
resultParameters.addParameter().setName("return").setResource(createPatient(1)).setValue(new StringType("outputValue"));
|
||||
when(mock.someCustomOperation(any(IdType.class), argThat(new StringTypeMatcher(new StringType("myAwesomeDummyValue"))))).thenReturn(resultParameters);
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateType("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateType("2015-03-01"));
|
||||
inParams.addParameter().setName("dummy").setValue(new StringType("myAwesomeDummyValue"));
|
||||
|
||||
// invoke
|
||||
Parameters outParams = client.operation().onInstance(new IdType("Patient", "1")).named("$someCustomOperation")
|
||||
.withParameters(inParams).useHttpGet().execute();
|
||||
// verify
|
||||
assertEquals("outputValue", ((StringType)outParams.getParameter().get(0).getValue()).getValueAsString());
|
||||
}
|
||||
|
||||
/** Search using other query options */
|
||||
public void testOther() {
|
||||
// missing
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() {
|
||||
when(mock.find(idCaptor.capture())).thenReturn(createPatient(1));
|
||||
final Patient patient = client.read(Patient.class, "1");
|
||||
compareResultId(1, patient);
|
||||
compareResultUrl("/Patient/1", patient);
|
||||
assertEquals("1", idCaptor.getValue().getIdPart());
|
||||
}
|
||||
|
||||
/** Search - Compartments */
|
||||
@Test
|
||||
public void testSearchCompartements() {
|
||||
when(mock.searchCompartment(any(IdType.class))).thenReturn(Arrays.asList((IBaseResource) createPatient(1)));
|
||||
org.hl7.fhir.dstu3.model.Bundle response = client.search().forResource(Patient.class).withIdAndCompartment("1", "Condition")
|
||||
.returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
|
||||
Resource resource = response.getEntry().get(0).getResource();
|
||||
compareResultId(1, resource);
|
||||
compareResultUrl("/Patient/1", resource);
|
||||
}
|
||||
|
||||
/** */
|
||||
@Test
|
||||
public void testSearchPost() {
|
||||
when(mock.search(any(StringParam.class), Matchers.isNull(StringAndListParam.class)))
|
||||
.thenReturn(createPatients(1, 13));
|
||||
org.hl7.fhir.dstu3.model.Bundle result = client.search().forResource("Patient").usingStyle(SearchStyleEnum.POST)
|
||||
.returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
|
||||
Resource resource = result.getEntry().get(0).getResource();
|
||||
compareResultId(1, resource);
|
||||
compareResultUrl("/Patient/1", resource);
|
||||
}
|
||||
|
||||
/** Search/Query - Type */
|
||||
@Test
|
||||
public void testSearchUsingGenericClientBySearch() {
|
||||
// Perform a search
|
||||
when(mock.search(any(StringParam.class), Matchers.isNull(StringAndListParam.class)))
|
||||
.thenReturn(Arrays.asList(createPatient(1)));
|
||||
final Bundle results = client.search().forResource(Patient.class)
|
||||
.where(Patient.NAME.matchesExactly().value(PATIENT_NAME)).returnBundle(Bundle.class).execute();
|
||||
verify(mock).search(any(StringParam.class), Matchers.isNull(StringAndListParam.class));
|
||||
IBaseResource resource = results.getEntry().get(0).getResource();
|
||||
|
||||
compareResultId(1, resource);
|
||||
compareResultUrl("/Patient/1", resource);
|
||||
}
|
||||
|
||||
/** Search - Multi-valued Parameters (ANY/OR) */
|
||||
@Test
|
||||
public void testSearchUsingGenericClientBySearchWithMultiValues() {
|
||||
when(mock.search(any(StringParam.class), Matchers.isNotNull(StringAndListParam.class)))
|
||||
.thenReturn(Arrays.asList(createPatient(1)));
|
||||
final Bundle results = client.search().forResource(Patient.class)
|
||||
.where(Patient.ADDRESS.matches().values("Toronto")).and(Patient.ADDRESS.matches().values("Ontario"))
|
||||
.and(Patient.ADDRESS.matches().values("Canada"))
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("SHORTNAME", "TOYS")).returnBundle(Bundle.class).execute();
|
||||
IBaseResource resource = results.getEntry().get(0).getResource();
|
||||
|
||||
compareResultId(1, resource);
|
||||
compareResultUrl("/Patient/1", resource);
|
||||
}
|
||||
|
||||
/** Search - Paging */
|
||||
@Test
|
||||
public void testSearchWithPaging() {
|
||||
// Perform a search
|
||||
when(mock.search(any(StringParam.class), Matchers.isNull(StringAndListParam.class)))
|
||||
.thenReturn(createPatients(1, 13));
|
||||
final org.hl7.fhir.dstu3.model.Bundle results = client.search().forResource(Patient.class).count(8).returnBundle(org.hl7.fhir.dstu3.model.Bundle.class)
|
||||
.execute();
|
||||
|
||||
assertEquals(results.getEntry().size(), 8);
|
||||
IBaseResource resource = results.getEntry().get(0).getResource();
|
||||
compareResultId(1, resource);
|
||||
compareResultUrl("/Patient/1", resource);
|
||||
compareResultId(8, results.getEntry().get(7).getResource());
|
||||
|
||||
// ourLog.info("Next: " + results.getLink("next").getUrl());
|
||||
// String url = results.getLink("next").getUrl().replace("?", "Patient?");
|
||||
// results.getLink("next").setUrl(url);
|
||||
// ourLog.info("New Next: " + results.getLink("next").getUrl());
|
||||
|
||||
// load next page
|
||||
final org.hl7.fhir.dstu3.model.Bundle nextPage = client.loadPage().next(results).execute();
|
||||
resource = nextPage.getEntry().get(0).getResource();
|
||||
compareResultId(9, resource);
|
||||
compareResultUrl("/Patient/9", resource);
|
||||
assertNull(nextPage.getLink(org.hl7.fhir.dstu3.model.Bundle.LINK_NEXT));
|
||||
}
|
||||
|
||||
/** Search - Subsetting (_summary and _elements) */
|
||||
@Test
|
||||
@Ignore
|
||||
public void testSummary() {
|
||||
Object response = client.search().forResource(Patient.class)
|
||||
.returnBundle(org.hl7.fhir.dstu3.model.Bundle.class).execute();
|
||||
}
|
||||
|
||||
/** Transaction - Server */
|
||||
// @Ignore
|
||||
// @Test
|
||||
// public void testTransaction() {
|
||||
// ca.uhn.fhir.model.api.Bundle bundle = new ca.uhn.fhir.model.api.Bundle();
|
||||
// BundleEntry entry = bundle.addEntry();
|
||||
// final Patient existing = new Patient();
|
||||
// existing.getName().get(0).addFamily("Created with bundle");
|
||||
// entry.setResource(existing);
|
||||
//
|
||||
// BoundCodeDt<BundleEntryTransactionMethodEnum> theTransactionOperation = new BoundCodeDt(
|
||||
// BundleEntryTransactionMethodEnum.VALUESET_BINDER, BundleEntryTransactionMethodEnum.POST);
|
||||
// entry.setTransactionMethod(theTransactionOperation);
|
||||
// ca.uhn.fhir.model.api.Bundle response = client.transaction().withBundle(bundle).execute();
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testUpdateById() throws Exception {
|
||||
when(mock.update(idCaptor.capture(), patientCaptor.capture())).thenReturn(new MethodOutcome());
|
||||
client.update("1", createPatient(1));
|
||||
assertEquals("1", idCaptor.getValue().getIdPart());
|
||||
compareResultId(1, patientCaptor.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Ignore
|
||||
@Test
|
||||
public void testResourceNotFound() throws Exception {
|
||||
when(mock.update(idCaptor.capture(), patientCaptor.capture())).thenThrow(ResourceNotFoundException.class);
|
||||
try {
|
||||
client.update("1", createPatient(2));
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVRead() {
|
||||
when(mock.findHistory(idCaptor.capture())).thenReturn(createPatient(1));
|
||||
final Patient patient = client.vread(Patient.class, "1", "2");
|
||||
compareResultId(1, patient);
|
||||
compareResultUrl("/Patient/1", patient);
|
||||
assertEquals("1", idCaptor.getValue().getIdPart());
|
||||
assertEquals("2", idCaptor.getValue().getVersionIdPart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXFindUnknownPatient() {
|
||||
try {
|
||||
JaxRsResponseException notFoundException = new JaxRsResponseException(new ResourceNotFoundException(new IdType("999955541264")));
|
||||
when(mock.find(idCaptor.capture())).thenThrow(notFoundException);
|
||||
client.read(Patient.class, "999955541264");
|
||||
fail();
|
||||
} catch (final ResourceNotFoundException e) {
|
||||
assertEquals(ResourceNotFoundException.STATUS_CODE, e.getStatusCode());
|
||||
assertTrue(e.getMessage().contains("999955541264"));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
System.out.println(ourPort);
|
||||
jettyServer = new Server(ourPort);
|
||||
jettyServer.setHandler(context);
|
||||
ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
|
||||
jerseyServlet.setInitOrder(0);
|
||||
|
||||
//@formatter:off
|
||||
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",
|
||||
StringUtils.join(Arrays.asList(
|
||||
TestJaxRsMockPatientRestProviderDstu3.class.getCanonicalName(),
|
||||
JaxRsExceptionInterceptor.class.getCanonicalName(),
|
||||
TestJaxRsConformanceRestProviderDstu3.class.getCanonicalName(),
|
||||
TestJaxRsMockPageProviderDstu3.class.getCanonicalName()
|
||||
), ";"));
|
||||
//@formatter:on
|
||||
|
||||
jettyServer.start();
|
||||
|
||||
ourCtx.setRestfulClientFactory(new JaxRsRestfulClientFactory(ourCtx));
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
serverBase = "http://localhost:" + ourPort + "/";
|
||||
client = ourCtx.newRestfulGenericClient(serverBase);
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
try {
|
||||
jettyServer.destroy();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package ca.uhn.fhir.jaxrs.server.test;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsConformanceProvider;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
/**
|
||||
* A conformance provider exposes the mock patient and this provider
|
||||
*/
|
||||
@Path("")
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class TestJaxRsConformanceRestProviderDstu3 extends AbstractJaxRsConformanceProvider {
|
||||
|
||||
public TestJaxRsConformanceRestProviderDstu3() {
|
||||
super(FhirContext.forDstu3(), "description", "name", "version");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() {
|
||||
ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> map = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
|
||||
map.put(TestJaxRsMockPatientRestProviderDstu3.class, new TestJaxRsMockPatientRestProviderDstu3());
|
||||
map.put(TestJaxRsConformanceRestProviderDstu3.class, new TestJaxRsConformanceRestProviderDstu3());
|
||||
return map;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package ca.uhn.fhir.jaxrs.server.test;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||
|
||||
/**
|
||||
* A dummy patient provider exposing no methods
|
||||
*/
|
||||
public class TestJaxRsDummyPatientProviderDstu3 extends AbstractJaxRsResourceProvider<Patient> {
|
||||
|
||||
public TestJaxRsDummyPatientProviderDstu3() {
|
||||
super(FhirContext.forDstu3());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package ca.uhn.fhir.jaxrs.server.test;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsPageProvider;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
|
||||
@Path("/")
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class TestJaxRsMockPageProviderDstu3 extends AbstractJaxRsPageProvider {
|
||||
|
||||
public TestJaxRsMockPageProviderDstu3() {
|
||||
super(FhirContext.forDstu3());
|
||||
}
|
||||
@Override
|
||||
public IPagingProvider getPagingProvider() {
|
||||
return TestJaxRsMockPatientRestProviderDstu3.PAGING_PROVIDER;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package ca.uhn.fhir.jaxrs.server.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.interceptor.Interceptors;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.interceptor.JaxRsExceptionInterceptor;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.Delete;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
|
||||
/**
|
||||
* A test server delegating each call to a mock
|
||||
*/
|
||||
@Path(TestJaxRsMockPatientRestProviderDstu3.PATH)
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
@Interceptors(JaxRsExceptionInterceptor.class)
|
||||
public class TestJaxRsMockPatientRestProviderDstu3 extends AbstractJaxRsResourceProvider<Patient> {
|
||||
|
||||
static final String PATH = "/Patient";
|
||||
|
||||
public static final TestJaxRsMockPatientRestProviderDstu3 mock = Mockito.mock(TestJaxRsMockPatientRestProviderDstu3.class);
|
||||
|
||||
public static final FifoMemoryPagingProvider PAGING_PROVIDER;
|
||||
|
||||
static
|
||||
{
|
||||
PAGING_PROVIDER = new FifoMemoryPagingProvider(10);
|
||||
PAGING_PROVIDER.setDefaultPageSize(10);
|
||||
PAGING_PROVIDER.setMaximumPageSize(100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public TestJaxRsMockPatientRestProviderDstu3() {
|
||||
super(FhirContext.forDstu3());
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name, @RequiredParam(name=Patient.SP_ADDRESS) StringAndListParam theAddressParts) {
|
||||
return mock.search(name, theAddressParts);
|
||||
}
|
||||
|
||||
@Update
|
||||
public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient) throws Exception {
|
||||
return mock.update(theId, patient);
|
||||
}
|
||||
|
||||
@Read
|
||||
public Patient find(@IdParam final IdType theId) {
|
||||
return mock.find(theId);
|
||||
}
|
||||
|
||||
@Read(version = true)
|
||||
public Patient findHistory(@IdParam final IdType theId) {
|
||||
return mock.findHistory(theId);
|
||||
}
|
||||
|
||||
@Create
|
||||
public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional)
|
||||
throws Exception {
|
||||
return mock.create(patient, theConditional);
|
||||
}
|
||||
|
||||
@Delete
|
||||
public MethodOutcome delete(@IdParam final IdType theId) {
|
||||
return mock.delete(theId);
|
||||
}
|
||||
|
||||
@Search(compartmentName = "Condition")
|
||||
public List<IBaseResource> searchCompartment(@IdParam IdType thePatientId) {
|
||||
return mock.searchCompartment(thePatientId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}/$someCustomOperation")
|
||||
public Response someCustomOperationUsingGet(@PathParam("id") String id, String resource) throws Exception {
|
||||
return customOperation(resource, RequestTypeEnum.GET, id, "$someCustomOperation",
|
||||
RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{id}/$someCustomOperation")
|
||||
public Response someCustomOperationUsingPost(@PathParam("id") String id, String resource) throws Exception {
|
||||
return customOperation(resource, RequestTypeEnum.POST, id, "$someCustomOperation",
|
||||
RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||
}
|
||||
|
||||
@Operation(name = "someCustomOperation", idempotent = true, returnParameters = {
|
||||
@OperationParam(name = "return", type = StringType.class) })
|
||||
public Parameters someCustomOperation(@IdParam IdType myId, @OperationParam(name = "dummy") StringType dummyInput) {
|
||||
return mock.someCustomOperation(myId, dummyInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPagingProvider getPagingProvider() {
|
||||
return PAGING_PROVIDER;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package ca.uhn.fhir.jaxrs.server.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.junit.Before;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProviderDstu3;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsMethodBindings;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
|
||||
|
||||
@FixMethodOrder(MethodSorters.DEFAULT)
|
||||
public class JaxRsMethodBindingsDstu3Test {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
JaxRsMethodBindings.getClassBindings().clear();
|
||||
}
|
||||
|
||||
@Test(expected = NotImplementedOperationException.class)
|
||||
public void testFindMethodsForProviderNotDefinedMappingMethods() {
|
||||
new TestJaxRsDummyPatientProviderDstu3().getBindings().getBinding(RestOperationTypeEnum.UPDATE, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindMethodsForProviderWithMethods() {
|
||||
class TestFindPatientProvider extends TestJaxRsDummyPatientProviderDstu3 {
|
||||
@Search
|
||||
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
new TestFindPatientProvider();
|
||||
assertEquals(TestFindPatientProvider.class, new TestFindPatientProvider().getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE, "").getMethod().getDeclaringClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindMethodsFor2ProvidersWithMethods() {
|
||||
class TestFindPatientProvider extends TestJaxRsDummyPatientProviderDstu3 {
|
||||
@Search
|
||||
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
class TestUpdatePatientProvider extends TestJaxRsDummyPatientProviderDstu3 {
|
||||
@Update
|
||||
public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
assertEquals(TestFindPatientProvider.class, new TestFindPatientProvider().getBindings().getBinding(RestOperationTypeEnum.SEARCH_TYPE, "").getMethod().getDeclaringClass());
|
||||
assertEquals(TestUpdatePatientProvider.class, new TestUpdatePatientProvider().getBindings().getBinding(RestOperationTypeEnum.UPDATE, "").getMethod().getDeclaringClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindMethodsWithDoubleMethodsDeclaration() {
|
||||
class TestDoubleSearchProvider extends TestJaxRsDummyPatientProviderDstu3 {
|
||||
@Search
|
||||
public List<Patient> search1(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<Patient> search2(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
new TestDoubleSearchProvider();
|
||||
fail();
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage().contains("search1"));
|
||||
assertTrue(e.getMessage().contains("search2"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindMethodsWithMultipleMethods() {
|
||||
class TestFindPatientProvider extends TestJaxRsDummyPatientProviderDstu3 {
|
||||
@Search
|
||||
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||
return null;
|
||||
}
|
||||
@Update
|
||||
public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient) {
|
||||
return null;
|
||||
}
|
||||
@Operation(name = "firstMethod", idempotent = true, returnParameters = { @OperationParam(name = "return", type = StringType.class) })
|
||||
public Parameters firstMethod(@OperationParam(name = "dummy") StringType dummyInput) {
|
||||
return null;
|
||||
}
|
||||
@Operation(name = "secondMethod", returnParameters = { @OperationParam(name = "return", type = StringType.class) })
|
||||
public Parameters secondMethod(@OperationParam(name = "dummy") StringType dummyInput) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
JaxRsMethodBindings bindings = new TestFindPatientProvider().getBindings();
|
||||
assertEquals("search", bindings.getBinding(RestOperationTypeEnum.SEARCH_TYPE, "").getMethod().getName());
|
||||
assertEquals("update", bindings.getBinding(RestOperationTypeEnum.UPDATE, "").getMethod().getName());
|
||||
assertEquals("firstMethod", bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$firstMethod").getMethod().getName());
|
||||
assertEquals("secondMethod", bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$secondMethod").getMethod().getName());
|
||||
try {
|
||||
bindings.getBinding(RestOperationTypeEnum.EXTENDED_OPERATION_TYPE, "$thirdMethod");
|
||||
fail();
|
||||
} catch(NotImplementedOperationException e){
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package ca.uhn.fhir.jaxrs.server.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.glassfish.jersey.internal.MapPropertiesDelegate;
|
||||
import org.glassfish.jersey.server.ContainerRequest;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProviderDstu3;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsResponse;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
|
||||
public class JaxRsRequestDstu3Test {
|
||||
|
||||
private static final String RESOURCE_STRING = "</Patient>";
|
||||
private static final String BASEURI = "http://baseuri";
|
||||
private static final String REQUESTURI = "http://baseuri/test";
|
||||
|
||||
private JaxRsRequest details;
|
||||
private MultivaluedMap<String, String> queryParameters = new MultivaluedHashMap<String, String>();
|
||||
private ContainerRequest headers;
|
||||
private TestJaxRsDummyPatientProviderDstu3 provider;
|
||||
|
||||
@Before
|
||||
public void setUp() throws URISyntaxException {
|
||||
details = createRequestDetails();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHeader() {
|
||||
String headerKey = "key";
|
||||
String headerValue = "location_value";
|
||||
String headerValue2 = "location_value_2";
|
||||
assertTrue(StringUtils.isBlank(details.getHeader(headerKey)));
|
||||
headers.header(headerKey, headerValue);
|
||||
assertEquals(headerValue, details.getHeader(headerKey));
|
||||
assertEquals(Arrays.asList(headerValue), details.getHeaders(headerKey));
|
||||
|
||||
headers.header(headerKey, headerValue2);
|
||||
assertEquals(headerValue, details.getHeader(headerKey));
|
||||
assertEquals(Arrays.asList(headerValue, headerValue2), details.getHeaders(headerKey));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetByteStreamRequestContents() {
|
||||
assertEquals(RESOURCE_STRING, new String(details.getByteStreamRequestContents()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerBaseForRequest() {
|
||||
assertEquals(BASEURI, new String(details.getServerBaseForRequest()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResponse() {
|
||||
JaxRsResponse response = (JaxRsResponse) details.getResponse();
|
||||
assertEquals(details, response.getRequestDetails());
|
||||
assertTrue(response == details.getResponse());
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void testGetReader() throws IOException {
|
||||
details.getReader();
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void testGetInputStream() {
|
||||
details.getInputStream();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetServerBaseForRequest() {
|
||||
assertEquals(JaxRsRequestDstu3Test.BASEURI, details.getFhirServerBase());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetServer() {
|
||||
assertEquals(this.provider, details.getServer());
|
||||
}
|
||||
|
||||
public JaxRsRequest createRequestDetails() throws URISyntaxException {
|
||||
//headers
|
||||
headers = new ContainerRequest(new URI(BASEURI), new URI(REQUESTURI), HttpMethod.GET, null, new MapPropertiesDelegate());
|
||||
|
||||
//uri info
|
||||
UriInfo uriInfo = mock(UriInfo.class);
|
||||
when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
|
||||
|
||||
//mocks
|
||||
provider = spy(TestJaxRsDummyPatientProviderDstu3.class);
|
||||
doReturn(uriInfo).when(provider).getUriInfo();
|
||||
doReturn(BASEURI).when(provider).getBaseForRequest();
|
||||
doReturn(BASEURI).when(provider).getBaseForServer();
|
||||
doReturn(headers).when(provider).getHeaders();
|
||||
|
||||
return new JaxRsRequest(provider, RESOURCE_STRING, RequestTypeEnum.GET, RestOperationTypeEnum.HISTORY_TYPE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package ca.uhn.fhir.jaxrs.server.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Binary;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
|
||||
import ca.uhn.fhir.jaxrs.server.util.JaxRsResponse;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.method.ParseAction;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
|
||||
public class JaxRsResponseDstu3Test {
|
||||
|
||||
private JaxRsResponse response;
|
||||
private JaxRsRequest request;
|
||||
private Bundle bundle;
|
||||
private Set<SummaryEnum> theSummaryMode;
|
||||
|
||||
@Before
|
||||
public void setUp() throws URISyntaxException {
|
||||
request = new JaxRsRequestDstu3Test().createRequestDetails();
|
||||
this.response = (JaxRsResponse) request.getResponse();
|
||||
bundle = getSinglePatientResource();
|
||||
theSummaryMode = Collections.<SummaryEnum>emptySet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResponseWriterNoZipNoBrowser() throws IOException {
|
||||
boolean theRequestIsBrowser = false;
|
||||
boolean respondGzip = false;
|
||||
Set<SummaryEnum> theSummaryMode = Collections.<SummaryEnum>emptySet();
|
||||
boolean theAddContentLocationHeader = false;
|
||||
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), bundle, theSummaryMode, 200, theAddContentLocationHeader, respondGzip, request);
|
||||
assertEquals(200, result.getStatus());
|
||||
assertEquals(Constants.CT_FHIR_JSON+Constants.CHARSET_UTF8_CTSUFFIX, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
assertTrue(result.getEntity().toString().contains("Patient"));
|
||||
assertTrue(result.getEntity().toString().contains("15"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAttachmentResponse() throws IOException {
|
||||
boolean theRequestIsBrowser = true;
|
||||
boolean respondGzip = true;
|
||||
IBaseBinary binary = new Binary();
|
||||
String contentType = "foo";
|
||||
byte[] content = new byte[] { 1, 2, 3, 4 };
|
||||
binary.setContentType(contentType);
|
||||
binary.setContent(content);
|
||||
boolean theAddContentLocationHeader = false;
|
||||
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theSummaryMode, 200, theAddContentLocationHeader, respondGzip, this.request);
|
||||
assertEquals(200, result.getStatus());
|
||||
assertEquals(contentType, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
assertEquals(content, result.getEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAttachmentResponseNoContent() throws IOException {
|
||||
boolean theRequestIsBrowser = true;
|
||||
boolean respondGzip = true;
|
||||
IBaseBinary binary = new Binary();
|
||||
binary.setContent(new byte[]{});
|
||||
boolean theAddContentLocationHeader = false;
|
||||
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theSummaryMode, 200, theAddContentLocationHeader, respondGzip, this.request);
|
||||
assertEquals(200, result.getStatus());
|
||||
assertEquals(null, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
assertEquals(null, result.getEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAttachmentResponseEmptyContent() throws IOException {
|
||||
boolean theRequestIsBrowser = true;
|
||||
boolean respondGzip = true;
|
||||
IBaseBinary binary = new Binary();
|
||||
boolean theAddContentLocationHeader = false;
|
||||
Response result = (Response) RestfulServerUtils.streamResponseAsResource(request.getServer(), binary, theSummaryMode, 200, theAddContentLocationHeader, respondGzip, this.request);
|
||||
assertEquals(200, result.getStatus());
|
||||
assertEquals(null, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
assertEquals(null, result.getEntity());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReturnResponse() throws IOException {
|
||||
IdType theId = new IdType(15L);
|
||||
ParseAction<?> outcome = ParseAction.create(createPatient());
|
||||
int operationStatus = 200;
|
||||
boolean allowPrefer = true;
|
||||
String resourceName = "Patient";
|
||||
MethodOutcome methodOutcome = new MethodOutcome(theId);
|
||||
Response result = response.returnResponse(outcome, operationStatus, allowPrefer, methodOutcome, resourceName);
|
||||
assertEquals(200, result.getStatus());
|
||||
assertEquals(Constants.CT_JSON+Constants.CHARSET_UTF8_CTSUFFIX, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
System.out.println(result.getEntity().toString());
|
||||
assertTrue(result.getEntity().toString().contains("resourceType\":\"Patient"));
|
||||
assertTrue(result.getEntity().toString().contains("15"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnResponseAsXml() throws IOException {
|
||||
IdType theId = new IdType(15L);
|
||||
ParseAction<?> outcome = ParseAction.create(createPatient());
|
||||
int operationStatus = 200;
|
||||
boolean allowPrefer = true;
|
||||
String resourceName = "Patient";
|
||||
MethodOutcome methodOutcome = new MethodOutcome(theId);
|
||||
response.getRequestDetails().getParameters().put(Constants.PARAM_FORMAT, new String[]{Constants.CT_XML});
|
||||
Response result = response.returnResponse(outcome, operationStatus, allowPrefer, methodOutcome, resourceName);
|
||||
assertEquals(200, result.getStatus());
|
||||
assertEquals(Constants.CT_XML+Constants.CHARSET_UTF8_CTSUFFIX, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
assertTrue(result.getEntity().toString().contains("<Patient"));
|
||||
assertTrue(result.getEntity().toString().contains("15"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoOutcomeXml() throws IOException {
|
||||
ParseAction<?> outcome = ParseAction.create((IBaseResource) null);
|
||||
int operationStatus = Constants.STATUS_HTTP_204_NO_CONTENT;
|
||||
boolean allowPrefer = true;
|
||||
String resourceName = "Patient";
|
||||
MethodOutcome methodOutcome = new MethodOutcome(null);
|
||||
response.getRequestDetails().getParameters().put(Constants.PARAM_FORMAT, new String[]{Constants.CT_XML});
|
||||
Response result = response.returnResponse(outcome, operationStatus, allowPrefer, methodOutcome, resourceName);
|
||||
assertEquals(204, result.getStatus());
|
||||
assertEquals(Constants.CT_XML+Constants.CHARSET_UTF8_CTSUFFIX, result.getHeaderString(Constants.HEADER_CONTENT_TYPE));
|
||||
}
|
||||
|
||||
private Bundle getSinglePatientResource() {
|
||||
Patient theResource = createPatient();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.addEntry().setResource(theResource);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
private Patient createPatient() {
|
||||
Patient theResource = new Patient();
|
||||
theResource.setId(new IdType(15L));
|
||||
return theResource;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package ca.uhn.fhir.jaxrs.server.example;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsConformanceProvider;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
/**
|
||||
* Conformance Rest Service
|
||||
*
|
||||
* @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
|
||||
*/
|
||||
@Path("")
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class JaxRsConformanceProviderDstu3 extends AbstractJaxRsConformanceProvider {
|
||||
private static final String SERVER_VERSION = "1.0.0";
|
||||
private static final String SERVER_DESCRIPTION = "Jax-Rs Test Example Description";
|
||||
private static final String SERVER_NAME = "Jax-Rs Test Example";
|
||||
|
||||
@Inject
|
||||
private JaxRsPatientRestProvider patientProvider;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public JaxRsConformanceProviderDstu3() {
|
||||
super(FhirContext.forDstu3(), SERVER_VERSION, SERVER_DESCRIPTION, SERVER_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() {
|
||||
ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> map = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
|
||||
map.put(JaxRsConformanceProviderDstu3.class, this);
|
||||
map.put(JaxRsPatientRestProvider.class, patientProvider);
|
||||
return map;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package ca.uhn.fhir.jaxrs.server.example;
|
||||
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsPageProvider;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
|
||||
@Path("/")
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class JaxRsPageProviderDstu3 extends AbstractJaxRsPageProvider {
|
||||
|
||||
public JaxRsPageProviderDstu3() {
|
||||
super(FhirContext.forDstu3());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPagingProvider getPagingProvider() {
|
||||
return JaxRsPatientRestProviderDstu3.PAGE_PROVIDER;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
package ca.uhn.fhir.jaxrs.server.example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Condition;
|
||||
import org.hl7.fhir.dstu3.model.HumanName;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.Delete;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
||||
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
|
||||
/**
|
||||
* A demo JaxRs Patient Rest Provider
|
||||
*
|
||||
* @author Peter Van Houte | peter.vanhoute@agfa.com | Agfa Healthcare
|
||||
*/
|
||||
@Local
|
||||
@Path(JaxRsPatientRestProviderDstu3.PATH)
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class JaxRsPatientRestProviderDstu3 extends AbstractJaxRsResourceProvider<Patient> {
|
||||
|
||||
private static Long counter = 1L;
|
||||
|
||||
/**
|
||||
* The HAPI paging provider for this server
|
||||
*/
|
||||
public static final IPagingProvider PAGE_PROVIDER;
|
||||
|
||||
static final String PATH = "/Patient";
|
||||
private static final ConcurrentHashMap<String, List<Patient>> patients = new ConcurrentHashMap<String, List<Patient>>();
|
||||
|
||||
static {
|
||||
PAGE_PROVIDER = new FifoMemoryPagingProvider(10);
|
||||
}
|
||||
|
||||
static {
|
||||
patients.put(String.valueOf(counter), createPatient("Van Houte"));
|
||||
patients.put(String.valueOf(counter), createPatient("Agnew"));
|
||||
for (int i = 0; i < 20; i++) {
|
||||
patients.put(String.valueOf(counter), createPatient("Random Patient " + counter));
|
||||
}
|
||||
}
|
||||
|
||||
public JaxRsPatientRestProviderDstu3() {
|
||||
super(FhirContext.forDstu3(), JaxRsPatientRestProviderDstu3.class);
|
||||
}
|
||||
|
||||
@Create
|
||||
public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional) throws Exception {
|
||||
patients.put("" + counter, createPatient(patient));
|
||||
final MethodOutcome result = new MethodOutcome().setCreated(true);
|
||||
result.setResource(patient);
|
||||
result.setId(new IdType(patient.getId()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Delete
|
||||
public MethodOutcome delete(@IdParam final IdType theId) {
|
||||
final Patient deletedPatient = find(theId);
|
||||
patients.remove(deletedPatient.getIdElement().getIdPart());
|
||||
final MethodOutcome result = new MethodOutcome().setCreated(true);
|
||||
result.setResource(deletedPatient);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Read
|
||||
public Patient find(@IdParam final IdType theId) {
|
||||
if (patients.containsKey(theId.getIdPart())) {
|
||||
return getLast(patients.get(theId.getIdPart()));
|
||||
} else {
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
}
|
||||
|
||||
@Read(version = true)
|
||||
public Patient findHistory(@IdParam final IdType theId) {
|
||||
if (patients.containsKey(theId.getIdPart())) {
|
||||
final List<Patient> list = patients.get(theId.getIdPart());
|
||||
for (final Patient patient : list) {
|
||||
if (patient.getIdElement().getVersionIdPartAsLong().equals(theId.getVersionIdPartAsLong())) {
|
||||
return patient;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
|
||||
@Operation(name = "firstVersion", idempotent = true, returnParameters = { @OperationParam(name = "return", type = StringType.class) })
|
||||
public Parameters firstVersion(@IdParam final IdType theId, @OperationParam(name = "dummy") StringType dummyInput) {
|
||||
Parameters parameters = new Parameters();
|
||||
Patient patient = find(new IdType(theId.getResourceType(), theId.getIdPart(), "0"));
|
||||
parameters.addParameter().setName("return").setResource(patient).setValue(new StringType((counter - 1) + "" + "inputVariable [ " + dummyInput.getValue() + "]"));
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AddProfileTagEnum getAddProfileTag() {
|
||||
return AddProfileTagEnum.NEVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BundleInclusionRule getBundleInclusionRule() {
|
||||
return BundleInclusionRule.BASED_ON_INCLUDES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ETagSupportEnum getETagSupport() {
|
||||
return ETagSupportEnum.DISABLED;
|
||||
}
|
||||
|
||||
/** THE DEFAULTS */
|
||||
|
||||
@Override
|
||||
public List<IServerInterceptor> getInterceptors() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private Patient getLast(final List<Patient> list) {
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPagingProvider getPagingProvider() {
|
||||
return PAGE_PROVIDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultPrettyPrint() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseBrowserFriendlyContentTypes() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}/$firstVersion")
|
||||
public Response operationFirstVersionUsingGet(@PathParam("id") String id) throws IOException {
|
||||
return customOperation(null, RequestTypeEnum.GET, id, "$firstVersion", RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{id}/$firstVersion")
|
||||
public Response operationFirstVersionUsingGet(@PathParam("id") String id, final String resource) throws Exception {
|
||||
return customOperation(resource, RequestTypeEnum.POST, id, "$firstVersion", RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<Patient> search(@RequiredParam(name = Patient.SP_NAME) final StringParam name) {
|
||||
final List<Patient> result = new LinkedList<Patient>();
|
||||
for (final List<Patient> patientIterator : patients.values()) {
|
||||
Patient single = null;
|
||||
for (Patient patient : patientIterator) {
|
||||
if (name == null || patient.getName().get(0).getFamily().get(0).getValueNotNull().equals(name.getValueNotNull())) {
|
||||
single = patient;
|
||||
}
|
||||
}
|
||||
if (single != null) {
|
||||
result.add(single);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Search(compartmentName = "Condition")
|
||||
public List<IBaseResource> searchCompartment(@IdParam IdType thePatientId) {
|
||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
Condition condition = new Condition();
|
||||
condition.setId(new IdType("665577"));
|
||||
retVal.add(condition);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Update
|
||||
public MethodOutcome update(@IdParam final IdType theId, @ResourceParam final Patient patient) {
|
||||
final String idPart = theId.getIdPart();
|
||||
if (patients.containsKey(idPart)) {
|
||||
final List<Patient> patientList = patients.get(idPart);
|
||||
final Patient lastPatient = getLast(patientList);
|
||||
patient.setId(createId(theId.getIdPartAsLong(), lastPatient.getIdElement().getVersionIdPartAsLong() + 1));
|
||||
patientList.add(patient);
|
||||
final MethodOutcome result = new MethodOutcome().setCreated(false);
|
||||
result.setResource(patient);
|
||||
result.setId(new IdType(patient.getId()));
|
||||
return result;
|
||||
} else {
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
}
|
||||
|
||||
private static IdType createId(final Long id, final Long theVersionId) {
|
||||
return new IdType("Patient", "" + id, "" + theVersionId);
|
||||
}
|
||||
|
||||
private static List<Patient> createPatient(final Patient patient) {
|
||||
patient.setId(createId(counter, 1L));
|
||||
final LinkedList<Patient> list = new LinkedList<Patient>();
|
||||
list.add(patient);
|
||||
counter++;
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<Patient> createPatient(final String name) {
|
||||
final Patient patient = new Patient();
|
||||
patient.getName().add(new HumanName().addFamily(name));
|
||||
return createPatient(patient);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
package ca.uhn.fhir.jaxrs.server.example;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu3.model.Conformance;
|
||||
import org.hl7.fhir.dstu3.model.DateType;
|
||||
import org.hl7.fhir.dstu3.model.HumanName;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.client.JaxRsRestfulClientFactory;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.method.SearchStyleEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
|
||||
public class JaxRsPatientProviderDstu3Test {
|
||||
|
||||
private static IGenericClient client;
|
||||
private static final FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static final String PATIENT_NAME = "Van Houte";
|
||||
private static int ourPort;
|
||||
private static Server jettyServer;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass()
|
||||
throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/");
|
||||
System.out.println(ourPort);
|
||||
jettyServer = new Server(ourPort);
|
||||
jettyServer.setHandler(context);
|
||||
ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
|
||||
jerseyServlet.setInitOrder(0);
|
||||
//@formatter:off
|
||||
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",
|
||||
StringUtils.join(Arrays.asList(
|
||||
JaxRsConformanceProviderDstu3.class.getCanonicalName(),
|
||||
JaxRsPatientRestProviderDstu3.class.getCanonicalName(),
|
||||
JaxRsPageProviderDstu3.class.getCanonicalName()
|
||||
), ";"));
|
||||
//@formatter:on
|
||||
jettyServer.start();
|
||||
|
||||
ourCtx.setRestfulClientFactory(new JaxRsRestfulClientFactory(ourCtx));
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/");
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass()
|
||||
throws Exception {
|
||||
try {
|
||||
jettyServer.destroy();
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Search/Query - Type */
|
||||
@Test
|
||||
public void findUsingGenericClientBySearch() {
|
||||
// Perform a search
|
||||
final Bundle results = client.search().forResource(Patient.class)
|
||||
.where(Patient.NAME.matchesExactly().value(PATIENT_NAME)).returnBundle(Bundle.class).execute();
|
||||
System.out.println(results.getEntry().get(0));
|
||||
assertEquals(results.getEntry().size(), 1);
|
||||
}
|
||||
|
||||
/** Search - Multi-valued Parameters (ANY/OR) */
|
||||
@Test
|
||||
public void findUsingGenericClientBySearchWithMultiValues() {
|
||||
final Bundle response = client.search().forResource(Patient.class)
|
||||
.where(Patient.ADDRESS.matches().values("Toronto")).and(Patient.ADDRESS.matches().values("Ontario"))
|
||||
.and(Patient.ADDRESS.matches().values("Canada"))
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("SHORTNAME", "TOYS")).returnBundle(Bundle.class).execute();
|
||||
System.out.println(response.getEntry().get(0));
|
||||
}
|
||||
|
||||
/** Search - Paging */
|
||||
@Test
|
||||
public void findWithPaging() {
|
||||
// Perform a search
|
||||
final Bundle results = client.search().forResource(Patient.class).limitTo(8).returnBundle(Bundle.class).execute();
|
||||
System.out.println(results.getEntry().size());
|
||||
|
||||
if (results.getLink(Bundle.LINK_NEXT) != null) {
|
||||
|
||||
// load next page
|
||||
final Bundle nextPage = client.loadPage().next(results).execute();
|
||||
System.out.println(nextPage.getEntry().size());
|
||||
}
|
||||
}
|
||||
|
||||
/** Search using other query options */
|
||||
public void testOther() {
|
||||
//missing
|
||||
}
|
||||
|
||||
/** */
|
||||
@Test
|
||||
public void testSearchPost() {
|
||||
Bundle response = client.search()
|
||||
.forResource("Patient")
|
||||
.usingStyle(SearchStyleEnum.POST)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
assertTrue(response.getEntry().size() > 0);
|
||||
}
|
||||
|
||||
/** Search - Compartments */
|
||||
@Test
|
||||
public void testSearchCompartements() {
|
||||
Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.withIdAndCompartment("1", "Condition")
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
assertTrue(response.getEntry().size() > 0);
|
||||
}
|
||||
|
||||
/** Search - Subsetting (_summary and _elements) */
|
||||
@Test
|
||||
@Ignore
|
||||
public void testSummary() {
|
||||
client.search()
|
||||
.forResource(Patient.class)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatePatient() {
|
||||
final Patient existing = new Patient();
|
||||
existing.setId((IdType) null);
|
||||
existing.getName().add(new HumanName().addFamily("Created Patient 54"));
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
final MethodOutcome results = client.create().resource(existing).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
System.out.println(results.getId());
|
||||
final Patient patient = (Patient) results.getResource();
|
||||
System.out.println(patient);
|
||||
assertNotNull(client.read(Patient.class, patient.getId()));
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
}
|
||||
|
||||
|
||||
/** Conditional Creates */
|
||||
@Test
|
||||
public void testConditionalCreate() {
|
||||
final Patient existing = new Patient();
|
||||
existing.setId((IdType) null);
|
||||
existing.getName().add(new HumanName().addFamily("Created Patient 54"));
|
||||
client.setEncoding(EncodingEnum.XML);
|
||||
final MethodOutcome results = client.create().resource(existing).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
System.out.println(results.getId());
|
||||
final Patient patient = (Patient) results.getResource();
|
||||
|
||||
client.create()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().identifier(patient.getId()))
|
||||
.execute();
|
||||
}
|
||||
|
||||
|
||||
/** Find By Id */
|
||||
@Test
|
||||
public void findUsingGenericClientById() {
|
||||
final Patient results = client.read(Patient.class, "1");
|
||||
assertEquals(results.getIdElement().getIdPartAsLong().longValue(), 1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateById() {
|
||||
final Patient existing = client.read(Patient.class, "1");
|
||||
final List<HumanName> name = existing.getName();
|
||||
name.get(0).addSuffix("The Second");
|
||||
existing.getName().addAll(name);
|
||||
client.setEncoding(EncodingEnum.XML);
|
||||
final MethodOutcome results = client.update("1", existing);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletePatient() {
|
||||
final Patient existing = new Patient();
|
||||
existing.getName().add(new HumanName().addFamily("Created Patient XYZ"));
|
||||
final MethodOutcome results = client.create().resource(existing).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
System.out.println(results.getId());
|
||||
final Patient patient = (Patient) results.getResource();
|
||||
client.delete(Patient.class, patient.getId());
|
||||
try {
|
||||
client.read(Patient.class, patient.getId());
|
||||
fail();
|
||||
}
|
||||
catch (final Exception e) {
|
||||
//assertEquals(e.getStatusCode(), Constants.STATUS_HTTP_404_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/** Transaction - Server */
|
||||
@Ignore
|
||||
@Test
|
||||
public void testTransaction() {
|
||||
Bundle bundle = new Bundle();
|
||||
BundleEntryComponent entry = bundle.addEntry();
|
||||
final Patient existing = new Patient();
|
||||
existing.getName().get(0).addFamily("Created with bundle");
|
||||
entry.setResource(existing);
|
||||
|
||||
// FIXME ?
|
||||
// BoundCodeDt<BundleEntryTransactionMethodEnum> theTransactionOperation =
|
||||
// new BoundCodeDt(
|
||||
// BundleEntryTransactionMethodEnum.VALUESET_BINDER,
|
||||
// BundleEntryTransactionMethodEnum.POST);
|
||||
// entry.setTransactionMethod(theTransactionOperation);
|
||||
Bundle response = client.transaction().withBundle(bundle).execute();
|
||||
}
|
||||
|
||||
/** Conformance - Server */
|
||||
@Test
|
||||
@Ignore
|
||||
public void testConformance() {
|
||||
final Conformance conf = client.fetchConformance().ofType(Conformance.class).execute();
|
||||
System.out.println(conf.getRest().get(0).getResource().get(0).getType());
|
||||
assertEquals(conf.getRest().get(0).getResource().get(0).getType().toString(), "Patient");
|
||||
}
|
||||
|
||||
/** Extended Operations */
|
||||
// Create a client to talk to the HeathIntersections server
|
||||
@Test
|
||||
public void testExtendedOperations() {
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateType("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateType("2015-03-01"));
|
||||
inParams.addParameter().setName("dummy").setValue(new StringType("myAwesomeDummyValue"));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client
|
||||
.operation()
|
||||
.onInstance(new IdType("Patient", "1"))
|
||||
.named("$firstVersion")
|
||||
.withParameters(inParams)
|
||||
//.useHttpGet() // Use HTTP GET instead of POST
|
||||
.execute();
|
||||
String resultValue = outParams.getParameter().get(0).getValue().toString();
|
||||
System.out.println(resultValue);
|
||||
assertEquals("expected but found : "+ resultValue, resultValue.contains("myAwesomeDummyValue"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtendedOperationsUsingGet() {
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateType("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateType("2015-03-01"));
|
||||
inParams.addParameter().setName("dummy").setValue(new StringType("myAwesomeDummyValue"));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client
|
||||
.operation()
|
||||
.onInstance(new IdType("Patient", "1"))
|
||||
.named("$firstVersion")
|
||||
.withParameters(inParams)
|
||||
.useHttpGet() // Use HTTP GET instead of POST
|
||||
.execute();
|
||||
String resultValue = outParams.getParameter().get(0).getValue().toString();
|
||||
System.out.println(resultValue);
|
||||
assertEquals("expected but found : "+ resultValue, resultValue.contains("myAwesomeDummyValue"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVRead() {
|
||||
final Patient patient = client.vread(Patient.class, "1", "1");
|
||||
System.out.println(patient);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() {
|
||||
final Patient patient = client.read(Patient.class, "1");
|
||||
System.out.println(patient);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2016 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
public class PathAndRef {
|
||||
|
||||
private final String myPath;
|
||||
|
|
|
@ -9,6 +9,7 @@ import static org.hamcrest.Matchers.endsWith;
|
|||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
@ -32,6 +33,9 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.dstu3.model.BaseResource;
|
||||
|
@ -118,7 +122,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
|
||||
private void assertGone(IIdType theId) {
|
||||
try {
|
||||
assertNotGone(theId);
|
||||
|
@ -240,7 +243,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChoiceParamDate() {
|
||||
Observation o2 = new Observation();
|
||||
|
@ -254,7 +256,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
assertEquals(id2, found.getResources(0, 1).get(0).getIdElement());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateDifferentTypesWithSameForcedId() {
|
||||
String idName = "forcedId";
|
||||
|
@ -264,17 +266,17 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
pat.addName().addFamily("FAM");
|
||||
IIdType patId = myPatientDao.update(pat, mySrd).getId();
|
||||
assertEquals("Patient/" + idName, patId.toUnqualifiedVersionless().getValue());
|
||||
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.setId(idName);
|
||||
obs.getCode().addCoding().setSystem("foo").setCode("testCreateDifferentTypesWithSameForcedId");
|
||||
IIdType obsId = myObservationDao.update(obs, mySrd).getId();
|
||||
assertEquals("Observation/" + idName, obsId.toUnqualifiedVersionless().getValue());
|
||||
|
||||
|
||||
pat = myPatientDao.read(patId.toUnqualifiedVersionless(), mySrd);
|
||||
obs = myObservationDao.read(obsId.toUnqualifiedVersionless(), mySrd);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChoiceParamDateAlt() {
|
||||
Observation o2 = new Observation();
|
||||
|
@ -468,7 +470,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
|
||||
NamingSystem res = myFhirCtx.newXmlParser().parseResource(NamingSystem.class, input);
|
||||
IIdType id = myNamingSystemDao.create(res, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
|
||||
assertThat(toUnqualifiedVersionlessIdValues(myNamingSystemDao.search(NamingSystem.SP_NAME, new StringParam("NDF"))), contains(id.getValue()));
|
||||
}
|
||||
|
||||
|
@ -497,7 +499,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
assertEquals("my message", oo.getIssue().get(0).getDiagnostics());
|
||||
assertEquals(IssueType.INCOMPLETE, oo.getIssue().get(0).getCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateOperationOutcomeInfo() {
|
||||
FhirResourceDaoDstu3<Bundle> dao = new FhirResourceDaoDstu3<Bundle>();
|
||||
|
@ -593,7 +595,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
myBundleDao.create(bundle, mySrd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateWithIfNoneExistBasic() {
|
||||
String methodName = "testCreateWithIfNoneExistBasic";
|
||||
|
@ -773,7 +775,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
// Lose typing so we can put the wrong type in
|
||||
@SuppressWarnings("rawtypes")
|
||||
IFhirResourceDao dao = myNamingSystemDao;
|
||||
|
||||
|
||||
Patient resource = new Patient();
|
||||
resource.addName().addFamily("My Name");
|
||||
try {
|
||||
|
@ -1473,10 +1475,10 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
|
||||
@Test
|
||||
public void testHistoryWithFutureSinceDate() throws Exception {
|
||||
|
||||
|
||||
Date before = new Date();
|
||||
Thread.sleep(10);
|
||||
|
||||
|
||||
Patient inPatient = new Patient();
|
||||
inPatient.addName().addFamily("version1");
|
||||
inPatient.getMeta().addProfile("http://example.com/1");
|
||||
|
@ -1484,18 +1486,18 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
|
||||
Thread.sleep(10);
|
||||
Date after = new Date();
|
||||
|
||||
|
||||
// No since
|
||||
|
||||
|
||||
IBundleProvider history = myPatientDao.history(null, mySrd);
|
||||
assertEquals(1, history.size());
|
||||
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||
assertEquals("version1", inPatient.getName().get(0).getFamilyAsSingleString());
|
||||
List<String> profiles = toStringList(outPatient.getMeta().getProfile());
|
||||
assertThat(profiles, contains("http://example.com/1"));
|
||||
|
||||
|
||||
// Before since
|
||||
|
||||
|
||||
history = myPatientDao.history(before, mySrd);
|
||||
assertEquals(1, history.size());
|
||||
outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||
|
@ -1504,12 +1506,12 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
assertThat(profiles, contains("http://example.com/1"));
|
||||
|
||||
// After since
|
||||
|
||||
|
||||
history = myPatientDao.history(after, mySrd);
|
||||
assertEquals(0, history.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHistoryReflectsMetaOperations() throws Exception {
|
||||
Patient inPatient = new Patient();
|
||||
|
@ -1523,25 +1525,25 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
assertEquals("version1", inPatient.getName().get(0).getFamilyAsSingleString());
|
||||
List<String> profiles = toStringList(outPatient.getMeta().getProfile());
|
||||
assertThat(profiles, contains("http://example.com/1"));
|
||||
|
||||
|
||||
/*
|
||||
* Change metadata
|
||||
*/
|
||||
|
||||
|
||||
inPatient.getMeta().addProfile("http://example.com/2");
|
||||
myPatientDao.metaAddOperation(id, inPatient.getMeta(), mySrd);
|
||||
|
||||
|
||||
history = myPatientDao.history(null, mySrd);
|
||||
assertEquals(1, history.size());
|
||||
outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||
assertEquals("version1", inPatient.getName().get(0).getFamilyAsSingleString());
|
||||
profiles = toStringList(outPatient.getMeta().getProfile());
|
||||
assertThat(profiles, containsInAnyOrder("http://example.com/1", "http://example.com/2"));
|
||||
|
||||
|
||||
/*
|
||||
* Do an update
|
||||
*/
|
||||
|
||||
|
||||
inPatient.setId(id);
|
||||
inPatient.getMeta().addProfile("http://example.com/3");
|
||||
inPatient.getName().get(0).addFamily("version2");
|
||||
|
@ -1559,7 +1561,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
assertEquals("version1", outPatient.getName().get(0).getFamilyAsSingleString());
|
||||
profiles = toStringList(outPatient.getMeta().getProfile());
|
||||
assertThat(profiles, containsInAnyOrder("http://example.com/1", "http://example.com/2"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHistoryWithDeletedResource() throws Exception {
|
||||
|
@ -1603,7 +1605,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
assertEquals("Resource Patient/FOOFOOFOO is not known", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIdParam() {
|
||||
Patient patient = new Patient();
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
package ca.uhn.fhir.jpa.provider.dstu3;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.dstu3.model.DecimalType;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.Questionnaire;
|
||||
import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
|
||||
|
@ -17,6 +28,7 @@ import org.junit.AfterClass;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
|
@ -99,5 +111,77 @@ public class ResourceProviderQuestionnaireResponseDstu3Test extends BaseResource
|
|||
assertThat(e.toString(), containsString("Answer value must be of type string"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveQuestionnaire() throws Exception {
|
||||
String input = "<QuestionnaireResponse xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
" <status value=\"completed\"/>\n" +
|
||||
" <authored value=\"2016-05-03T13:05:20-04:00\"/>\n" +
|
||||
" <item>\n" +
|
||||
" <linkId value=\"breast-feeding-intention\"/>\n" +
|
||||
" <text value=\"Breast Feeding Intention:\"/>\n" +
|
||||
" <answer>\n" +
|
||||
" <valueCoding>\n" +
|
||||
" <system value=\"http://example.org/codesystem-breastfeeding-intention\"/>\n" +
|
||||
" <code value=\"true\"/>\n" +
|
||||
" <display value=\"Mother wants to provide formula exclusively\"/>\n" +
|
||||
" </valueCoding>\n" +
|
||||
" </answer>\n" +
|
||||
" </item>\n" +
|
||||
" <item>\n" +
|
||||
" <linkId value=\"breast-feeding-education\"/>\n" +
|
||||
" <text value=\"Answer if not exclusive BM:\"/>\n" +
|
||||
" <answer>\n" +
|
||||
" <valueCoding>\n" +
|
||||
" <system value=\"http://example.org/codesystem-breastfeeding-education\"/>\n" +
|
||||
" <code value=\"true\"/>\n" +
|
||||
" <display value=\"Mother not given comprehensive education per protocol\"/>\n" +
|
||||
" </valueCoding>\n" +
|
||||
" </answer>\n" +
|
||||
" </item>\n" +
|
||||
" <item>\n" +
|
||||
" <linkId value=\"breast-feeding-exclusion\"/>\n" +
|
||||
" <text value=\"Exclusion Criteria:\"/>\n" +
|
||||
" <answer>\n" +
|
||||
" <valueCoding>\n" +
|
||||
" <system value=\"http://example.org/codesystem-breastfeeding-exclusion\"/>\n" +
|
||||
" <code value=\"true\"/>\n" +
|
||||
" <display\n" +
|
||||
" value=\"Maternal use of drugs of abuse, antimetabolites, chemotherapeutic agents, or radioisotopes\"\n" +
|
||||
" />\n" +
|
||||
" </valueCoding>\n" +
|
||||
" </answer>\n" +
|
||||
" </item>\n" +
|
||||
"</QuestionnaireResponse>";
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse");
|
||||
post.setEntity(new StringEntity(input, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
final IdType id2;
|
||||
try {
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info("Response: {}", responseString);
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue();
|
||||
assertThat(newIdString, startsWith(ourServerBase + "/QuestionnaireResponse/"));
|
||||
id2 = new IdType(newIdString);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(response);
|
||||
}
|
||||
|
||||
HttpGet get = new HttpGet(ourServerBase + "/QuestionnaireResponse/" + id2.getIdPart() + "?_format=xml&_pretty=true");
|
||||
response = ourHttpClient.execute(get);
|
||||
try {
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info("Response: {}", responseString);
|
||||
assertThat(responseString, containsString("Exclusion Criteria"));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class CommonConfig {
|
|||
public IServerInterceptor requestLoggingInterceptor() {
|
||||
LoggingInterceptor retVal = new LoggingInterceptor();
|
||||
retVal.setLoggerName("fhirtest.request");
|
||||
retVal.setMessageFormat("Path[${servletPath}] ${requestBodyFhir}");
|
||||
retVal.setMessageFormat("${requestVerb} ${servletPath} -\n${requestBodyFhir}");
|
||||
retVal.setLogExceptions(false);
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
</triggeringPolicy>
|
||||
<encoder>
|
||||
<!-- [%file:%line] -->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %msg%n</pattern>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
|
|
@ -81,6 +81,17 @@ public class ServerSearchDstu2Test {
|
|||
assertEquals("param2value", ourLastRef.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchParamWithSpace() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/?param2=param+value&foo=bar");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
ourLog.info(responseContent);
|
||||
assertEquals("searchParam2", ourLastMethod);
|
||||
assertEquals("param value", ourLastRef.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownSearchParam() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/?foo=bar");
|
||||
|
|
|
@ -70,11 +70,13 @@ public class LoggingInterceptorDstu2Test {
|
|||
private static Server ourServer;
|
||||
private static RestfulServer servlet;
|
||||
private IServerInterceptor myInterceptor;
|
||||
private static Exception ourThrowException;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myInterceptor = mock(IServerInterceptor.class);
|
||||
servlet.setInterceptors(Collections.singletonList(myInterceptor));
|
||||
ourThrowException = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -139,7 +141,48 @@ public class LoggingInterceptorDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
public void testRequestBodyRead() throws Exception {
|
||||
|
||||
LoggingInterceptor interceptor = new LoggingInterceptor();
|
||||
interceptor.setMessageFormat("${operationType} - ${operationName} - ${idOrResourceName} - ${requestBodyFhir}");
|
||||
servlet.setInterceptors(Collections.singletonList((IServerInterceptor) interceptor));
|
||||
|
||||
Logger logger = mock(Logger.class);
|
||||
interceptor.setLogger(logger);
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(logger, times(1)).info(captor.capture());
|
||||
assertEquals("read - - Patient/1 - ", captor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestBodyReadWithContentTypeHeader() throws Exception {
|
||||
|
||||
LoggingInterceptor interceptor = new LoggingInterceptor();
|
||||
interceptor.setMessageFormat("${operationType} - ${operationName} - ${idOrResourceName} - ${requestBodyFhir}");
|
||||
servlet.setInterceptors(Collections.singletonList((IServerInterceptor) interceptor));
|
||||
|
||||
Logger logger = mock(Logger.class);
|
||||
interceptor.setLogger(logger);
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader(Constants.HEADER_CONTENT_TYPE, Constants.CT_FHIR_XML);
|
||||
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(logger, times(1)).info(captor.capture());
|
||||
assertEquals("read - - Patient/1 - ", captor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestBodyCreate() throws Exception {
|
||||
|
||||
LoggingInterceptor interceptor = new LoggingInterceptor();
|
||||
interceptor.setMessageFormat("${operationType} - ${operationName} - ${idOrResourceName} - ${requestBodyFhir}");
|
||||
|
@ -151,10 +194,37 @@ public class LoggingInterceptorDstu2Test {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setValue("VAL");
|
||||
String input = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(input, ContentType.parse(Constants.CT_FHIR_XML+";charset=utf-8")));
|
||||
|
||||
httpPost.setEntity(new StringEntity(input, ContentType.parse(Constants.CT_FHIR_XML + ";charset=utf-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(logger, times(1)).info(captor.capture());
|
||||
assertEquals("create - - Patient - <Patient xmlns=\"http://hl7.org/fhir\"><identifier><value value=\"VAL\"/></identifier></Patient>", captor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestBodyCreateException() throws Exception {
|
||||
|
||||
LoggingInterceptor interceptor = new LoggingInterceptor();
|
||||
interceptor.setMessageFormat("${operationType} - ${operationName} - ${idOrResourceName} - ${requestBodyFhir}");
|
||||
servlet.setInterceptors(Collections.singletonList((IServerInterceptor) interceptor));
|
||||
|
||||
Logger logger = mock(Logger.class);
|
||||
interceptor.setLogger(logger);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setValue("VAL");
|
||||
String input = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
|
||||
ourThrowException = new NullPointerException("FOO");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(input, ContentType.parse(Constants.CT_FHIR_XML + ";charset=utf-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
|
@ -348,10 +418,13 @@ public class LoggingInterceptorDstu2Test {
|
|||
}
|
||||
|
||||
@Create
|
||||
public MethodOutcome create(@ResourceParam Patient thePatient) {
|
||||
public MethodOutcome create(@ResourceParam Patient thePatient) throws Exception {
|
||||
if (ourThrowException != null) {
|
||||
throw ourThrowException;
|
||||
}
|
||||
return new MethodOutcome(new IdDt("Patient/1"));
|
||||
}
|
||||
|
||||
|
||||
@Operation(name = "$everything", idempotent = true)
|
||||
public Bundle patientTypeOperation(@OperationParam(name = "start") DateDt theStart, @OperationParam(name = "end") DateDt theEnd) {
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
|
@ -89,6 +90,8 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
Validate.notBlank(theUri, "theUri must not be null or blank");
|
||||
|
||||
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
return (T) fetchStructureDefinition(theContext, theUri);
|
||||
}
|
||||
|
|
|
@ -1541,7 +1541,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
|
||||
private void validateQuestionannaireResponse(List<ValidationMessage> errors, Element element, NodeStack stack) {
|
||||
Element q = element.getNamedChild("questionnaire");
|
||||
if (hint(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), q != null, "No questionnaire is identified, so no validation can be performed against the base questionnaire")) {
|
||||
if (hint(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), q != null && isNotBlank(q.getNamedChildValue("reference")), "No questionnaire is identified, so no validation can be performed against the base questionnaire")) {
|
||||
long t = System.nanoTime();
|
||||
Questionnaire qsrc = context.fetchResource(Questionnaire.class, q.getNamedChildValue("reference"));
|
||||
sdTime = sdTime + (System.nanoTime() - t);
|
||||
|
|
|
@ -120,14 +120,14 @@ public class XmlParserDstu3Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeContained() throws Exception {
|
||||
public void testEncodeContainedWithNonLocalId() throws Exception {
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setId("Patient1");
|
||||
p.setBirthDate(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").parse("2016-04-15 10:15:30"));
|
||||
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.setId("#1234567");
|
||||
pr.setId("1234567");
|
||||
pr.setSubject(new Reference(p));
|
||||
pr.setCode(new CodeableConcept().addCoding(new Coding("breastfeeding-readiness-assessment", "Breastfeeding Readiness Assessment", "Breastfeeding Readiness Assessment")));
|
||||
// pr.setReason(new StringType("Single Live Birth"));
|
||||
|
|
Loading…
Reference in New Issue