More test coverage
This commit is contained in:
parent
b3d8d453de
commit
a7cbb5c022
|
@ -721,7 +721,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
protected IBaseResource parseResourceBody(String theResourceBody) {
|
||||
EncodingEnum encoding = MethodUtil.detectEncodingNoDefault(theResourceBody);
|
||||
if (encoding == null) {
|
||||
throw new InvalidRequestException("FHIR client can't determine resource encoding");
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType"));
|
||||
}
|
||||
return encoding.newParser(myContext).parseResource(theResourceBody);
|
||||
}
|
||||
|
@ -2220,7 +2220,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
myRawBundle = theBundle;
|
||||
myRawBundleEncoding = MethodUtil.detectEncodingNoDefault(myRawBundle);
|
||||
if (myRawBundleEncoding == null) {
|
||||
throw new IllegalArgumentException("Can not determine encoding of raw resource body");
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2431,7 +2431,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
EncodingEnum enc = MethodUtil.detectEncodingNoDefault(theResourceRaw);
|
||||
if (enc == null) {
|
||||
throw new IllegalArgumentException("Could not detect encoding (XML/JSON) in string. Is this a valid FHIR resource?");
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType"));
|
||||
}
|
||||
switch (enc) {
|
||||
case XML:
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -200,9 +201,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
|
|||
if (myParams != null) {
|
||||
return httpClient.createParamRequest(getContext(), myParams, encoding);
|
||||
} else {
|
||||
if (encoding == null) {
|
||||
encoding = EncodingEnum.XML;
|
||||
}
|
||||
encoding = ObjectUtils.defaultIfNull(encoding, EncodingEnum.XML);
|
||||
String contents = encodeContents(thePrettyPrint, encoding);
|
||||
String contentType = getContentType(encoding);
|
||||
return httpClient.createByteRequest(getContext(), contents, contentType, encoding);
|
||||
|
|
|
@ -36,6 +36,7 @@ import java.util.Set;
|
|||
import java.util.TreeSet;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
|
@ -45,7 +46,6 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
|||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
|
@ -232,7 +232,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
return resource;
|
||||
case METHOD_OUTCOME:
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
retVal.setOperationOutcome((BaseOperationOutcome) resource);
|
||||
retVal.setOperationOutcome((IBaseOperationOutcome) resource);
|
||||
return retVal;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -6,10 +6,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
import java.io.IOException;
|
||||
import java.io.PushbackReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -23,6 +21,7 @@ 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;
|
||||
|
@ -46,7 +45,6 @@ import ca.uhn.fhir.model.api.TagList;
|
|||
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.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.annotation.At;
|
||||
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||
|
@ -89,7 +87,9 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
|
|||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.SearchParameterMap;
|
||||
import ca.uhn.fhir.util.DateUtils;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
|
@ -113,6 +113,12 @@ import ca.uhn.fhir.util.ReflectionUtil;
|
|||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MethodUtil {
|
||||
|
||||
/** Non instantiable */
|
||||
private MethodUtil() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
private static final String LABEL = "label=\"";
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MethodUtil.class);
|
||||
|
||||
|
@ -132,19 +138,14 @@ public class MethodUtil {
|
|||
}
|
||||
|
||||
|
||||
public static IIdType convertIdToType(IIdType value, Class<? extends IIdType> idParamType) {
|
||||
if (value != null && !idParamType.isAssignableFrom(value.getClass())) {
|
||||
try {
|
||||
IIdType newValue = idParamType.newInstance();
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends IIdType> T convertIdToType(IIdType value, Class<T> theIdParamType) {
|
||||
if (value != null && !theIdParamType.isAssignableFrom(value.getClass())) {
|
||||
IIdType newValue = ReflectionUtil.newInstance(theIdParamType);
|
||||
newValue.setValue(value.getValue());
|
||||
value = newValue;
|
||||
} catch (InstantiationException e) {
|
||||
throw new ConfigurationException("Failed to instantiate " + idParamType, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ConfigurationException("Failed to instantiate " + idParamType, e);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
public static HttpGetClientInvocation createConformanceInvocation(FhirContext theContext) {
|
||||
|
@ -212,13 +213,9 @@ public class MethodUtil {
|
|||
for (String nextValue : nextEntry.getValue()) {
|
||||
b.append(haveQuestionMark ? '&' : '?');
|
||||
haveQuestionMark = true;
|
||||
try {
|
||||
b.append(URLEncoder.encode(nextEntry.getKey(), "UTF-8"));
|
||||
b.append(UrlUtil.escape(nextEntry.getKey()));
|
||||
b.append('=');
|
||||
b.append(URLEncoder.encode(nextValue, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ConfigurationException("UTF-8 not supported on this platform");
|
||||
}
|
||||
b.append(UrlUtil.escape(nextValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,9 +284,7 @@ public class MethodUtil {
|
|||
|
||||
public static EncodingEnum detectEncoding(String theBody) {
|
||||
EncodingEnum retVal = detectEncodingNoDefault(theBody);
|
||||
if (retVal == null) {
|
||||
retVal = EncodingEnum.XML;
|
||||
}
|
||||
retVal = ObjectUtils.defaultIfNull(retVal, EncodingEnum.XML);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -321,10 +316,6 @@ public class MethodUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static Integer findConditionalOperationParameterIndex(Method theMethod) {
|
||||
return MethodUtil.findParamAnnotationIndex(theMethod, ConditionalUrlParam.class);
|
||||
}
|
||||
|
||||
public static Integer findIdParameterIndex(Method theMethod, FhirContext theContext) {
|
||||
Integer index = MethodUtil.findParamAnnotationIndex(theMethod, IdParam.class);
|
||||
if (index != null) {
|
||||
|
@ -365,7 +356,7 @@ public class MethodUtil {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<IParameter> getResourceParameters(FhirContext theContext, Method theMethod, Object theProvider, RestOperationTypeEnum theRestfulOperationTypeEnum) {
|
||||
public static List<IParameter> getResourceParameters(final FhirContext theContext, Method theMethod, Object theProvider, RestOperationTypeEnum theRestfulOperationTypeEnum) {
|
||||
List<IParameter> parameters = new ArrayList<IParameter>();
|
||||
|
||||
Class<?>[] parameterTypes = theMethod.getParameterTypes();
|
||||
|
@ -514,7 +505,7 @@ public class MethodUtil {
|
|||
|
||||
@Override
|
||||
public Object outgoingClient(Object theObject) {
|
||||
return new StringDt(((ValidationModeEnum)theObject).getCode());
|
||||
return ParametersUtil.createString(theContext, ((ValidationModeEnum)theObject).getCode());
|
||||
}
|
||||
});
|
||||
} else if (nextAnnotation instanceof Validate.Profile) {
|
||||
|
@ -529,7 +520,7 @@ public class MethodUtil {
|
|||
|
||||
@Override
|
||||
public Object outgoingClient(Object theObject) {
|
||||
return new StringDt(theObject.toString());
|
||||
return ParametersUtil.createString(theContext, theObject.toString());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -10,6 +10,7 @@ ca.uhn.fhir.context.RuntimeResourceDefinition.nonInstantiableType=Resource type
|
|||
ca.uhn.fhir.rest.client.BaseClient.ioExceptionDuringOperation=Encountered IOException when performing {0} to URL {1} - {2}
|
||||
ca.uhn.fhir.rest.client.BaseClient.failedToParseResponse=Failed to parse response from server when performing {0} to URL {1} - {2}
|
||||
|
||||
ca.uhn.fhir.rest.client.GenericClient.cantDetermineRequestType=Unable to determing encoding of request (body does not appear to be valid XML or JSON)
|
||||
ca.uhn.fhir.rest.client.GenericClient.noPagingLinkFoundInBundle=Can not perform paging operation because no link was found in Bundle with relation "{0}"
|
||||
ca.uhn.fhir.rest.client.GenericClient.noVersionIdForVread=No version specified in URL for 'vread' operation: {0}
|
||||
ca.uhn.fhir.rest.client.GenericClient.incompleteUriForRead=The given URI is not an absolute URL and is not usable for this operation: {0}
|
||||
|
|
|
@ -51,8 +51,13 @@ public class DaoConfig {
|
|||
// ***
|
||||
// update setter javadoc if default changes
|
||||
// ***
|
||||
private int myDeferIndexingForCodesystemsOfSize = 100;
|
||||
// ***
|
||||
// update setter javadoc if default changes
|
||||
// ***
|
||||
private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR;
|
||||
private int myHardSearchLimit = 1000;
|
||||
|
||||
private int myHardTagListLimit = 1000;
|
||||
|
||||
private int myIncludeLimit = 2000;
|
||||
|
@ -63,13 +68,13 @@ public class DaoConfig {
|
|||
private boolean myIndexContainedResources = true;
|
||||
|
||||
private List<IServerInterceptor> myInterceptors;
|
||||
|
||||
// ***
|
||||
// update setter javadoc if default changes
|
||||
// ***
|
||||
private int myMaximumExpansionSize = 5000;
|
||||
|
||||
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
||||
|
||||
private boolean mySchedulingDisabled;
|
||||
|
||||
private boolean mySubscriptionEnabled;
|
||||
|
@ -77,8 +82,20 @@ public class DaoConfig {
|
|||
private long mySubscriptionPollDelay = 1000;
|
||||
|
||||
private Long mySubscriptionPurgeInactiveAfterMillis;
|
||||
|
||||
private Set<String> myTreatBaseUrlsAsLocal = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* When a code system is added that contains more than this number of codes,
|
||||
* the code system will be indexed later in an incremental process in order to
|
||||
* avoid overwhelming Lucene with a huge number of codes in a single operation.
|
||||
* <p>
|
||||
* Defaults to 100
|
||||
* </p>
|
||||
*/
|
||||
public int getDeferIndexingForCodesystemsOfSize() {
|
||||
return myDeferIndexingForCodesystemsOfSize;
|
||||
}
|
||||
/**
|
||||
* Sets the number of milliseconds that search results for a given client search
|
||||
* should be preserved before being purged from the database.
|
||||
|
@ -117,6 +134,7 @@ public class DaoConfig {
|
|||
}
|
||||
return myInterceptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #setMaximumExpansionSize(int)}
|
||||
*/
|
||||
|
@ -180,7 +198,6 @@ public class DaoConfig {
|
|||
public boolean isAllowInlineMatchUrlReferences() {
|
||||
return myAllowInlineMatchUrlReferences;
|
||||
}
|
||||
|
||||
public boolean isAllowMultipleDelete() {
|
||||
return myAllowMultipleDelete;
|
||||
}
|
||||
|
@ -251,6 +268,18 @@ public class DaoConfig {
|
|||
myAllowMultipleDelete = theAllowMultipleDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a code system is added that contains more than this number of codes,
|
||||
* the code system will be indexed later in an incremental process in order to
|
||||
* avoid overwhelming Lucene with a huge number of codes in a single operation.
|
||||
* <p>
|
||||
* Defaults to 100
|
||||
* </p>
|
||||
*/
|
||||
public void setDeferIndexingForCodesystemsOfSize(int theDeferIndexingForCodesystemsOfSize) {
|
||||
myDeferIndexingForCodesystemsOfSize = theDeferIndexingForCodesystemsOfSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of milliseconds that search results for a given client search
|
||||
* should be preserved before being purged from the database.
|
||||
|
|
|
@ -71,7 +71,6 @@ import ca.uhn.fhir.jpa.search.DeferConceptIndexingInterceptor;
|
|||
//@formatter:on
|
||||
public class TermConcept implements Serializable {
|
||||
private static final int MAX_DESC_LENGTH = 400;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@OneToMany(fetch=FetchType.LAZY, mappedBy="myParent")
|
||||
|
@ -189,6 +188,10 @@ public class TermConcept implements Serializable {
|
|||
return myId;
|
||||
}
|
||||
|
||||
public Long getIndexStatus() {
|
||||
return myIndexStatus;
|
||||
}
|
||||
|
||||
public Collection<TermConceptParentChildLink> getParents() {
|
||||
if (myParents == null) {
|
||||
myParents = new ArrayList<TermConceptParentChildLink>();
|
||||
|
|
|
@ -1,9 +1,32 @@
|
|||
package ca.uhn.fhir.jpa.search;
|
||||
|
||||
import org.hibernate.search.indexes.interceptor.DontInterceptEntityInterceptor;
|
||||
import org.hibernate.search.indexes.interceptor.EntityIndexingInterceptor;
|
||||
import org.hibernate.search.indexes.interceptor.IndexingOverride;
|
||||
|
||||
public class DeferConceptIndexingInterceptor extends DontInterceptEntityInterceptor
|
||||
//implements EntityIndexingInterceptor<TermConcept>
|
||||
{
|
||||
// nothing for now
|
||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||
|
||||
public class DeferConceptIndexingInterceptor implements EntityIndexingInterceptor<TermConcept> {
|
||||
|
||||
@Override
|
||||
public IndexingOverride onAdd(TermConcept theEntity) {
|
||||
if (theEntity.getIndexStatus() == null) {
|
||||
return IndexingOverride.SKIP;
|
||||
}
|
||||
return IndexingOverride.APPLY_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexingOverride onUpdate(TermConcept theEntity) {
|
||||
return onAdd(theEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexingOverride onDelete(TermConcept theEntity) {
|
||||
return IndexingOverride.APPLY_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexingOverride onCollectionUpdate(TermConcept theEntity) {
|
||||
return IndexingOverride.APPLY_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,9 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
|||
}
|
||||
|
||||
theConcept.setCodeSystem(theCodeSystem);
|
||||
if (theTotalConcepts < myDaoConfig.getDeferIndexingForCodesystemsOfSize()) {
|
||||
theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
|
||||
}
|
||||
|
||||
myConceptDao.save(theConcept);
|
||||
for (TermConceptParentChildLink next : theConcept.getChildren()) {
|
||||
|
|
|
@ -174,7 +174,7 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
|||
} else if (nextFilter.getOp() == FilterOperator.ISA) {
|
||||
if (isNotBlank(nextFilter.getValue())) {
|
||||
TermConcept code = super.findCode(system, nextFilter.getValue());
|
||||
bool.must(qb.keyword().onField("myParentPids").matching(code.getId()).createQuery());
|
||||
bool.must(qb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
||||
}
|
||||
} else {
|
||||
throw new InvalidRequestException("Unknown filter property[" + nextFilter + "] + op[" + nextFilter.getOpElement().getValueAsString() + "]");
|
||||
|
|
|
@ -9,7 +9,6 @@ import static org.junit.Assert.fail;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.AuditEvent;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
|
@ -22,11 +21,13 @@ import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
|
|||
import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||
|
@ -339,6 +340,25 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
|||
assertEquals(URL_MY_CODE_SYSTEM, result.getExpansion().getContains().get(idx).getSystem());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexingIsDeferredForLargeCodeSystems() {
|
||||
myDaoConfig.setDeferIndexingForCodesystemsOfSize(1);
|
||||
|
||||
createExternalCsAndLocalVs();
|
||||
|
||||
ValueSet vs = new ValueSet();
|
||||
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||
|
||||
include.addFilter().setProperty("display").setOp(FilterOperator.ISA).setValue("ParentA");
|
||||
|
||||
ValueSet result = myValueSetDao.expand(vs, null);
|
||||
|
||||
String encoded = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result);
|
||||
ourLog.info(encoded);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithExcludeInExternalValueSet() {
|
||||
createExternalCsAndLocalVs();
|
||||
|
@ -487,6 +507,11 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
|||
myDaoConfig.setMaximumExpansionSize(5000);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myDaoConfig.setDeferIndexingForCodesystemsOfSize(new DaoConfig().getDeferIndexingForCodesystemsOfSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchCodeBelowLocalCodesystem() {
|
||||
createLocalCsAndVs();
|
||||
|
|
|
@ -18,6 +18,7 @@ import ca.uhn.fhir.rest.annotation.Operation;
|
|||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.annotation.Validate;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
@ -62,6 +63,51 @@ public class ServerInvalidDefinitionDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongResourceType() {
|
||||
RestfulServer srv = new RestfulServer(ourCtx);
|
||||
srv.setFhirContext(ourCtx);
|
||||
srv.setResourceProviders(new UpdateWithWrongResourceType());
|
||||
|
||||
try {
|
||||
srv.init();
|
||||
fail();
|
||||
} catch (ServletException e) {
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("ConfigurationException"));
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("Method 'update' is annotated with @ResourceParam but has a type that is not an implemtation of org.hl7.fhir.instance.model.api.IBaseResource or String or byte[]"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongValidateModeType() {
|
||||
RestfulServer srv = new RestfulServer(ourCtx);
|
||||
srv.setFhirContext(ourCtx);
|
||||
srv.setResourceProviders(new ValidateWithWrongModeType());
|
||||
|
||||
try {
|
||||
srv.init();
|
||||
fail();
|
||||
} catch (ServletException e) {
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("ConfigurationException"));
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("Parameter annotated with @Validate.Mode must be of type ca.uhn.fhir.rest.api.ValidationModeEnum"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongValidateProfileType() {
|
||||
RestfulServer srv = new RestfulServer(ourCtx);
|
||||
srv.setFhirContext(ourCtx);
|
||||
srv.setResourceProviders(new ValidateWithWrongProfileType());
|
||||
|
||||
try {
|
||||
srv.init();
|
||||
fail();
|
||||
} catch (ServletException e) {
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("ConfigurationException"));
|
||||
assertThat(e.getCause().toString(), StringContains.containsString("Parameter annotated with @Validate.Profile must be of type java.lang.String"));
|
||||
}
|
||||
}
|
||||
|
||||
public static class OperationReturningOldBundleProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
|
@ -90,4 +136,46 @@ public class ServerInvalidDefinitionDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
public static class UpdateWithWrongResourceType implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Update
|
||||
public MethodOutcome update(@ResourceParam Integer theParam2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ValidateWithWrongModeType implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Validate
|
||||
public MethodOutcome update(@ResourceParam Patient thePatient, @Validate.Mode Integer theParam2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ValidateWithWrongProfileType implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Validate
|
||||
public MethodOutcome update(@ResourceParam Patient thePatient, @Validate.Profile Integer theParam2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1147,6 +1147,45 @@ public class GenericClientDstu3Test {
|
|||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionWithInvalidBody() throws Exception {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
// Transaction
|
||||
try {
|
||||
client.transaction().withBundle("FOO");
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
// Create
|
||||
try {
|
||||
client.create().resource("FOO").execute();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
// Update
|
||||
try {
|
||||
client.update().resource("FOO").execute();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
// Validate
|
||||
try {
|
||||
client.validate().resource("FOO").execute();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateById() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.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.OperationOutcome;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import 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.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class NonGenericClientDstu3Test {
|
||||
private static FhirContext ourCtx;
|
||||
private HttpClient myHttpClient;
|
||||
private HttpResponse myHttpResponse;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
|
||||
System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true");
|
||||
|
||||
}
|
||||
|
||||
private String extractBodyAsString(ArgumentCaptor<HttpUriRequest> capt, int theIdx) throws IOException {
|
||||
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(theIdx)).getEntity().getContent(), "UTF-8");
|
||||
return body;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateResourceOnly() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
OperationOutcome conf = new OperationOutcome();
|
||||
conf.getText().setDivAsString("OK!");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
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"));
|
||||
}
|
||||
});
|
||||
|
||||
IClient client = ourCtx.newRestfulClient(IClient.class, "http://example.com/fhir");
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAM");
|
||||
|
||||
int idx = 0;
|
||||
MethodOutcome outcome = client.validate(patient, null, null);
|
||||
String resp = ourCtx.newXmlParser().encodeResourceToString(outcome.getOperationOutcome());
|
||||
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><text><div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div></text></OperationOutcome>", resp);
|
||||
assertEquals("http://example.com/fhir/$validate", capt.getAllValues().get(idx).getURI().toString());
|
||||
String request = extractBodyAsString(capt,idx);
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><family value=\"FAM\"/></name></Patient></resource></parameter></Parameters>", request);
|
||||
|
||||
idx = 1;
|
||||
outcome = client.validate(patient, ValidationModeEnum.CREATE, "http://foo");
|
||||
resp = ourCtx.newXmlParser().encodeResourceToString(outcome.getOperationOutcome());
|
||||
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><text><div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div></text></OperationOutcome>", resp);
|
||||
assertEquals("http://example.com/fhir/$validate", capt.getAllValues().get(idx).getURI().toString());
|
||||
request = extractBodyAsString(capt,idx);
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><family value=\"FAM\"/></name></Patient></resource></parameter><parameter><name value=\"mode\"/><valueString value=\"create\"/></parameter><parameter><name value=\"profile\"/><valueString value=\"http://foo\"/></parameter></Parameters>", request);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
public class MethodUtilTest {
|
||||
|
||||
@Test
|
||||
public void testConvertIdToType() {
|
||||
IdDt id = new IdDt("Patient/123");
|
||||
IdType id2 = MethodUtil.convertIdToType(id, IdType.class);
|
||||
assertEquals("Patient/123", id2.getValue());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue