Use corrrect types from client
This commit is contained in:
parent
41b58108f2
commit
dd8b1cd979
|
@ -26,26 +26,19 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<!--
|
||||
<exclusion>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
</exclusion>
|
||||
-->
|
||||
<exclusion>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -90,19 +83,6 @@
|
|||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Android does not come with the Servlet API bundled, and MethodUtil
|
||||
requires it.
|
||||
|
||||
We provide a dummy implementation of servlet api to reduce size
|
||||
and prevent from rewriting the BaseMethodBinding and friends.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -118,6 +98,7 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--
|
||||
<classpathDependencyScopeExclude>compile+runtime+test+provided</classpathDependencyScopeExclude>
|
||||
<additionalClasspathElements>
|
||||
<additionalClasspathElement>${project.build.directory}/hapi-fhir-android-${project.version}-dstu2.jar</additionalClasspathElement>
|
||||
|
@ -128,6 +109,7 @@
|
|||
<classpathDependencyExclude>javax.json:*</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.glassfish:javax.json</classpathDependencyExclude>
|
||||
</classpathDependencyExcludes>
|
||||
-->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -148,18 +130,6 @@
|
|||
<artifactSet>
|
||||
<includes combine.children="append">
|
||||
<include>ca.uhn.hapi.fhir:hapi-fhir-base</include>
|
||||
<include>org.glassfish:javax.json</include>
|
||||
<include>org.codehaus.woodstox:woodstox-core-asl</include>
|
||||
<include>javax.xml.stream:stax-api</include>
|
||||
<include>org.codehaus.woodstox:stax2-api</include>
|
||||
<include>org.glassfish:javax.json</include>
|
||||
<!--
|
||||
<include>net.sourceforge.cobertura:cobertura</include>
|
||||
<include>org.apache.commons:*</include>
|
||||
<include>org.apache.httpcomponents:*</include>
|
||||
<include>commons-codec:commons-codec</include>
|
||||
-->
|
||||
<include>javax.servlet:javax.servlet-api</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
package ca.uhn.fhir.android;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Observable;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
|
@ -18,10 +12,7 @@ import org.apache.commons.io.filefilter.WildcardFileFilter;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ctc.wstx.stax.WstxInputFactory;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
|
@ -39,7 +30,11 @@ public class BuiltJarIT {
|
|||
|
||||
@Test
|
||||
public void testParserXml() throws Exception {
|
||||
// fail("*******: " + WstxInputFactory.class.getProtectionDomain().getCodeSource().getLocation().toString());
|
||||
try {
|
||||
Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
|
@ -54,8 +49,6 @@ public class BuiltJarIT {
|
|||
|
||||
@Test
|
||||
public void testParserJson() {
|
||||
ourLog.info("AAAAA");
|
||||
ourLog.info("AAAAA");
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
|
@ -72,7 +65,6 @@ public class BuiltJarIT {
|
|||
QuantityDt dt = (QuantityDt) p2.getValue();
|
||||
dt.getComparatorElement().getValueAsEnum();
|
||||
|
||||
QuantityCompararatorEnum.GREATERTHAN.name();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -168,15 +168,6 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
return myLastResponseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pretty print flag, which is a request to the server for it to return "pretty printed" responses. Note
|
||||
* that this is currently a non-standard flag (_pretty) which is supported only by HAPI based servers (and any other
|
||||
* servers which might implement it).
|
||||
*/
|
||||
public Boolean getPrettyPrint() {
|
||||
return myPrettyPrint;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -319,22 +310,6 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
if (handlesBinary.isBinary()) {
|
||||
InputStream reader = response.readEntity();
|
||||
try {
|
||||
|
||||
if (ourLog.isTraceEnabled() || myKeepResponses || theLogRequestAndResponse) {
|
||||
byte[] responseBytes = IOUtils.toByteArray(reader);
|
||||
if (myKeepResponses) {
|
||||
myLastResponse = response;
|
||||
myLastResponseBody = null;
|
||||
}
|
||||
String message = "HTTP " + response.getStatus() + " " + response.getStatusInfo();
|
||||
if (theLogRequestAndResponse) {
|
||||
ourLog.info("Client response: {} - {} bytes", message, responseBytes.length);
|
||||
} else {
|
||||
ourLog.trace("Client response: {} - {} bytes", message, responseBytes.length);
|
||||
}
|
||||
reader = new ByteArrayInputStream(responseBytes);
|
||||
}
|
||||
|
||||
return handlesBinary.invokeClient(mimeType, reader, response.getStatus(), headers);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
|
@ -441,20 +416,6 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
myKeepResponses = theKeepResponses;
|
||||
}
|
||||
|
||||
/**
|
||||
* For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
|
||||
*/
|
||||
public void setLastResponse(IHttpResponse theLastResponse) {
|
||||
myLastResponse = theLastResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
|
||||
*/
|
||||
public void setLastResponseBody(String theLastResponseBody) {
|
||||
myLastResponseBody = theLastResponseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pretty print flag, which is a request to the server for it to return "pretty printed" responses. Note
|
||||
* that this is currently a non-standard flag (_pretty) which is supported only by HAPI based servers (and any other
|
||||
|
|
|
@ -116,7 +116,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
|
||||
}
|
||||
|
||||
protected IParser createAppropriateParserForParsingResponse(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode) {
|
||||
protected IParser createAppropriateParserForParsingResponse(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, List<Class<? extends IBaseResource>> thePreferTypes) {
|
||||
EncodingEnum encoding = EncodingEnum.forContentType(theResponseMimeType);
|
||||
if (encoding == null) {
|
||||
NonFhirResponseException ex = NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
|
||||
|
@ -125,6 +125,9 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
}
|
||||
|
||||
IParser parser = encoding.newParser(getContext());
|
||||
|
||||
parser.setPreferTypes(thePreferTypes);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
|
@ -325,7 +328,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
ex = new PreconditionFailedException("Server responded with HTTP 412");
|
||||
break;
|
||||
case Constants.STATUS_HTTP_422_UNPROCESSABLE_ENTITY:
|
||||
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theStatusCode);
|
||||
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theStatusCode, null);
|
||||
// TODO: handle if something other than OO comes back
|
||||
BaseOperationOutcome operationOutcome = (BaseOperationOutcome) parser.parseResource(theResponseReader);
|
||||
ex = new UnprocessableEntityException(myContext, operationOutcome);
|
||||
|
|
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.method;
|
|||
* 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
|
||||
* 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,
|
||||
|
@ -25,15 +25,7 @@ import java.io.IOException;
|
|||
import java.io.Reader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
|
@ -91,7 +83,8 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
private MethodReturnTypeEnum myMethodReturnType;
|
||||
private Class<?> myResourceListCollectionType;
|
||||
private String myResourceName;
|
||||
private Class<? extends IResource> myResourceType;
|
||||
private Class<? extends IBaseResource> myResourceType;
|
||||
private List<Class<? extends IBaseResource>> myPreferTypesList;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BaseResourceReturningMethodBinding(Class<?> theReturnResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
|
||||
|
@ -137,6 +130,8 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
myPreferTypesList = createPreferTypesList();
|
||||
}
|
||||
|
||||
public MethodReturnTypeEnum getMethodReturnType() {
|
||||
|
@ -157,11 +152,11 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
|
||||
@Override
|
||||
public Object invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) {
|
||||
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theResponseStatusCode);
|
||||
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theResponseStatusCode, myPreferTypesList);
|
||||
|
||||
switch (getReturnType()) {
|
||||
case BUNDLE: {
|
||||
|
||||
|
||||
Bundle dstu1bundle = null;
|
||||
IBaseBundle dstu2bundle = null;
|
||||
List<? extends IBaseResource> listOfResources = null;
|
||||
|
@ -177,7 +172,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
dstu2bundle = (IBaseBundle) parser.parseResource(type, theResponseReader);
|
||||
listOfResources = BundleUtil.toListOfResources(getContext(), dstu2bundle);
|
||||
}
|
||||
|
||||
|
||||
switch (getMethodReturnType()) {
|
||||
case BUNDLE:
|
||||
return dstu1bundle;
|
||||
|
@ -185,7 +180,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
return dstu2bundle;
|
||||
case LIST_OF_RESOURCES:
|
||||
if (myResourceListCollectionType != null) {
|
||||
for (Iterator<? extends IBaseResource> iter = listOfResources.iterator(); iter.hasNext(); ) {
|
||||
for (Iterator<? extends IBaseResource> iter = listOfResources.iterator(); iter.hasNext();) {
|
||||
IBaseResource next = iter.next();
|
||||
if (!myResourceListCollectionType.isAssignableFrom(next.getClass())) {
|
||||
ourLog.debug("Not returning resource of type {} because it is not a subclass or instance of {}", next.getClass(), myResourceListCollectionType);
|
||||
|
@ -243,6 +238,19 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
throw new IllegalStateException("Should not get here!");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Class<? extends IBaseResource>> createPreferTypesList() {
|
||||
List<Class<? extends IBaseResource>> preferTypes = null;
|
||||
if (myResourceListCollectionType != null && IBaseResource.class.isAssignableFrom(myResourceListCollectionType)) {
|
||||
preferTypes = new ArrayList<Class<? extends IBaseResource>>(1);
|
||||
preferTypes.add((Class<? extends IBaseResource>) myResourceListCollectionType);
|
||||
// } else if (myResourceType != null) {
|
||||
// preferTypes = new ArrayList<Class<? extends IBaseResource>>(1);
|
||||
// preferTypes.add((Class<? extends IBaseResource>) myResourceListCollectionType);
|
||||
}
|
||||
return preferTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException {
|
||||
|
||||
|
@ -250,7 +258,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
|
||||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
|
||||
if (responseObject.getResource() != null) {
|
||||
|
||||
|
||||
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
|
||||
IServerInterceptor next = theServer.getInterceptors().get(i);
|
||||
boolean continueProcessing = next.outgoingResponse(theRequest, responseObject.getResource());
|
||||
|
@ -258,12 +266,12 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest);
|
||||
|
||||
return theRequest.getResponse().streamResponseAsResource(responseObject.getResource(), prettyPrint, summaryMode, Constants.STATUS_HTTP_200_OK, null,
|
||||
theRequest.isRespondGzip(), isAddContentLocationHeader());
|
||||
|
||||
|
||||
return theRequest.getResponse().streamResponseAsResource(responseObject.getResource(), prettyPrint, summaryMode, Constants.STATUS_HTTP_200_OK, null, theRequest.isRespondGzip(),
|
||||
isAddContentLocationHeader());
|
||||
|
||||
} else {
|
||||
// Is this request coming from a browser
|
||||
String uaHeader = theRequest.getHeader("user-agent");
|
||||
|
@ -271,7 +279,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
if (uaHeader != null && uaHeader.contains("Mozilla")) {
|
||||
requestIsBrowser = true;
|
||||
}
|
||||
|
||||
|
||||
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
|
||||
IServerInterceptor next = theServer.getInterceptors().get(i);
|
||||
boolean continueProcessing = next.outgoingResponse(theRequest, responseObject.getDstu1Bundle());
|
||||
|
@ -356,7 +364,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
|
||||
responseObject = new ResourceOrDstu1Bundle(resource);
|
||||
break;
|
||||
|
||||
|
||||
} else {
|
||||
Set<Include> includes = getRequestIncludesFromParams(params);
|
||||
|
||||
|
@ -364,20 +372,21 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
if (count == null) {
|
||||
count = result.preferredPageSize();
|
||||
}
|
||||
|
||||
|
||||
Integer offsetI = RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_PAGINGOFFSET);
|
||||
if (offsetI == null || offsetI < 0) {
|
||||
offsetI = 0;
|
||||
}
|
||||
int start = Math.max(0, Math.min(offsetI, result.size() - 1));
|
||||
|
||||
|
||||
IVersionSpecificBundleFactory bundleFactory = theServer.getFhirContext().newBundleFactory();
|
||||
|
||||
ResponseEncoding responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest, theServer.getDefaultResponseEncoding());
|
||||
EncodingEnum linkEncoding = theRequest.getParameters().containsKey(Constants.PARAM_FORMAT) && responseEncoding != null ? responseEncoding.getEncoding() : null;
|
||||
|
||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest);
|
||||
bundleFactory.initializeBundleFromBundleProvider(theServer, result, linkEncoding, theRequest.getFhirServerBase(), linkSelf, prettyPrint, start, count, null, getResponseBundleType(), includes);
|
||||
bundleFactory.initializeBundleFromBundleProvider(theServer, result, linkEncoding, theRequest.getFhirServerBase(), linkSelf, prettyPrint, start, count, null, getResponseBundleType(),
|
||||
includes);
|
||||
Bundle bundle = bundleFactory.getDstu1Bundle();
|
||||
if (bundle != null) {
|
||||
responseObject = new ResourceOrDstu1Bundle(bundle);
|
||||
|
|
|
@ -153,7 +153,7 @@ public class GetTagsMethodBinding extends BaseMethodBinding<TagList> {
|
|||
@Override
|
||||
public TagList invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws BaseServerResponseException {
|
||||
if (theResponseStatusCode == Constants.STATUS_HTTP_200_OK) {
|
||||
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theResponseStatusCode);
|
||||
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theResponseStatusCode, null);
|
||||
TagList retVal = parser.parseTagList(theResponseReader);
|
||||
return retVal;
|
||||
} else {
|
||||
|
|
|
@ -8,80 +8,28 @@ import java.io.PushbackReader;
|
|||
import java.io.Reader;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
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.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.Tag;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.context.*;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.annotation.At;
|
||||
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||
import ca.uhn.fhir.rest.annotation.Count;
|
||||
import ca.uhn.fhir.rest.annotation.Elements;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
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.ServerBase;
|
||||
import ca.uhn.fhir.rest.annotation.Since;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
import ca.uhn.fhir.rest.annotation.TagListParam;
|
||||
import ca.uhn.fhir.rest.annotation.TransactionParam;
|
||||
import ca.uhn.fhir.rest.annotation.Validate;
|
||||
import ca.uhn.fhir.rest.annotation.VersionIdParam;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.method.OperationParameter.IOperationParamConverter;
|
||||
import ca.uhn.fhir.rest.param.CollectionBinder;
|
||||
import ca.uhn.fhir.rest.param.DateAndListParam;
|
||||
import ca.uhn.fhir.rest.param.NumberAndListParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityAndListParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||
import ca.uhn.fhir.rest.param.ResourceParameter;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.param.ResourceParameter.Mode;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TransactionParameter;
|
||||
import ca.uhn.fhir.rest.param.UriAndListParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
|
@ -121,8 +69,17 @@ public class MethodUtil {
|
|||
|
||||
private static final String LABEL = "label=\"";
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MethodUtil.class);
|
||||
|
||||
private static final String SCHEME = "scheme=\"";
|
||||
private static final Set<String> ourServletRequestTypes = new HashSet<String>();
|
||||
private static final Set<String> ourServletResponseTypes = new HashSet<String>();
|
||||
|
||||
static {
|
||||
ourServletRequestTypes.add("javax.servlet.ServletRequest");
|
||||
ourServletResponseTypes.add("javax.servlet.ServletResponse");
|
||||
ourServletRequestTypes.add("javax.servlet.http.HttpServletRequest");
|
||||
ourServletResponseTypes.add("javax.servlet.http.HttpServletResponse");
|
||||
}
|
||||
|
||||
|
||||
static void addTagsToPostOrPut(FhirContext theContext, IBaseResource resource, BaseHttpClientInvocation retVal) {
|
||||
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
||||
|
@ -391,16 +348,22 @@ public class MethodUtil {
|
|||
throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of an invalid generic type (can not be a collection of a collection of a collection)");
|
||||
}
|
||||
}
|
||||
if (parameterType.equals(HttpServletRequest.class) || parameterType.equals(ServletRequest.class)) {
|
||||
|
||||
/*
|
||||
* Note: for the frst two here, we're using strings instead of static binding
|
||||
* so that we don't need the java.servlet JAR on the classpath in order to use
|
||||
* this class
|
||||
*/
|
||||
if (ourServletRequestTypes.contains(parameterType.getName())) {
|
||||
param = new ServletRequestParameter();
|
||||
} else if (ourServletResponseTypes.contains(parameterType.getName())) {
|
||||
param = new ServletResponseParameter();
|
||||
} else if (parameterType.equals(RequestDetails.class)) {
|
||||
param = new RequestDetailsParameter();
|
||||
} else if (parameterType.equals(IRequestOperationCallback.class)) {
|
||||
param = new RequestOperationCallbackParameter();
|
||||
} else if (parameterType.equals(SummaryEnum.class)) {
|
||||
param = new SummaryEnumParameter();
|
||||
} else if (parameterType.equals(HttpServletResponse.class) || parameterType.equals(ServletResponse.class)) {
|
||||
param = new ServletResponseParameter();
|
||||
} else {
|
||||
for (int i = 0; i < annotations.length && param == null; i++) {
|
||||
Annotation nextAnnotation = annotations[i];
|
||||
|
|
|
@ -163,7 +163,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
|||
@Override
|
||||
public HttpGetClientInvocation invokeClient(Object[] theArgs) {
|
||||
HttpGetClientInvocation retVal;
|
||||
IdDt id = ((IdDt) theArgs[myIdIndex]);
|
||||
IIdType id = ((IIdType) theArgs[myIdIndex]);
|
||||
if (myVersionIdIndex == null) {
|
||||
String resourceName = getResourceName();
|
||||
if (id.hasVersionIdPart()) {
|
||||
|
|
|
@ -56,12 +56,12 @@ import ca.uhn.fhir.util.jar.IDependencyLog;
|
|||
* This class contains code adapted from the Apache Axiom project.
|
||||
*/
|
||||
public class XmlUtil {
|
||||
private static XMLOutputFactory ourFragmentOutputFactory;
|
||||
private static volatile boolean ourHaveLoggedStaxImplementation;
|
||||
private static volatile XMLInputFactory ourInputFactory;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
|
||||
private static volatile XMLOutputFactory ourOutputFactory;
|
||||
private static XMLOutputFactory ourFragmentOutputFactory;
|
||||
private static Throwable ourNextException;
|
||||
private static volatile XMLOutputFactory ourOutputFactory;
|
||||
private static final Map<String, Integer> VALID_ENTITY_NAMES;
|
||||
private static final ExtendedEntityReplacingXmlResolver XML_RESOLVER = new ExtendedEntityReplacingXmlResolver();
|
||||
|
||||
|
@ -1519,6 +1519,42 @@ public class XmlUtil {
|
|||
VALID_ENTITY_NAMES = Collections.unmodifiableMap(validEntityNames);
|
||||
}
|
||||
|
||||
private static XMLOutputFactory createOutputFactory() throws FactoryConfigurationError {
|
||||
try {
|
||||
// Detect if we're running with the Android lib, and force repackaged Woodstox to be used
|
||||
Class.forName("ca.uhn.fhir.repackage.javax.xml.stream.XMLOutputFactory");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ok
|
||||
}
|
||||
|
||||
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
|
||||
|
||||
if (!ourHaveLoggedStaxImplementation) {
|
||||
logStaxImplementation(outputFactory.getClass());
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that these properties are Woodstox specific and they cause a crash in environments where SJSXP is
|
||||
* being used (e.g. glassfish) so we don't set them there.
|
||||
*/
|
||||
try {
|
||||
Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
|
||||
if (outputFactory instanceof WstxOutputFactory) {
|
||||
outputFactory.setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, new MyEscaper());
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
ourLog.debug("WstxOutputFactory (Woodstox) not found on classpath");
|
||||
}
|
||||
return outputFactory;
|
||||
}
|
||||
|
||||
public static XMLEventWriter createXmlFragmentWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
XMLOutputFactory outputFactory = getOrCreateFragmentOutputFactory();
|
||||
XMLEventWriter retVal = outputFactory.createXMLEventWriter(theWriter);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static XMLEventReader createXmlReader(Reader reader) throws FactoryConfigurationError, XMLStreamException {
|
||||
throwUnitTestExceptionIfConfiguredToDoSo();
|
||||
|
||||
|
@ -1529,16 +1565,6 @@ public class XmlUtil {
|
|||
return er;
|
||||
}
|
||||
|
||||
private static void throwUnitTestExceptionIfConfiguredToDoSo() throws FactoryConfigurationError, XMLStreamException {
|
||||
if (ourNextException != null) {
|
||||
if (ourNextException instanceof FactoryConfigurationError) {
|
||||
throw ((FactoryConfigurationError)ourNextException);
|
||||
} else {
|
||||
throw (XMLStreamException)ourNextException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static XMLStreamWriter createXmlStreamWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
throwUnitTestExceptionIfConfiguredToDoSo();
|
||||
|
||||
|
@ -1547,15 +1573,20 @@ public class XmlUtil {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static XMLEventWriter createXmlFragmentWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
XMLOutputFactory outputFactory = getOrCreateFragmentOutputFactory();
|
||||
public static XMLEventWriter createXmlWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
XMLOutputFactory outputFactory = getOrCreateOutputFactory();
|
||||
XMLEventWriter retVal = outputFactory.createXMLEventWriter(theWriter);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static XMLEventWriter createXmlWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
XMLOutputFactory outputFactory = getOrCreateOutputFactory();
|
||||
XMLEventWriter retVal = outputFactory.createXMLEventWriter(theWriter);
|
||||
private static XMLOutputFactory getOrCreateFragmentOutputFactory() throws FactoryConfigurationError {
|
||||
XMLOutputFactory retVal = ourFragmentOutputFactory;
|
||||
if (retVal == null) {
|
||||
retVal = createOutputFactory();
|
||||
retVal.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
|
||||
ourFragmentOutputFactory = retVal;
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -1614,17 +1645,6 @@ public class XmlUtil {
|
|||
return ourInputFactory;
|
||||
}
|
||||
|
||||
private static XMLOutputFactory getOrCreateFragmentOutputFactory() throws FactoryConfigurationError {
|
||||
XMLOutputFactory retVal = ourFragmentOutputFactory;
|
||||
if (retVal == null) {
|
||||
retVal = createOutputFactory();
|
||||
retVal.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
|
||||
ourFragmentOutputFactory = retVal;
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
private static XMLOutputFactory getOrCreateOutputFactory() throws FactoryConfigurationError {
|
||||
if (ourOutputFactory == null) {
|
||||
|
@ -1633,36 +1653,6 @@ public class XmlUtil {
|
|||
return ourOutputFactory;
|
||||
}
|
||||
|
||||
private static XMLOutputFactory createOutputFactory() throws FactoryConfigurationError {
|
||||
try {
|
||||
// Detect if we're running with the Android lib, and force repackaged Woodstox to be used
|
||||
Class.forName("ca.uhn.fhir.repackage.javax.xml.stream.XMLOutputFactory");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ok
|
||||
}
|
||||
|
||||
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
|
||||
|
||||
if (!ourHaveLoggedStaxImplementation) {
|
||||
logStaxImplementation(outputFactory.getClass());
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that these properties are Woodstox specific and they cause a crash in environments where SJSXP is
|
||||
* being used (e.g. glassfish) so we don't set them there.
|
||||
*/
|
||||
try {
|
||||
Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
|
||||
if (outputFactory instanceof WstxOutputFactory) {
|
||||
outputFactory.setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, new MyEscaper());
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
ourLog.debug("WstxOutputFactory (Woodstox) not found on classpath");
|
||||
}
|
||||
return outputFactory;
|
||||
}
|
||||
|
||||
private static void logStaxImplementation(Class<?> theClass) {
|
||||
IDependencyLog logger = DependencyLogFactory.createJarLogger();
|
||||
if (logger != null) {
|
||||
|
@ -1671,6 +1661,23 @@ public class XmlUtil {
|
|||
ourHaveLoggedStaxImplementation = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* FOR UNIT TESTS ONLY - Throw this exception for the next operation
|
||||
*/
|
||||
static void setThrowExceptionForUnitTest(Throwable theException) {
|
||||
ourNextException = theException;
|
||||
}
|
||||
|
||||
private static void throwUnitTestExceptionIfConfiguredToDoSo() throws FactoryConfigurationError, XMLStreamException {
|
||||
if (ourNextException != null) {
|
||||
if (ourNextException instanceof FactoryConfigurationError) {
|
||||
throw ((FactoryConfigurationError)ourNextException);
|
||||
} else {
|
||||
throw (XMLStreamException)ourNextException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ExtendedEntityReplacingXmlResolver implements XMLResolver {
|
||||
@Override
|
||||
public Object resolveEntity(String thePublicID, String theSystemID, String theBaseURI, String theNamespace) throws XMLStreamException {
|
||||
|
@ -1735,11 +1742,4 @@ public class XmlUtil {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* FOR UNIT TESTS ONLY - Throw this exception for the next operation
|
||||
*/
|
||||
static void setThrowExceptionForUnitTest(Throwable theException) {
|
||||
ourNextException = theException;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,19 +38,19 @@ import ca.uhn.fhir.util.TestUtil;
|
|||
|
||||
public class BinaryClientTest {
|
||||
|
||||
private FhirContext ctx;
|
||||
private HttpClient httpClient;
|
||||
private FhirContext mtCtx;
|
||||
private HttpClient myHttpClient;
|
||||
private HttpResponse httpResponse;
|
||||
|
||||
// atom-document-large.xml
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ctx = FhirContext.forDstu1();
|
||||
mtCtx = FhirContext.forDstu1();
|
||||
|
||||
httpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ctx.getRestfulClientFactory().setHttpClient(httpClient);
|
||||
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
mtCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
mtCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
|
||||
httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
@ -58,12 +58,12 @@ public class BinaryClientTest {
|
|||
@Test
|
||||
public void testRead() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", "foo/bar"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 }));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
IClient client = mtCtx.newRestfulClient(IClient.class, "http://foo");
|
||||
Binary resp = client.read(new IdDt("http://foo/Patient/123"));
|
||||
|
||||
assertEquals(HttpGet.class, capt.getValue().getClass());
|
||||
|
@ -81,12 +81,12 @@ public class BinaryClientTest {
|
|||
res.setContentType("text/plain");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] {}));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
IClient client = mtCtx.newRestfulClient(IClient.class, "http://foo");
|
||||
client.create(res);
|
||||
|
||||
assertEquals(HttpPost.class, capt.getValue().getClass());
|
||||
|
|
|
@ -74,11 +74,14 @@ public class LoggingInterceptorTest {
|
|||
public void testLogger() throws Exception {
|
||||
System.out.println("Starting testLogger");
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort);
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
|
||||
LoggingInterceptor interceptor = new LoggingInterceptor(true);
|
||||
client.registerInterceptor(interceptor);
|
||||
Patient patient = client.read(Patient.class, "1");
|
||||
assertFalse(patient.getIdentifierFirstRep().isEmpty());
|
||||
|
||||
verify(myMockAppender, atLeastOnce()).doAppend(argThat(new ArgumentMatcher<ILoggingEvent>() {
|
||||
verify(myMockAppender, times(1)).doAppend(argThat(new ArgumentMatcher<ILoggingEvent>() {
|
||||
@Override
|
||||
public boolean matches(final Object argument) {
|
||||
String formattedMessage = ((LoggingEvent) argument).getFormattedMessage();
|
||||
|
@ -86,6 +89,22 @@ public class LoggingInterceptorTest {
|
|||
return formattedMessage.replace("; ", ";").toLowerCase().contains("Content-Type: application/xml+fhir;charset=utf-8".toLowerCase());
|
||||
}
|
||||
}));
|
||||
|
||||
// Unregister the interceptor
|
||||
client.unregisterInterceptor(interceptor);
|
||||
|
||||
patient = client.read(Patient.class, "1");
|
||||
assertFalse(patient.getIdentifierFirstRep().isEmpty());
|
||||
|
||||
verify(myMockAppender, times(1)).doAppend(argThat(new ArgumentMatcher<ILoggingEvent>() {
|
||||
@Override
|
||||
public boolean matches(final Object argument) {
|
||||
String formattedMessage = ((LoggingEvent) argument).getFormattedMessage();
|
||||
System.out.println("Verifying: " + formattedMessage);
|
||||
return formattedMessage.replace("; ", ";").toLowerCase().contains("Content-Type: application/xml+fhir;charset=utf-8".toLowerCase());
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
|
@ -15,11 +15,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
|
@ -32,16 +28,8 @@ import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
|||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.dstu3.model.Binary;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
|
||||
import org.hl7.fhir.dstu3.model.Conformance;
|
||||
import org.hl7.fhir.dstu3.model.Device;
|
||||
import org.hl7.fhir.dstu3.model.Encounter;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.hl7.fhir.dstu3.model.OperationOutcome;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
|
@ -102,6 +90,62 @@ public class GenericClientDstu3Test {
|
|||
return "HAPI-FHIR/" + VersionUtil.getVersion() + " (FHIR Client; FHIR " + FhirVersionEnum.DSTU3.getFhirVersionString() + "/DSTU3; apache)";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCustomTypeFromClientSearch() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Bundle b = new Bundle();
|
||||
|
||||
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
||||
patient.setId("123");
|
||||
patient.getText().setDivAsString("OK!");
|
||||
b.addEntry().setResource(patient);
|
||||
|
||||
|
||||
final String respString = p.encodeResourceToString(b);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
Bundle bundle = client.search().forResource(MyPatientWithExtensions.class).returnBundle(Bundle.class).execute();
|
||||
|
||||
assertEquals(1, bundle.getEntry().size());
|
||||
assertEquals(MyPatientWithExtensions.class, bundle.getEntry().get(0).getResource().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCustomTypeFromClientRead() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
||||
patient.setId("123");
|
||||
patient.getText().setDivAsString("OK!");
|
||||
|
||||
final String respString = p.encodeResourceToString(patient);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
MyPatientWithExtensions read = client.read().resource(MyPatientWithExtensions.class).withId(new IdType("1")).execute();
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", read.getText().getDivAsString());
|
||||
}
|
||||
|
||||
private byte[] extractBodyAsByteArray(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
||||
byte[] body = IOUtils.toByteArray(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent());
|
||||
return body;
|
||||
|
|
|
@ -7,6 +7,7 @@ import static org.mockito.Mockito.when;
|
|||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
|
@ -17,6 +18,8 @@ import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
|||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.OperationOutcome;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -31,8 +34,7 @@ import org.mockito.stubbing.Answer;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Validate;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
|
@ -60,6 +62,62 @@ public class NonGenericClientDstu3Test {
|
|||
return body;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCustomTypeFromClientSearch() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Bundle b = new Bundle();
|
||||
|
||||
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
||||
patient.setId("123");
|
||||
patient.getText().setDivAsString("OK!");
|
||||
b.addEntry().setResource(patient);
|
||||
|
||||
|
||||
final String respString = p.encodeResourceToString(b);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IClientWithCustomType client = ourCtx.newRestfulClient(IClientWithCustomType.class, "http://example.com/fhir");
|
||||
List<MyPatientWithExtensions> list = client.search();
|
||||
|
||||
assertEquals(1, list.size());
|
||||
assertEquals(MyPatientWithExtensions.class, list.get(0).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCustomTypeFromClientRead() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
||||
patient.setId("123");
|
||||
patient.getText().setDivAsString("OK!");
|
||||
|
||||
final String respString = p.encodeResourceToString(patient);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IClientWithCustomType client = ourCtx.newRestfulClient(IClientWithCustomType.class, "http://example.com/fhir");
|
||||
MyPatientWithExtensions read = client.read(new IdType("1"));
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", read.getText().getDivAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateResourceOnly() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
@ -102,21 +160,31 @@ public class NonGenericClientDstu3Test {
|
|||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forDstu3();
|
||||
}
|
||||
|
||||
private interface IClient extends IRestfulClient {
|
||||
|
||||
@Validate
|
||||
MethodOutcome validate(@ResourceParam IBaseResource theResource, @Validate.Mode ValidationModeEnum theMode, @Validate.Profile String theProfile);
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forDstu3();
|
||||
private interface IClientWithCustomType extends IRestfulClient {
|
||||
|
||||
@Search
|
||||
List<MyPatientWithExtensions> search();
|
||||
|
||||
@Read
|
||||
MyPatientWithExtensions read(@IdParam IdType theId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -123,6 +123,10 @@
|
|||
conditional deletes which did not find any matches,
|
||||
per FHIR-I decision.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Client that declares explicitly that it is searching/reading/etc for
|
||||
a custom type did not automatically parse into that type.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.6" date="2016-07-07">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue