Merge branch 'master' into jaxrs-client
This commit is contained in:
commit
69450c7dab
|
@ -70,6 +70,8 @@ import ca.uhn.fhir.model.api.IResourceBlock;
|
||||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||||
import ca.uhn.fhir.model.api.annotation.Block;
|
import ca.uhn.fhir.model.api.annotation.Block;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Compartment;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Compartments;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
import ca.uhn.fhir.model.api.annotation.Description;
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||||
|
@ -87,7 +89,6 @@ import ca.uhn.fhir.util.ReflectionUtil;
|
||||||
class ModelScanner {
|
class ModelScanner {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
|
||||||
|
|
||||||
private final Map<Class<? extends Annotation>, Class<? extends Annotation>> myAnnotationForwards = new HashMap<Class<? extends Annotation>, Class<? extends Annotation>>();
|
|
||||||
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>();
|
private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<String, RuntimeResourceDefinition>();
|
||||||
|
@ -101,7 +102,8 @@ class ModelScanner {
|
||||||
|
|
||||||
private Set<Class<? extends IBase>> myVersionTypes;
|
private Set<Class<? extends IBase>> myVersionTypes;
|
||||||
|
|
||||||
ModelScanner(FhirContext theContext, FhirVersionEnum theVersion, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions, Collection<Class<? extends IElement>> theResourceTypes) throws ConfigurationException {
|
ModelScanner(FhirContext theContext, FhirVersionEnum theVersion, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theExistingDefinitions,
|
||||||
|
Collection<Class<? extends IElement>> theResourceTypes) throws ConfigurationException {
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
myVersion = theVersion;
|
myVersion = theVersion;
|
||||||
Set<Class<? extends IBase>> toScan;
|
Set<Class<? extends IBase>> toScan;
|
||||||
|
@ -233,68 +235,13 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There are two implementations of all of the annotations (e.g. {@link Child} and
|
* There are two implementations of all of the annotations (e.g. {@link Child} and {@link org.hl7.fhir.instance.model.annotations.Child}) since the HL7.org ones will eventually replace the HAPI
|
||||||
* {@link org.hl7.fhir.instance.model.annotations.Child}) since the HL7.org ones will eventually replace the HAPI
|
* ones. Annotations can't extend each other or implement interfaces or anything like that, so rather than duplicate all of the annotation processing code this method just creates an interface
|
||||||
* ones. Annotations can't extend each other or implement interfaces or anything like that, so rather than duplicate
|
* Proxy to simulate the HAPI annotations if the HL7.org ones are found instead.
|
||||||
* all of the annotation processing code this method just creates an interface Proxy to simulate the HAPI
|
|
||||||
* annotations if the HL7.org ones are found instead.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
private <T extends Annotation> T pullAnnotation(AnnotatedElement theTarget, Class<T> theAnnotationType) {
|
||||||
private <T extends Annotation> T pullAnnotation(Class<?> theContainer, AnnotatedElement theTarget, Class<T> theAnnotationType) {
|
|
||||||
|
|
||||||
T retVal = theTarget.getAnnotation(theAnnotationType);
|
T retVal = theTarget.getAnnotation(theAnnotationType);
|
||||||
// if (myContext.getVersion().getVersion() != FhirVersionEnum.DSTU2_HL7ORG) {
|
|
||||||
return retVal;
|
return retVal;
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (retVal == null) {
|
|
||||||
// final Class<? extends Annotation> altAnnotationClass;
|
|
||||||
// /*
|
|
||||||
// * Use a cache to minimize Class.forName calls, since they are slow and expensive..
|
|
||||||
// */
|
|
||||||
// if (myAnnotationForwards.containsKey(theAnnotationType) == false) {
|
|
||||||
// String sourceClassName = theAnnotationType.getName();
|
|
||||||
// String candidateAltClassName = sourceClassName.replace("ca.uhn.fhir.model.api.annotation", "org.hl7.fhir.instance.model.annotations");
|
|
||||||
// if (!sourceClassName.equals(candidateAltClassName)) {
|
|
||||||
// Class<?> forName;
|
|
||||||
// try {
|
|
||||||
// forName = Class.forName(candidateAltClassName);
|
|
||||||
// ourLog.debug("Forwarding annotation request for [{}] to class [{}]", theAnnotationType, forName);
|
|
||||||
// } catch (ClassNotFoundException e) {
|
|
||||||
// forName = null;
|
|
||||||
// }
|
|
||||||
// altAnnotationClass = (Class<? extends Annotation>) forName;
|
|
||||||
// } else {
|
|
||||||
// altAnnotationClass = null;
|
|
||||||
// }
|
|
||||||
// myAnnotationForwards.put(theAnnotationType, altAnnotationClass);
|
|
||||||
// } else {
|
|
||||||
// altAnnotationClass = myAnnotationForwards.get(theAnnotationType);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (altAnnotationClass == null) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// final Annotation altAnnotation;
|
|
||||||
// altAnnotation = theTarget.getAnnotation(altAnnotationClass);
|
|
||||||
// if (altAnnotation == null) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// InvocationHandler h = new InvocationHandler() {
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
|
|
||||||
// Method altMethod = altAnnotationClass.getMethod(theMethod.getName(), theMethod.getParameterTypes());
|
|
||||||
// return altMethod.invoke(altAnnotation, theArgs);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// retVal = (T) Proxy.newProxyInstance(theAnnotationType.getClassLoader(), new Class<?>[] { theAnnotationType }, h);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scan(Class<? extends IBase> theClass) throws ConfigurationException {
|
private void scan(Class<? extends IBase> theClass) throws ConfigurationException {
|
||||||
|
@ -303,17 +250,18 @@ class ModelScanner {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceDef resourceDefinition = pullAnnotation(theClass, theClass, ResourceDef.class);
|
ResourceDef resourceDefinition = pullAnnotation(theClass, ResourceDef.class);
|
||||||
if (resourceDefinition != null) {
|
if (resourceDefinition != null) {
|
||||||
if (!IBaseResource.class.isAssignableFrom(theClass)) {
|
if (!IBaseResource.class.isAssignableFrom(theClass)) {
|
||||||
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
throw new ConfigurationException(
|
||||||
|
"Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<? extends IBaseResource> resClass = (Class<? extends IBaseResource>) theClass;
|
Class<? extends IBaseResource> resClass = (Class<? extends IBaseResource>) theClass;
|
||||||
scanResource(resClass, resourceDefinition);
|
scanResource(resClass, resourceDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
DatatypeDef datatypeDefinition = pullAnnotation(theClass, theClass, DatatypeDef.class);
|
DatatypeDef datatypeDefinition = pullAnnotation(theClass, DatatypeDef.class);
|
||||||
if (datatypeDefinition != null) {
|
if (datatypeDefinition != null) {
|
||||||
if (ICompositeType.class.isAssignableFrom(theClass)) {
|
if (ICompositeType.class.isAssignableFrom(theClass)) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -325,17 +273,19 @@ class ModelScanner {
|
||||||
scanPrimitiveDatatype(resClass, datatypeDefinition);
|
scanPrimitiveDatatype(resClass, datatypeDefinition);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
// throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
// throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " +
|
||||||
|
// theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Block blockDefinition = pullAnnotation(theClass, theClass, Block.class);
|
Block blockDefinition = pullAnnotation(theClass, Block.class);
|
||||||
|
|
||||||
if (blockDefinition != null) {
|
if (blockDefinition != null) {
|
||||||
if (IResourceBlock.class.isAssignableFrom(theClass) || IBaseBackboneElement.class.isAssignableFrom(theClass) || IBaseDatatypeElement.class.isAssignableFrom(theClass)) {
|
if (IResourceBlock.class.isAssignableFrom(theClass) || IBaseBackboneElement.class.isAssignableFrom(theClass) || IBaseDatatypeElement.class.isAssignableFrom(theClass)) {
|
||||||
scanBlock(theClass);
|
scanBlock(theClass);
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationException("Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
throw new ConfigurationException(
|
||||||
|
"Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": " + theClass.getCanonicalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,8 +314,8 @@ class ModelScanner {
|
||||||
RuntimeCompositeDatatypeDefinition resourceDef;
|
RuntimeCompositeDatatypeDefinition resourceDef;
|
||||||
if (theClass.equals(ExtensionDt.class)) {
|
if (theClass.equals(ExtensionDt.class)) {
|
||||||
resourceDef = new RuntimeExtensionDtDefinition(theDatatypeDefinition, theClass, true);
|
resourceDef = new RuntimeExtensionDtDefinition(theDatatypeDefinition, theClass, true);
|
||||||
// } else if (IBaseMetaType.class.isAssignableFrom(theClass)) {
|
// } else if (IBaseMetaType.class.isAssignableFrom(theClass)) {
|
||||||
// resourceDef = new RuntimeMetaDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
|
// resourceDef = new RuntimeMetaDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
|
||||||
} else {
|
} else {
|
||||||
resourceDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
|
resourceDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
|
||||||
}
|
}
|
||||||
|
@ -429,7 +379,8 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void scanCompositeElementForChildren(Class<? extends IBase> theClass, Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
|
private void scanCompositeElementForChildren(Class<? extends IBase> theClass, Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef,
|
||||||
|
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
|
||||||
int baseElementOrder = theOrderToElementDef.isEmpty() ? 0 : theOrderToElementDef.lastEntry().getKey() + 1;
|
int baseElementOrder = theOrderToElementDef.isEmpty() ? 0 : theOrderToElementDef.lastEntry().getKey() + 1;
|
||||||
|
|
||||||
for (Field next : theClass.getDeclaredFields()) {
|
for (Field next : theClass.getDeclaredFields()) {
|
||||||
|
@ -439,16 +390,16 @@ class ModelScanner {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Child childAnnotation = pullAnnotation(theClass, next, Child.class);
|
Child childAnnotation = pullAnnotation(next, Child.class);
|
||||||
if (childAnnotation == null) {
|
if (childAnnotation == null) {
|
||||||
ourLog.trace("Ignoring non @Child field {} on target type {}", next.getName(), theClass);
|
ourLog.trace("Ignoring non @Child field {} on target type {}", next.getName(), theClass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Description descriptionAnnotation = pullAnnotation(theClass, next, Description.class);
|
Description descriptionAnnotation = pullAnnotation(next, Description.class);
|
||||||
|
|
||||||
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> orderMap = theOrderToElementDef;
|
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> orderMap = theOrderToElementDef;
|
||||||
Extension extensionAttr = pullAnnotation(theClass, next, Extension.class);
|
Extension extensionAttr = pullAnnotation(next, Extension.class);
|
||||||
if (extensionAttr != null) {
|
if (extensionAttr != null) {
|
||||||
orderMap = theOrderToExtensionDef;
|
orderMap = theOrderToExtensionDef;
|
||||||
}
|
}
|
||||||
|
@ -471,8 +422,8 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order == Child.REPLACE_PARENT) {
|
if (order == Child.REPLACE_PARENT) {
|
||||||
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT + ") but no parent element with extension URL " + extensionAttr.url() + " could be found on type "
|
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT
|
||||||
+ next.getDeclaringClass().getSimpleName());
|
+ ") but no parent element with extension URL " + extensionAttr.url() + " could be found on type " + next.getDeclaringClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -487,8 +438,8 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order == Child.REPLACE_PARENT) {
|
if (order == Child.REPLACE_PARENT) {
|
||||||
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT + ") but no parent element with name " + elementName + " could be found on type "
|
throw new ConfigurationException("Field " + next.getName() + "' on target type " + theClass.getSimpleName() + " has order() of REPLACE_PARENT (" + Child.REPLACE_PARENT
|
||||||
+ next.getDeclaringClass().getSimpleName());
|
+ ") but no parent element with name " + elementName + " could be found on type " + next.getDeclaringClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -504,8 +455,7 @@ class ModelScanner {
|
||||||
// int max = childAnnotation.max();
|
// int max = childAnnotation.max();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict with any given
|
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict with any given IDs and can be figured out later
|
||||||
* IDs and can be figured out later
|
|
||||||
*/
|
*/
|
||||||
if (order == Child.ORDER_UNKNOWN) {
|
if (order == Child.ORDER_UNKNOWN) {
|
||||||
order = Integer.MIN_VALUE;
|
order = Integer.MIN_VALUE;
|
||||||
|
@ -572,7 +522,8 @@ class ModelScanner {
|
||||||
binder = getBoundCodeBinder(next);
|
binder = getBoundCodeBinder(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et, binder);
|
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et,
|
||||||
|
binder);
|
||||||
|
|
||||||
if (IBaseEnumeration.class.isAssignableFrom(nextElementType)) {
|
if (IBaseEnumeration.class.isAssignableFrom(nextElementType)) {
|
||||||
def.setEnumerationType(ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next));
|
def.setEnumerationType(ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next));
|
||||||
|
@ -600,10 +551,10 @@ class ModelScanner {
|
||||||
RuntimeChildResourceDefinition def = new RuntimeChildResourceDefinition(next, elementName, childAnnotation, descriptionAnnotation, refTypesList);
|
RuntimeChildResourceDefinition def = new RuntimeChildResourceDefinition(next, elementName, childAnnotation, descriptionAnnotation, refTypesList);
|
||||||
orderMap.put(order, def);
|
orderMap.put(order, def);
|
||||||
|
|
||||||
} else if (IResourceBlock.class.isAssignableFrom(nextElementType) || IBaseBackboneElement.class.isAssignableFrom(nextElementType) || IBaseDatatypeElement.class.isAssignableFrom(nextElementType)) {
|
} else if (IResourceBlock.class.isAssignableFrom(nextElementType) || IBaseBackboneElement.class.isAssignableFrom(nextElementType)
|
||||||
|
|| IBaseDatatypeElement.class.isAssignableFrom(nextElementType)) {
|
||||||
/*
|
/*
|
||||||
* Child is a resource block (i.e. a sub-tag within a resource) TODO: do these have a better name
|
* Child is a resource block (i.e. a sub-tag within a resource) TODO: do these have a better name according to HL7?
|
||||||
* according to HL7?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Class<? extends IBase> blockDef = (Class<? extends IBase>) nextElementType;
|
Class<? extends IBase> blockDef = (Class<? extends IBase>) nextElementType;
|
||||||
|
@ -611,13 +562,14 @@ class ModelScanner {
|
||||||
RuntimeChildResourceBlockDefinition def = new RuntimeChildResourceBlockDefinition(next, childAnnotation, descriptionAnnotation, elementName, blockDef);
|
RuntimeChildResourceBlockDefinition def = new RuntimeChildResourceBlockDefinition(next, childAnnotation, descriptionAnnotation, elementName, blockDef);
|
||||||
orderMap.put(order, def);
|
orderMap.put(order, def);
|
||||||
|
|
||||||
} else if (IDatatype.class.equals(nextElementType) || IElement.class.equals(nextElementType) || "Type".equals(nextElementType.getSimpleName()) || IBaseDatatype.class.equals(nextElementType)) {
|
} else if (IDatatype.class.equals(nextElementType) || IElement.class.equals(nextElementType) || "Type".equals(nextElementType.getSimpleName())
|
||||||
|
|| IBaseDatatype.class.equals(nextElementType)) {
|
||||||
|
|
||||||
RuntimeChildAny def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation);
|
RuntimeChildAny def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation);
|
||||||
orderMap.put(order, def);
|
orderMap.put(order, def);
|
||||||
|
|
||||||
} else if (IDatatype.class.isAssignableFrom(nextElementType) || IPrimitiveType.class.isAssignableFrom(nextElementType) || ICompositeType.class.isAssignableFrom(nextElementType) || IBaseDatatype.class.isAssignableFrom(nextElementType)
|
} else if (IDatatype.class.isAssignableFrom(nextElementType) || IPrimitiveType.class.isAssignableFrom(nextElementType) || ICompositeType.class.isAssignableFrom(nextElementType)
|
||||||
|| IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
|| IBaseDatatype.class.isAssignableFrom(nextElementType) || IBaseExtension.class.isAssignableFrom(nextElementType)) {
|
||||||
Class<? extends IBase> nextDatatype = (Class<? extends IBase>) nextElementType;
|
Class<? extends IBase> nextDatatype = (Class<? extends IBase>) nextElementType;
|
||||||
|
|
||||||
addScanAlso(nextDatatype);
|
addScanAlso(nextDatatype);
|
||||||
|
@ -645,10 +597,11 @@ class ModelScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeableConceptElement concept = pullAnnotation(theClass, next, CodeableConceptElement.class);
|
CodeableConceptElement concept = pullAnnotation(next, CodeableConceptElement.class);
|
||||||
if (concept != null) {
|
if (concept != null) {
|
||||||
if (!ICodedDatatype.class.isAssignableFrom(nextDatatype)) {
|
if (!ICodedDatatype.class.isAssignableFrom(nextDatatype)) {
|
||||||
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName() + " but type is not a subtype of " + ICodedDatatype.class.getName());
|
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName()
|
||||||
|
+ " but type is not a subtype of " + ICodedDatatype.class.getName());
|
||||||
} else {
|
} else {
|
||||||
Class<? extends ICodeEnum> type = concept.type();
|
Class<? extends ICodeEnum> type = concept.type();
|
||||||
myScanAlsoCodeTable.add(type);
|
myScanAlsoCodeTable.add(type);
|
||||||
|
@ -711,21 +664,23 @@ class ModelScanner {
|
||||||
Class<?> parent = theClass.getSuperclass();
|
Class<?> parent = theClass.getSuperclass();
|
||||||
primaryNameProvider = false;
|
primaryNameProvider = false;
|
||||||
while (parent.equals(Object.class) == false && isBlank(resourceName)) {
|
while (parent.equals(Object.class) == false && isBlank(resourceName)) {
|
||||||
ResourceDef nextDef = pullAnnotation(theClass, parent, ResourceDef.class);
|
ResourceDef nextDef = pullAnnotation(parent, ResourceDef.class);
|
||||||
if (nextDef != null) {
|
if (nextDef != null) {
|
||||||
resourceName = nextDef.name();
|
resourceName = nextDef.name();
|
||||||
}
|
}
|
||||||
parent = parent.getSuperclass();
|
parent = parent.getSuperclass();
|
||||||
}
|
}
|
||||||
if (isBlank(resourceName)) {
|
if (isBlank(resourceName)) {
|
||||||
throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name(): " + theClass.getCanonicalName() + " - This is only allowed for types that extend other resource types ");
|
throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name(): " + theClass.getCanonicalName()
|
||||||
|
+ " - This is only allowed for types that extend other resource types ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourceId = resourceDefinition.id();
|
String resourceId = resourceDefinition.id();
|
||||||
if (!isBlank(resourceId)) {
|
if (!isBlank(resourceId)) {
|
||||||
if (myIdToResourceDefinition.containsKey(resourceId)) {
|
if (myIdToResourceDefinition.containsKey(resourceId)) {
|
||||||
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and " + myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
|
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and "
|
||||||
|
+ myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,7 +706,7 @@ class ModelScanner {
|
||||||
Map<Field, SearchParamDefinition> compositeFields = new LinkedHashMap<Field, SearchParamDefinition>();
|
Map<Field, SearchParamDefinition> compositeFields = new LinkedHashMap<Field, SearchParamDefinition>();
|
||||||
|
|
||||||
for (Field nextField : theClass.getFields()) {
|
for (Field nextField : theClass.getFields()) {
|
||||||
SearchParamDefinition searchParam = pullAnnotation(theClass, nextField, SearchParamDefinition.class);
|
SearchParamDefinition searchParam = pullAnnotation(nextField, SearchParamDefinition.class);
|
||||||
if (searchParam != null) {
|
if (searchParam != null) {
|
||||||
RestSearchParameterTypeEnum paramType = RestSearchParameterTypeEnum.valueOf(searchParam.type().toUpperCase());
|
RestSearchParameterTypeEnum paramType = RestSearchParameterTypeEnum.valueOf(searchParam.type().toUpperCase());
|
||||||
if (paramType == null) {
|
if (paramType == null) {
|
||||||
|
@ -761,7 +716,17 @@ class ModelScanner {
|
||||||
compositeFields.put(nextField, searchParam);
|
compositeFields.put(nextField, searchParam);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), paramType);
|
|
||||||
|
Set<String> providesMembershipInCompartments = null;
|
||||||
|
Compartments compartmentsAnnotation = pullAnnotation(nextField, Compartments.class);
|
||||||
|
if (compartmentsAnnotation != null) {
|
||||||
|
providesMembershipInCompartments = new HashSet<String>();
|
||||||
|
for (Compartment next : compartmentsAnnotation.providesMembershipIn()) {
|
||||||
|
providesMembershipInCompartments.add(next.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), paramType, providesMembershipInCompartments);
|
||||||
theResourceDef.addSearchParam(param);
|
theResourceDef.addSearchParam(param);
|
||||||
nameToParam.put(param.getName(), param);
|
nameToParam.put(param.getName(), param);
|
||||||
}
|
}
|
||||||
|
@ -774,13 +739,14 @@ class ModelScanner {
|
||||||
for (String nextName : searchParam.compositeOf()) {
|
for (String nextName : searchParam.compositeOf()) {
|
||||||
RuntimeSearchParam param = nameToParam.get(nextName);
|
RuntimeSearchParam param = nameToParam.get(nextName);
|
||||||
if (param == null) {
|
if (param == null) {
|
||||||
ourLog.warn("Search parameter {}.{} declares that it is a composite with compositeOf value '{}' but that is not a valid parametr name itself. Valid values are: {}", new Object[] { theResourceDef.getName(), searchParam.name(), nextName, nameToParam.keySet() });
|
ourLog.warn("Search parameter {}.{} declares that it is a composite with compositeOf value '{}' but that is not a valid parametr name itself. Valid values are: {}",
|
||||||
|
new Object[] { theResourceDef.getName(), searchParam.name(), nextName, nameToParam.keySet() });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
compositeOf.add(param);
|
compositeOf.add(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), RestSearchParameterTypeEnum.COMPOSITE, compositeOf);
|
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), RestSearchParameterTypeEnum.COMPOSITE, compositeOf, null);
|
||||||
theResourceDef.addSearchParam(param);
|
theResourceDef.addSearchParam(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.context;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
||||||
|
@ -29,23 +30,30 @@ import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
||||||
|
|
||||||
public class RuntimeSearchParam {
|
public class RuntimeSearchParam {
|
||||||
|
|
||||||
|
private List<RuntimeSearchParam> myCompositeOf;
|
||||||
private String myDescription;
|
private String myDescription;
|
||||||
private String myName;
|
private String myName;
|
||||||
private RestSearchParameterTypeEnum myParamType;
|
private RestSearchParameterTypeEnum myParamType;
|
||||||
private String myPath;
|
private String myPath;
|
||||||
private List<RuntimeSearchParam> myCompositeOf;
|
private Set<String> myProvidesMembershipInCompartments;
|
||||||
|
|
||||||
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType) {
|
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf,
|
||||||
this(theName, theDescription, thePath, theParamType, null);
|
Set<String> theProvidesMembershipInCompartments) {
|
||||||
}
|
|
||||||
|
|
||||||
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf) {
|
|
||||||
super();
|
super();
|
||||||
myName = theName;
|
myName = theName;
|
||||||
myDescription = theDescription;
|
myDescription = theDescription;
|
||||||
myPath = thePath;
|
myPath = thePath;
|
||||||
myParamType = theParamType;
|
myParamType = theParamType;
|
||||||
myCompositeOf = theCompositeOf;
|
myCompositeOf = theCompositeOf;
|
||||||
|
if (theProvidesMembershipInCompartments != null && !theProvidesMembershipInCompartments.isEmpty()) {
|
||||||
|
myProvidesMembershipInCompartments = Collections.unmodifiableSet(theProvidesMembershipInCompartments);
|
||||||
|
} else {
|
||||||
|
myProvidesMembershipInCompartments = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set<String> theProvidesMembershipInCompartments) {
|
||||||
|
this(theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RuntimeSearchParam> getCompositeOf() {
|
public List<RuntimeSearchParam> getCompositeOf() {
|
||||||
|
@ -70,7 +78,7 @@ public class RuntimeSearchParam {
|
||||||
|
|
||||||
public List<String> getPathsSplit() {
|
public List<String> getPathsSplit() {
|
||||||
String path = getPath();
|
String path = getPath();
|
||||||
if (path.indexOf('|')==-1) {
|
if (path.indexOf('|') == -1) {
|
||||||
return Collections.singletonList(path);
|
return Collections.singletonList(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,4 +91,11 @@ public class RuntimeSearchParam {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can return null
|
||||||
|
*/
|
||||||
|
public Set<String> getProvidesMembershipInCompartments() {
|
||||||
|
return myProvidesMembershipInCompartments;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ca.uhn.fhir.model.api.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value= {})
|
||||||
|
public @interface Compartment {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This may only be populated on a reference field. On such a field, places the containing
|
||||||
|
* resource in a compartment with the name(s) specified by the given strings, where the compartment
|
||||||
|
* belongs to the target resource. For example, this field could be populated with <code>Patient</code> on
|
||||||
|
* the <code>Observation.subject</code> field.
|
||||||
|
*/
|
||||||
|
String name();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ca.uhn.fhir.model.api.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value= {ElementType.FIELD})
|
||||||
|
public @interface Compartments {
|
||||||
|
|
||||||
|
Compartment[] providesMembershipIn();
|
||||||
|
|
||||||
|
}
|
|
@ -25,6 +25,29 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denotes a parameter for a REST method which will contain the resource actually
|
||||||
|
* being created/updated/etc in an operation which contains a resource in the HTTP request.
|
||||||
|
* <p>
|
||||||
|
* For example, in a {@link Create} operation the method parameter annotated with this
|
||||||
|
* annotation will contain the actual resource being created.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Parameters with this annotation should typically be of the type of resource being
|
||||||
|
* operated on (see below for an exception when raw data is required). For example, in a
|
||||||
|
* {@link IResourceProvider} for Patient resources, the parameter annotated with this
|
||||||
|
* annotation should be of type Patient.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Note that in servers it is also acceptable to have parameters with this annotation
|
||||||
|
* which are of type {@link String} or of type <code>byte[]</code>. Parameters of
|
||||||
|
* these types will contain the raw/unparsed HTTP request body. It is fine to
|
||||||
|
* have multiple parameters with this annotation, so you can have one parameter
|
||||||
|
* which accepts the parsed resource, and another which accepts the raw request.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
@Target(value=ElementType.PARAMETER)
|
@Target(value=ElementType.PARAMETER)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface ResourceParam {
|
public @interface ResourceParam {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package ca.uhn.fhir.rest.method;
|
package ca.uhn.fhir.rest.method;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR - Core Library
|
* HAPI FHIR - Core Library
|
||||||
|
@ -46,6 +49,7 @@ import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
||||||
* @author Doug Martin (Regenstrief Center for Biomedical Informatics)
|
* @author Doug Martin (Regenstrief Center for Biomedical Informatics)
|
||||||
*/
|
*/
|
||||||
abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvocation {
|
abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvocation {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHttpClientInvocationWithContents.class);
|
||||||
|
|
||||||
private final Bundle myBundle;
|
private final Bundle myBundle;
|
||||||
private final BundleTypeEnum myBundleType;
|
private final BundleTypeEnum myBundleType;
|
||||||
|
|
|
@ -117,7 +117,7 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
|
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
|
||||||
IResource resource = (IResource) theArgs[myResourceParameterIndex];
|
IResource resource = (IResource) theArgs[myResourceParameterIndex]; // TODO: use IBaseResource
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
throw new NullPointerException("Resource can not be null");
|
throw new NullPointerException("Resource can not be null");
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,10 +451,20 @@ public class MethodUtil {
|
||||||
mode = Mode.RESOURCE;
|
mode = Mode.RESOURCE;
|
||||||
} else if (String.class.equals(parameterType)) {
|
} else if (String.class.equals(parameterType)) {
|
||||||
mode = ResourceParameter.Mode.BODY;
|
mode = ResourceParameter.Mode.BODY;
|
||||||
|
} else if (byte[].class.equals(parameterType)) {
|
||||||
|
mode = ResourceParameter.Mode.BODY_BYTE_ARRAY;
|
||||||
} else if (EncodingEnum.class.equals(parameterType)) {
|
} else if (EncodingEnum.class.equals(parameterType)) {
|
||||||
mode = Mode.ENCODING;
|
mode = Mode.ENCODING;
|
||||||
} else {
|
} else {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName() + " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append("Method '");
|
||||||
|
b.append(theMethod.getName());
|
||||||
|
b.append("' is annotated with @");
|
||||||
|
b.append(ResourceParam.class.getSimpleName());
|
||||||
|
b.append(" but has a type that is not an implemtation of ");
|
||||||
|
b.append(IBaseResource.class.getCanonicalName());
|
||||||
|
b.append(" or String or byte[]");
|
||||||
|
throw new ConfigurationException(b.toString());
|
||||||
}
|
}
|
||||||
param = new ResourceParameter((Class<? extends IResource>) parameterType, theProvider, mode);
|
param = new ResourceParameter((Class<? extends IResource>) parameterType, theProvider, mode);
|
||||||
} else if (nextAnnotation instanceof IdParam || nextAnnotation instanceof VersionIdParam) {
|
} else if (nextAnnotation instanceof IdParam || nextAnnotation instanceof VersionIdParam) {
|
||||||
|
|
|
@ -105,8 +105,10 @@ public class ResourceParameter implements IParameter {
|
||||||
return IOUtils.toString(createRequestReader(theRequest));
|
return IOUtils.toString(createRequestReader(theRequest));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Shouldn't happen since we're reading from a byte array
|
// Shouldn't happen since we're reading from a byte array
|
||||||
throw new InternalErrorException("Failed to load request");
|
throw new InternalErrorException("Failed to load request", e);
|
||||||
}
|
}
|
||||||
|
case BODY_BYTE_ARRAY:
|
||||||
|
return theRequest.loadRequestContents();
|
||||||
case ENCODING:
|
case ENCODING:
|
||||||
return RestfulServerUtils.determineRequestEncoding(theRequest);
|
return RestfulServerUtils.determineRequestEncoding(theRequest);
|
||||||
case RESOURCE:
|
case RESOURCE:
|
||||||
|
@ -201,23 +203,27 @@ public class ResourceParameter implements IParameter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBaseResource parseResourceFromRequest(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding, Class<? extends IBaseResource> theResourceType) {
|
public static IBaseResource parseResourceFromRequest(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding, Class<? extends IBaseResource> theResourceType) {
|
||||||
IBaseResource retVal;
|
IBaseResource retVal = null;
|
||||||
|
|
||||||
if (IBaseBinary.class.isAssignableFrom(theResourceType)) {
|
if (IBaseBinary.class.isAssignableFrom(theResourceType)) {
|
||||||
FhirContext ctx = theRequest.getServer().getFhirContext();
|
|
||||||
String ct = theRequest.getHeader(Constants.HEADER_CONTENT_TYPE);
|
String ct = theRequest.getHeader(Constants.HEADER_CONTENT_TYPE);
|
||||||
|
if (EncodingEnum.forContentTypeStrict(ct) == null) {
|
||||||
|
FhirContext ctx = theRequest.getServer().getFhirContext();
|
||||||
IBaseBinary binary = (IBaseBinary) ctx.getResourceDefinition("Binary").newInstance();
|
IBaseBinary binary = (IBaseBinary) ctx.getResourceDefinition("Binary").newInstance();
|
||||||
binary.setContentType(ct);
|
binary.setContentType(ct);
|
||||||
binary.setContent(theRequest.loadRequestContents());
|
binary.setContent(theRequest.loadRequestContents());
|
||||||
|
|
||||||
retVal = binary;
|
retVal = binary;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retVal == null) {
|
||||||
retVal = loadResourceFromRequest(theRequest, theMethodBinding, theResourceType);
|
retVal = loadResourceFromRequest(theRequest, theMethodBinding, theResourceType);
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Mode {
|
public enum Mode {
|
||||||
BODY, ENCODING, RESOURCE
|
BODY, BODY_BYTE_ARRAY, ENCODING, RESOURCE
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class Constants {
|
||||||
public static final String FORMAT_XML = "xml";
|
public static final String FORMAT_XML = "xml";
|
||||||
public static final String HEADER_ACCEPT = "Accept";
|
public static final String HEADER_ACCEPT = "Accept";
|
||||||
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
||||||
public static final String HEADER_ACCEPT_VALUE_ALL = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
||||||
public static final String HEADER_ALLOW = "Allow";
|
public static final String HEADER_ALLOW = "Allow";
|
||||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||||
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
||||||
|
|
|
@ -44,6 +44,7 @@ public enum EncodingEnum {
|
||||||
;
|
;
|
||||||
|
|
||||||
private static HashMap<String, EncodingEnum> ourContentTypeToEncoding;
|
private static HashMap<String, EncodingEnum> ourContentTypeToEncoding;
|
||||||
|
private static HashMap<String, EncodingEnum> ourContentTypeToEncodingStrict;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ourContentTypeToEncoding = new HashMap<String, EncodingEnum>();
|
ourContentTypeToEncoding = new HashMap<String, EncodingEnum>();
|
||||||
|
@ -52,6 +53,9 @@ public enum EncodingEnum {
|
||||||
ourContentTypeToEncoding.put(next.getResourceContentType(), next);
|
ourContentTypeToEncoding.put(next.getResourceContentType(), next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add before we add the lenient ones
|
||||||
|
ourContentTypeToEncodingStrict = new HashMap<String, EncodingEnum>(ourContentTypeToEncoding);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are wrong, but we add them just to be tolerant of other
|
* These are wrong, but we add them just to be tolerant of other
|
||||||
* people's mistakes
|
* people's mistakes
|
||||||
|
@ -88,10 +92,30 @@ public enum EncodingEnum {
|
||||||
return myResourceContentType;
|
return myResourceContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the encoding for a given content type, or <code>null</code> if no encoding
|
||||||
|
* is found.
|
||||||
|
* <p>
|
||||||
|
* <b>This method is lenient!</b> Things like "application/xml" will return {@link EncodingEnum#XML}
|
||||||
|
* even if the "+fhir" part is missing from the expected content type.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
public static EncodingEnum forContentType(String theContentType) {
|
public static EncodingEnum forContentType(String theContentType) {
|
||||||
return ourContentTypeToEncoding.get(theContentType);
|
return ourContentTypeToEncoding.get(theContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the encoding for a given content type, or <code>null</code> if no encoding
|
||||||
|
* is found.
|
||||||
|
* <p>
|
||||||
|
* <b>This method is NOT lenient!</b> Things like "application/xml" will return <code>null</code>
|
||||||
|
* </p>
|
||||||
|
* @see #forContentType(String)
|
||||||
|
*/
|
||||||
|
public static EncodingEnum forContentTypeStrict(String theContentType) {
|
||||||
|
return ourContentTypeToEncodingStrict.get(theContentType);
|
||||||
|
}
|
||||||
|
|
||||||
public String getFormatContentType() {
|
public String getFormatContentType() {
|
||||||
return myFormatContentType;
|
return myFormatContentType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -517,7 +517,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
|
|
||||||
protected void handleRequest(RequestTypeEnum theRequestType, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
protected void handleRequest(RequestTypeEnum theRequestType, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
||||||
String fhirServerBase = null;
|
String fhirServerBase = null;
|
||||||
boolean requestIsBrowser = requestIsBrowser(theRequest);
|
|
||||||
ServletRequestDetails requestDetails = new ServletRequestDetails();
|
ServletRequestDetails requestDetails = new ServletRequestDetails();
|
||||||
requestDetails.setServer(this);
|
requestDetails.setServer(this);
|
||||||
requestDetails.setRequestType(theRequestType);
|
requestDetails.setRequestType(theRequestType);
|
||||||
|
@ -651,10 +650,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestIsBrowser) {
|
|
||||||
// if request is coming from a browser, prompt the user to enter login credentials
|
|
||||||
theResponse.setHeader("WWW-Authenticate", "BASIC realm=\"FHIR\"");
|
|
||||||
}
|
|
||||||
writeExceptionToResponse(theResponse, e);
|
writeExceptionToResponse(theResponse, e);
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -1399,9 +1394,4 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
return nextString.length() > 0 && (nextString.charAt(0) == '_' || nextString.charAt(0) == '$' || nextString.equals(Constants.URL_TOKEN_METADATA));
|
return nextString.length() > 0 && (nextString.charAt(0) == '_' || nextString.charAt(0) == '$' || nextString.equals(Constants.URL_TOKEN_METADATA));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean requestIsBrowser(HttpServletRequest theRequest) {
|
|
||||||
String userAgent = theRequest.getHeader("User-Agent");
|
|
||||||
return userAgent != null && userAgent.contains("Mozilla");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ ca.uhn.fhir.validation.ValidationResult.noIssuesDetected=No issues detected duri
|
||||||
# JPA Messages
|
# JPA Messages
|
||||||
|
|
||||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request.
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request.
|
||||||
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}"
|
||||||
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlNoMatches=Invalid match URL "{0}" - No resources match this search
|
||||||
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlMultipleMatches=Invalid match URL "{0}" - Multiple resources match this search
|
||||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationWithMultipleMatchFailure=Failed to {0} resource with match URL "{1}" because this search matched {2} resources
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationWithMultipleMatchFailure=Failed to {0} resource with match URL "{1}" because this search matched {2} resources
|
||||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedNoId=Failed to {0} resource in transaction because no ID was provided
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedNoId=Failed to {0} resource in transaction because no ID was provided
|
||||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedUnknownId=Failed to {0} resource in transaction because no resource could be found with ID {1}
|
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedUnknownId=Failed to {0} resource in transaction because no resource could be found with ID {1}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,32 +34,39 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
|
||||||
public class DaoConfig {
|
public class DaoConfig {
|
||||||
|
|
||||||
|
// ***
|
||||||
|
// update setter javadoc if default changes
|
||||||
|
// ***
|
||||||
|
private boolean myAllowInlineMatchUrlReferences = false;
|
||||||
|
|
||||||
private boolean myAllowMultipleDelete;
|
private boolean myAllowMultipleDelete;
|
||||||
private int myHardSearchLimit = 1000;
|
private int myHardSearchLimit = 1000;
|
||||||
private int myHardTagListLimit = 1000;
|
private int myHardTagListLimit = 1000;
|
||||||
private int myIncludeLimit = 2000;
|
private int myIncludeLimit = 2000;
|
||||||
|
|
||||||
|
// ***
|
||||||
|
// update setter javadoc if default changes
|
||||||
|
// ***
|
||||||
|
private boolean myIndexContainedResources = true;
|
||||||
|
|
||||||
private List<IServerInterceptor> myInterceptors;
|
private List<IServerInterceptor> myInterceptors;
|
||||||
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
||||||
private boolean mySchedulingDisabled;
|
private boolean mySchedulingDisabled;
|
||||||
private boolean mySubscriptionEnabled;
|
private boolean mySubscriptionEnabled;
|
||||||
private long mySubscriptionPollDelay = 1000;
|
private long mySubscriptionPollDelay = 1000;
|
||||||
private Long mySubscriptionPurgeInactiveAfterMillis;
|
private Long mySubscriptionPurgeInactiveAfterMillis;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link #setIncludeLimit(int)}
|
* See {@link #setIncludeLimit(int)}
|
||||||
*/
|
*/
|
||||||
public int getHardSearchLimit() {
|
public int getHardSearchLimit() {
|
||||||
return myHardSearchLimit;
|
return myHardSearchLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHardTagListLimit() {
|
public int getHardTagListLimit() {
|
||||||
return myHardTagListLimit;
|
return myHardTagListLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIncludeLimit() {
|
public int getIncludeLimit() {
|
||||||
return myIncludeLimit;
|
return myIncludeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the interceptors which will be notified of operations.
|
* Returns the interceptors which will be notified of operations.
|
||||||
*
|
*
|
||||||
|
@ -84,10 +91,25 @@ public class DaoConfig {
|
||||||
return mySubscriptionPurgeInactiveAfterMillis;
|
return mySubscriptionPurgeInactiveAfterMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #setAllowInlineMatchUrlReferences(boolean)
|
||||||
|
*/
|
||||||
|
public boolean isAllowInlineMatchUrlReferences() {
|
||||||
|
return myAllowInlineMatchUrlReferences;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAllowMultipleDelete() {
|
public boolean isAllowMultipleDelete() {
|
||||||
return myAllowMultipleDelete;
|
return myAllowMultipleDelete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should contained IDs be indexed the same way that non-contained IDs are (default is
|
||||||
|
* <code>true</code>)
|
||||||
|
*/
|
||||||
|
public boolean isIndexContainedResources() {
|
||||||
|
return myIndexContainedResources;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSchedulingDisabled() {
|
public boolean isSchedulingDisabled() {
|
||||||
return mySchedulingDisabled;
|
return mySchedulingDisabled;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +121,20 @@ public class DaoConfig {
|
||||||
return mySubscriptionEnabled;
|
return mySubscriptionEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should references containing match URLs be resolved and replaced in create and update operations. For
|
||||||
|
* example, if this property is set to true and a resource is created containing a reference
|
||||||
|
* to "Patient?identifier=12345", this is reference match URL will be resolved and replaced according
|
||||||
|
* to the usual match URL rules.
|
||||||
|
* <p>
|
||||||
|
* Default is false for now, as this is an experimental feature.
|
||||||
|
* </p>
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public void setAllowInlineMatchUrlReferences(boolean theAllowInlineMatchUrlReferences) {
|
||||||
|
myAllowInlineMatchUrlReferences = theAllowInlineMatchUrlReferences;
|
||||||
|
}
|
||||||
|
|
||||||
public void setAllowMultipleDelete(boolean theAllowMultipleDelete) {
|
public void setAllowMultipleDelete(boolean theAllowMultipleDelete) {
|
||||||
myAllowMultipleDelete = theAllowMultipleDelete;
|
myAllowMultipleDelete = theAllowMultipleDelete;
|
||||||
}
|
}
|
||||||
|
@ -120,6 +156,14 @@ public class DaoConfig {
|
||||||
myIncludeLimit = theIncludeLimit;
|
myIncludeLimit = theIncludeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should contained IDs be indexed the same way that non-contained IDs are (default is
|
||||||
|
* <code>true</code>)
|
||||||
|
*/
|
||||||
|
public void setIndexContainedResources(boolean theIndexContainedResources) {
|
||||||
|
myIndexContainedResources = theIndexContainedResources;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This may be used to optionally register server interceptors directly against the DAOs.
|
* This may be used to optionally register server interceptors directly against the DAOs.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%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%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.entity.ForcedId;
|
||||||
|
|
||||||
|
public interface IForcedIdDao extends JpaRepository<ForcedId, Long> {
|
||||||
|
|
||||||
|
@Query("SELECT f FROM ForcedId f WHERE f.myResourcePid = :resource_pid")
|
||||||
|
public ForcedId findByResourcePid(@Param("resource_pid") Long theResourcePid);
|
||||||
|
|
||||||
|
}
|
|
@ -462,7 +462,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
|
|
||||||
FhirTerser terser = getContext().newTerser();
|
FhirTerser terser = getContext().newTerser();
|
||||||
for (DaoMethodOutcome nextOutcome : idToPersistedOutcome.values()) {
|
for (DaoMethodOutcome nextOutcome : idToPersistedOutcome.values()) {
|
||||||
IBaseResource nextResource = (IBaseResource) nextOutcome.getResource();
|
IBaseResource nextResource = nextOutcome.getResource();
|
||||||
if (nextResource == null) {
|
if (nextResource == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ import javax.persistence.UniqueConstraint;
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@Entity()
|
@Entity()
|
||||||
@Table(name = "HFJ_FORCED_ID", uniqueConstraints = {
|
@Table(name = "HFJ_FORCED_ID", uniqueConstraints = {
|
||||||
@UniqueConstraint(name = "IDX_FORCEDID", columnNames = {"FORCED_ID"})
|
@UniqueConstraint(name = "IDX_FORCEDID", columnNames = {"FORCED_ID"}),
|
||||||
|
@UniqueConstraint(name = "IDX_FORCEDID_RESID", columnNames = {"RESOURCE_PID"})
|
||||||
})
|
})
|
||||||
@NamedQueries(value = {
|
@NamedQueries(value = {
|
||||||
@NamedQuery(name = "Q_GET_FORCED_ID", query = "SELECT f FROM ForcedId f WHERE myForcedId = :ID")
|
@NamedQuery(name = "Q_GET_FORCED_ID", query = "SELECT f FROM ForcedId f WHERE myForcedId = :ID")
|
||||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.entity;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Index;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
|
@ -34,9 +35,8 @@ import org.hibernate.search.annotations.Field;
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@Embeddable
|
@Embeddable
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "HFJ_SPIDX_COORDS" /* , indexes = { @Index(name = "IDX_SP_TOKEN", columnList = "SP_SYSTEM,SP_VALUE") } */)
|
@Table(name = "HFJ_SPIDX_COORDS", indexes = {
|
||||||
@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_COORDS", indexes = {
|
@Index(name = "IDX_SP_COORDS", columnList = "RES_TYPE,SP_NAME,SP_LATITUDE,SP_LONGITUDE")
|
||||||
@org.hibernate.annotations.Index(name = "IDX_SP_COORDS", columnNames = { "RES_TYPE", "SP_NAME", "SP_LATITUDE" })
|
|
||||||
})
|
})
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
public class ResourceIndexedSearchParamCoords extends BaseResourceIndexedSearchParam {
|
public class ResourceIndexedSearchParamCoords extends BaseResourceIndexedSearchParam {
|
||||||
|
|
|
@ -144,6 +144,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
private String myContentText;
|
private String myContentText;
|
||||||
|
|
||||||
|
@Column(name = "HAS_CONTAINED", nullable = true)
|
||||||
|
private boolean myHasContainedResource;
|
||||||
|
|
||||||
@Column(name = "SP_HAS_LINKS")
|
@Column(name = "SP_HAS_LINKS")
|
||||||
private boolean myHasLinks;
|
private boolean myHasLinks;
|
||||||
|
|
||||||
|
@ -158,6 +161,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
@Column(name = "SP_INDEX_STATUS", nullable = true)
|
@Column(name = "SP_INDEX_STATUS", nullable = true)
|
||||||
private Long myIndexStatus;
|
private Long myIndexStatus;
|
||||||
|
|
||||||
|
@Column(name = "IS_CONTAINED", nullable = true)
|
||||||
|
private boolean myIsContainedResource;
|
||||||
|
|
||||||
@Column(name = "RES_LANGUAGE", length = MAX_LANGUAGE_LENGTH, nullable = true)
|
@Column(name = "RES_LANGUAGE", length = MAX_LANGUAGE_LENGTH, nullable = true)
|
||||||
private String myLanguage;
|
private String myLanguage;
|
||||||
|
|
||||||
|
@ -340,10 +346,18 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHasContainedResource() {
|
||||||
|
return myHasContainedResource;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isHasLinks() {
|
public boolean isHasLinks() {
|
||||||
return myHasLinks;
|
return myHasLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isIsContainedResource() {
|
||||||
|
return myIsContainedResource;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isParamsCoordsPopulated() {
|
public boolean isParamsCoordsPopulated() {
|
||||||
return myParamsCoordsPopulated;
|
return myParamsCoordsPopulated;
|
||||||
}
|
}
|
||||||
|
@ -376,6 +390,10 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
myContentText = theContentText;
|
myContentText = theContentText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHasContainedResource(boolean theHasContainedResource) {
|
||||||
|
myHasContainedResource = theHasContainedResource;
|
||||||
|
}
|
||||||
|
|
||||||
public void setHasLinks(boolean theHasLinks) {
|
public void setHasLinks(boolean theHasLinks) {
|
||||||
myHasLinks = theHasLinks;
|
myHasLinks = theHasLinks;
|
||||||
}
|
}
|
||||||
|
@ -388,6 +406,10 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
myIndexStatus = theIndexStatus;
|
myIndexStatus = theIndexStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIsContainedResource(boolean theIsContainedResource) {
|
||||||
|
myIsContainedResource = theIsContainedResource;
|
||||||
|
}
|
||||||
|
|
||||||
public void setLanguage(String theLanguage) {
|
public void setLanguage(String theLanguage) {
|
||||||
if (defaultString(theLanguage).length() > MAX_LANGUAGE_LENGTH) {
|
if (defaultString(theLanguage).length() > MAX_LANGUAGE_LENGTH) {
|
||||||
throw new UnprocessableEntityException("Language exceeds maximum length of " + MAX_LANGUAGE_LENGTH + " chars: " + theLanguage);
|
throw new UnprocessableEntityException("Language exceeds maximum length of " + MAX_LANGUAGE_LENGTH + " chars: " + theLanguage);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -12,21 +13,29 @@ import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
|
|
||||||
public class BaseJpaTest {
|
public class BaseJpaTest {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaTest.class);
|
||||||
|
protected ServletRequestDetails mySrd;
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes" })
|
@SuppressWarnings({ "rawtypes" })
|
||||||
protected List toList(IBundleProvider theSearch) {
|
protected List toList(IBundleProvider theSearch) {
|
||||||
return theSearch.getResources(0, theSearch.size());
|
return theSearch.getResources(0, theSearch.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeCreateSrd() {
|
||||||
|
mySrd = mock(ServletRequestDetails.class);
|
||||||
|
}
|
||||||
|
|
||||||
protected List<IIdType> toUnqualifiedVersionlessIds(Bundle theFound) {
|
protected List<IIdType> toUnqualifiedVersionlessIds(Bundle theFound) {
|
||||||
List<IIdType> retVal = new ArrayList<IIdType>();
|
List<IIdType> retVal = new ArrayList<IIdType>();
|
||||||
for (Entry next : theFound.getEntry()) {
|
for (Entry next : theFound.getEntry()) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
|
@ -239,14 +240,14 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
|
|
||||||
public TransactionTemplate newTxTemplate() {
|
public TransactionTemplate newTxTemplate() {
|
||||||
TransactionTemplate retVal = new TransactionTemplate(myTxManager);
|
TransactionTemplate retVal = new TransactionTemplate(myTxManager);
|
||||||
retVal.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
retVal.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||||
retVal.afterPropertiesSet();
|
retVal.afterPropertiesSet();
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager) {
|
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager) {
|
||||||
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
||||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||||
txTemplate.execute(new TransactionCallback<Void>() {
|
txTemplate.execute(new TransactionCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void doInTransaction(TransactionStatus theStatus) {
|
public Void doInTransaction(TransactionStatus theStatus) {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import org.hl7.fhir.dstu3.model.Observation;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
|
import org.hl7.fhir.dstu3.model.Reference;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
|
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||||
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
|
|
||||||
|
public class FhirResourceDaoDstu3ContainedTest extends BaseJpaDstu3Test {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3ContainedTest.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void before() {
|
||||||
|
myDaoConfig.setIndexContainedResources(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndexContained() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId("#some_patient");
|
||||||
|
p.addName().addFamily("MYFAMILY").addGiven("MYGIVEN");
|
||||||
|
|
||||||
|
Observation o1 = new Observation();
|
||||||
|
o1.getCode().setText("Some Observation");
|
||||||
|
o1.setSubject(new Reference(p));
|
||||||
|
IIdType oid1 = myObservationDao.create(o1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Observation o2 = new Observation();
|
||||||
|
o2.getCode().setText("Some Observation");
|
||||||
|
o2.setSubject(new Reference(p));
|
||||||
|
IIdType oid2 = myObservationDao.create(o2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.addName().addFamily("MYFAMILY").addGiven("MYGIVEN");
|
||||||
|
IIdType pid2 = myPatientDao.create(p2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(o2));
|
||||||
|
|
||||||
|
|
||||||
|
SearchParameterMap map;
|
||||||
|
|
||||||
|
// map = new SearchParameterMap();
|
||||||
|
// map.add(Observation.SP_CODE, new TokenParam(null, "some observation").setModifier(TokenParamModifier.TEXT));
|
||||||
|
// assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(map)), containsInAnyOrder(toValues(id1, id2)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: make sure match URLs don't delete
|
||||||
|
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||||
import ca.uhn.fhir.rest.param.StringParam;
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
|
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
|
|
||||||
|
@ -46,31 +47,35 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs1.setStatus(ObservationStatus.FINAL);
|
obs1.setStatus(ObservationStatus.FINAL);
|
||||||
obs1.setValue(new Quantity(123));
|
obs1.setValue(new Quantity(123));
|
||||||
obs1.setComments("obs1");
|
obs1.setComments("obs1");
|
||||||
IIdType id1 = myObservationDao.create(obs1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType id1 = myObservationDao.create(obs1, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs2 = new Observation();
|
Observation obs2 = new Observation();
|
||||||
obs2.getCode().setText("Diastolic Blood Pressure");
|
obs2.getCode().setText("Diastolic Blood Pressure");
|
||||||
obs2.setStatus(ObservationStatus.FINAL);
|
obs2.setStatus(ObservationStatus.FINAL);
|
||||||
obs2.setValue(new Quantity(81));
|
obs2.setValue(new Quantity(81));
|
||||||
IIdType id2 = myObservationDao.create(obs2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType id2 = myObservationDao.create(obs2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
SearchParameterMap map;
|
SearchParameterMap map;
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Observation.SP_CODE, new TokenParam(null, "blood").setText(true));
|
map.add(Observation.SP_CODE, new TokenParam(null, "blood").setModifier(TokenParamModifier.TEXT));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(map)), containsInAnyOrder(toValues(id1, id2)));
|
assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(map)), containsInAnyOrder(toValues(id1, id2)));
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Observation.SP_CODE, new TokenParam(null, "blood").setText(true));
|
map.add(Observation.SP_CODE, new TokenParam(null, "blood").setModifier(TokenParamModifier.TEXT));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myPatientDao.search(map)), empty());
|
assertThat(toUnqualifiedVersionlessIdValues(myPatientDao.search(map)), empty());
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Observation.SP_CODE, new TokenParam(null, "blood").setText(true));
|
map.add(Observation.SP_CODE, new TokenParam(null, "blood").setModifier(TokenParamModifier.TEXT));
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("obs1"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("obs1"));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(map)), containsInAnyOrder(toValues(id1)));
|
assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(map)), containsInAnyOrder(toValues(id1)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ServletRequestDetails mockSrd() {
|
||||||
|
return new ServletRequestDetails();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void testStringTextSearch() {
|
public void testStringTextSearch() {
|
||||||
|
@ -78,13 +83,13 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs1.getCode().setText("AAAAA");
|
obs1.getCode().setText("AAAAA");
|
||||||
obs1.setValue(new StringType("Systolic Blood Pressure"));
|
obs1.setValue(new StringType("Systolic Blood Pressure"));
|
||||||
obs1.setStatus(ObservationStatus.FINAL);
|
obs1.setStatus(ObservationStatus.FINAL);
|
||||||
IIdType id1 = myObservationDao.create(obs1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType id1 = myObservationDao.create(obs1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs2 = new Observation();
|
Observation obs2 = new Observation();
|
||||||
obs1.getCode().setText("AAAAA");
|
obs1.getCode().setText("AAAAA");
|
||||||
obs1.setValue(new StringType("Diastolic Blood Pressure"));
|
obs1.setValue(new StringType("Diastolic Blood Pressure"));
|
||||||
obs2.setStatus(ObservationStatus.FINAL);
|
obs2.setStatus(ObservationStatus.FINAL);
|
||||||
IIdType id2 = myObservationDao.create(obs2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType id2 = myObservationDao.create(obs2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
SearchParameterMap map;
|
SearchParameterMap map;
|
||||||
|
|
||||||
|
@ -99,7 +104,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
public void testSuggestIgnoresBase64Content() {
|
public void testSuggestIgnoresBase64Content() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addName().addFamily("testSuggest");
|
patient.addName().addFamily("testSuggest");
|
||||||
IIdType ptId = myPatientDao.create(patient, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Media med = new Media();
|
Media med = new Media();
|
||||||
med.getSubject().setReferenceElement(ptId);
|
med.getSubject().setReferenceElement(ptId);
|
||||||
|
@ -107,7 +112,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
med.getContent().setContentType("LCws");
|
med.getContent().setContentType("LCws");
|
||||||
med.getContent().setDataElement(new Base64BinaryType(new byte[] {44,44,44,44,44,44,44,44}));
|
med.getContent().setDataElement(new Base64BinaryType(new byte[] {44,44,44,44,44,44,44,44}));
|
||||||
med.getContent().setTitle("bbbb syst");
|
med.getContent().setTitle("bbbb syst");
|
||||||
myMediaDao.create(med, new ServletRequestDetails());
|
myMediaDao.create(med, mockSrd());
|
||||||
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(med));
|
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(med));
|
||||||
|
|
||||||
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press");
|
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press");
|
||||||
|
@ -139,35 +144,35 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
public void testSuggest() {
|
public void testSuggest() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addName().addFamily("testSuggest");
|
patient.addName().addFamily("testSuggest");
|
||||||
IIdType ptId = myPatientDao.create(patient, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs = new Observation();
|
Observation obs = new Observation();
|
||||||
obs.getSubject().setReferenceElement(ptId);
|
obs.getSubject().setReferenceElement(ptId);
|
||||||
obs.getCode().setText("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL");
|
obs.getCode().setText("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL");
|
||||||
myObservationDao.create(obs, new ServletRequestDetails());
|
myObservationDao.create(obs, mockSrd());
|
||||||
|
|
||||||
obs = new Observation();
|
obs = new Observation();
|
||||||
obs.getSubject().setReferenceElement(ptId);
|
obs.getSubject().setReferenceElement(ptId);
|
||||||
obs.getCode().setText("MNBVCXZ");
|
obs.getCode().setText("MNBVCXZ");
|
||||||
myObservationDao.create(obs, new ServletRequestDetails());
|
myObservationDao.create(obs, mockSrd());
|
||||||
|
|
||||||
obs = new Observation();
|
obs = new Observation();
|
||||||
obs.getSubject().setReferenceElement(ptId);
|
obs.getSubject().setReferenceElement(ptId);
|
||||||
obs.getCode().setText("ZXC HELLO");
|
obs.getCode().setText("ZXC HELLO");
|
||||||
obs.addComponent().getCode().setText("HHHHHHHHHH");
|
obs.addComponent().getCode().setText("HHHHHHHHHH");
|
||||||
myObservationDao.create(obs, new ServletRequestDetails());
|
myObservationDao.create(obs, mockSrd());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These shouldn't match since they're for another patient
|
* These shouldn't match since they're for another patient
|
||||||
*/
|
*/
|
||||||
patient = new Patient();
|
patient = new Patient();
|
||||||
patient.addName().addFamily("testSuggest2");
|
patient.addName().addFamily("testSuggest2");
|
||||||
IIdType ptId2 = myPatientDao.create(patient, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId2 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs2 = new Observation();
|
Observation obs2 = new Observation();
|
||||||
obs2.getSubject().setReferenceElement(ptId2);
|
obs2.getSubject().setReferenceElement(ptId2);
|
||||||
obs2.getCode().setText("ZXCVBNMZZ");
|
obs2.getCode().setText("ZXCVBNMZZ");
|
||||||
myObservationDao.create(obs2, new ServletRequestDetails());
|
myObservationDao.create(obs2, mockSrd());
|
||||||
|
|
||||||
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM");
|
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM");
|
||||||
ourLog.info("Found: " + output);
|
ourLog.info("Found: " + output);
|
||||||
|
@ -212,7 +217,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
patient = new Patient();
|
patient = new Patient();
|
||||||
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
||||||
patient.addName().addGiven("NAMEAAA");
|
patient.addName().addGiven("NAMEAAA");
|
||||||
IIdType pId1 = myPatientDao.create(patient, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
@ -230,7 +235,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
patient.setId(pId1);
|
patient.setId(pId1);
|
||||||
patient.getText().setDivAsString("<div>DIVBBB</div>");
|
patient.getText().setDivAsString("<div>DIVBBB</div>");
|
||||||
patient.addName().addGiven("NAMEBBB");
|
patient.addName().addGiven("NAMEBBB");
|
||||||
myPatientDao.update(patient, new ServletRequestDetails());
|
myPatientDao.update(patient, mockSrd());
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
@ -254,19 +259,19 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
public void testEverythingInstanceWithContentFilter() {
|
public void testEverythingInstanceWithContentFilter() {
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.addName().addFamily("Everything").addGiven("Arthur");
|
pt1.addName().addFamily("Everything").addGiven("Arthur");
|
||||||
IIdType ptId1 = myPatientDao.create(pt1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId1 = myPatientDao.create(pt1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt2 = new Patient();
|
Patient pt2 = new Patient();
|
||||||
pt2.addName().addFamily("Everything").addGiven("Arthur");
|
pt2.addName().addFamily("Everything").addGiven("Arthur");
|
||||||
IIdType ptId2 = myPatientDao.create(pt2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId2 = myPatientDao.create(pt2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Device dev1 = new Device();
|
Device dev1 = new Device();
|
||||||
dev1.setManufacturer("Some Manufacturer");
|
dev1.setManufacturer("Some Manufacturer");
|
||||||
IIdType devId1 = myDeviceDao.create(dev1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType devId1 = myDeviceDao.create(dev1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Device dev2 = new Device();
|
Device dev2 = new Device();
|
||||||
dev2.setManufacturer("Some Manufacturer 2");
|
dev2.setManufacturer("Some Manufacturer 2");
|
||||||
myDeviceDao.create(dev2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
myDeviceDao.create(dev2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs1 = new Observation();
|
Observation obs1 = new Observation();
|
||||||
obs1.getText().setDivAsString("<div>OBSTEXT1</div>");
|
obs1.getText().setDivAsString("<div>OBSTEXT1</div>");
|
||||||
|
@ -274,19 +279,19 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs1.getCode().addCoding().setCode("CODE1");
|
obs1.getCode().addCoding().setCode("CODE1");
|
||||||
obs1.setValue(new StringType("obsvalue1"));
|
obs1.setValue(new StringType("obsvalue1"));
|
||||||
obs1.getDevice().setReferenceElement(devId1);
|
obs1.getDevice().setReferenceElement(devId1);
|
||||||
IIdType obsId1 = myObservationDao.create(obs1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId1 = myObservationDao.create(obs1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs2 = new Observation();
|
Observation obs2 = new Observation();
|
||||||
obs2.getSubject().setReferenceElement(ptId1);
|
obs2.getSubject().setReferenceElement(ptId1);
|
||||||
obs2.getCode().addCoding().setCode("CODE2");
|
obs2.getCode().addCoding().setCode("CODE2");
|
||||||
obs2.setValue(new StringType("obsvalue2"));
|
obs2.setValue(new StringType("obsvalue2"));
|
||||||
IIdType obsId2 = myObservationDao.create(obs2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId2 = myObservationDao.create(obs2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs3 = new Observation();
|
Observation obs3 = new Observation();
|
||||||
obs3.getSubject().setReferenceElement(ptId2);
|
obs3.getSubject().setReferenceElement(ptId2);
|
||||||
obs3.getCode().addCoding().setCode("CODE3");
|
obs3.getCode().addCoding().setCode("CODE3");
|
||||||
obs3.setValue(new StringType("obsvalue3"));
|
obs3.setValue(new StringType("obsvalue3"));
|
||||||
IIdType obsId3 = myObservationDao.create(obs3, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId3 = myObservationDao.create(obs3, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
List<String> actual;
|
List<String> actual;
|
||||||
|
@ -297,16 +302,16 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obstext1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obstext1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, param, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||||
|
|
||||||
request = mock(HttpServletRequest.class);
|
request = mock(HttpServletRequest.class);
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, null, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -317,12 +322,12 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs4.getSubject().setReferenceElement(ptId1);
|
obs4.getSubject().setReferenceElement(ptId1);
|
||||||
obs4.getCode().addCoding().setCode("CODE1");
|
obs4.getCode().addCoding().setCode("CODE1");
|
||||||
obs4.setValue(new StringType("obsvalue1"));
|
obs4.setValue(new StringType("obsvalue1"));
|
||||||
IIdType obsId4 = myObservationDao.create(obs4, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId4 = myObservationDao.create(obs4, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
assertNotEquals(obsId1.getIdPart(), obsId4.getIdPart(), devId1);
|
assertNotEquals(obsId1.getIdPart(), obsId4.getIdPart(), devId1);
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -334,11 +339,11 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs1.getSubject().setReferenceElement(ptId1);
|
obs1.getSubject().setReferenceElement(ptId1);
|
||||||
obs1.getCode().addCoding().setCode("CODE2");
|
obs1.getCode().addCoding().setCode("CODE2");
|
||||||
obs1.setValue(new StringType("obsvalue2"));
|
obs1.setValue(new StringType("obsvalue2"));
|
||||||
myObservationDao.update(obs1, new ServletRequestDetails());
|
myObservationDao.update(obs1, mockSrd());
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientInstanceEverything(request, ptId1, null, null, null, param, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -347,38 +352,38 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
public void testEverythingTypeWithContentFilter() {
|
public void testEverythingTypeWithContentFilter() {
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.addName().addFamily("Everything").addGiven("Arthur");
|
pt1.addName().addFamily("Everything").addGiven("Arthur");
|
||||||
IIdType ptId1 = myPatientDao.create(pt1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId1 = myPatientDao.create(pt1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient pt2 = new Patient();
|
Patient pt2 = new Patient();
|
||||||
pt2.addName().addFamily("Everything").addGiven("Arthur");
|
pt2.addName().addFamily("Everything").addGiven("Arthur");
|
||||||
IIdType ptId2 = myPatientDao.create(pt2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType ptId2 = myPatientDao.create(pt2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Device dev1 = new Device();
|
Device dev1 = new Device();
|
||||||
dev1.setManufacturer("Some Manufacturer");
|
dev1.setManufacturer("Some Manufacturer");
|
||||||
IIdType devId1 = myDeviceDao.create(dev1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType devId1 = myDeviceDao.create(dev1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Device dev2 = new Device();
|
Device dev2 = new Device();
|
||||||
dev2.setManufacturer("Some Manufacturer 2");
|
dev2.setManufacturer("Some Manufacturer 2");
|
||||||
IIdType devId2 = myDeviceDao.create(dev2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
myDeviceDao.create(dev2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs1 = new Observation();
|
Observation obs1 = new Observation();
|
||||||
obs1.getSubject().setReferenceElement(ptId1);
|
obs1.getSubject().setReferenceElement(ptId1);
|
||||||
obs1.getCode().addCoding().setCode("CODE1");
|
obs1.getCode().addCoding().setCode("CODE1");
|
||||||
obs1.setValue(new StringType("obsvalue1"));
|
obs1.setValue(new StringType("obsvalue1"));
|
||||||
obs1.getDevice().setReferenceElement(devId1);
|
obs1.getDevice().setReferenceElement(devId1);
|
||||||
IIdType obsId1 = myObservationDao.create(obs1, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId1 = myObservationDao.create(obs1, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs2 = new Observation();
|
Observation obs2 = new Observation();
|
||||||
obs2.getSubject().setReferenceElement(ptId1);
|
obs2.getSubject().setReferenceElement(ptId1);
|
||||||
obs2.getCode().addCoding().setCode("CODE2");
|
obs2.getCode().addCoding().setCode("CODE2");
|
||||||
obs2.setValue(new StringType("obsvalue2"));
|
obs2.setValue(new StringType("obsvalue2"));
|
||||||
IIdType obsId2 = myObservationDao.create(obs2, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId2 = myObservationDao.create(obs2, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation obs3 = new Observation();
|
Observation obs3 = new Observation();
|
||||||
obs3.getSubject().setReferenceElement(ptId2);
|
obs3.getSubject().setReferenceElement(ptId2);
|
||||||
obs3.getCode().addCoding().setCode("CODE3");
|
obs3.getCode().addCoding().setCode("CODE3");
|
||||||
obs3.setValue(new StringType("obsvalue3"));
|
obs3.setValue(new StringType("obsvalue3"));
|
||||||
IIdType obsId3 = myObservationDao.create(obs3, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId3 = myObservationDao.create(obs3, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
List<String> actual;
|
List<String> actual;
|
||||||
|
@ -389,11 +394,11 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, devId1)));
|
||||||
|
|
||||||
request = mock(HttpServletRequest.class);
|
request = mock(HttpServletRequest.class);
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, null, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1, ptId2, obsId3)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId2, devId1, ptId2, obsId3)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -404,12 +409,12 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs4.getSubject().setReferenceElement(ptId1);
|
obs4.getSubject().setReferenceElement(ptId1);
|
||||||
obs4.getCode().addCoding().setCode("CODE1");
|
obs4.getCode().addCoding().setCode("CODE1");
|
||||||
obs4.setValue(new StringType("obsvalue1"));
|
obs4.setValue(new StringType("obsvalue1"));
|
||||||
IIdType obsId4 = myObservationDao.create(obs4, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType obsId4 = myObservationDao.create(obs4, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
assertNotEquals(obsId1.getIdPart(), obsId4.getIdPart(), devId1);
|
assertNotEquals(obsId1.getIdPart(), obsId4.getIdPart(), devId1);
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId1, obsId4, devId1)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -421,11 +426,11 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
obs1.getSubject().setReferenceElement(ptId1);
|
obs1.getSubject().setReferenceElement(ptId1);
|
||||||
obs1.getCode().addCoding().setCode("CODE2");
|
obs1.getCode().addCoding().setCode("CODE2");
|
||||||
obs1.setValue(new StringType("obsvalue2"));
|
obs1.setValue(new StringType("obsvalue2"));
|
||||||
myObservationDao.update(obs1, new ServletRequestDetails());
|
myObservationDao.update(obs1, mockSrd());
|
||||||
|
|
||||||
param = new StringAndListParam();
|
param = new StringAndListParam();
|
||||||
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
|
||||||
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, new ServletRequestDetails()));
|
actual = toUnqualifiedVersionlessIdValues(myPatientDao.patientTypeEverything(request, null, null, null, param, null, mockSrd()));
|
||||||
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
assertThat(actual, containsInAnyOrder(toValues(ptId1, obsId4)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -443,7 +448,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
patient = new Patient();
|
patient = new Patient();
|
||||||
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
||||||
patient.addName().addGiven("NAMEAAA");
|
patient.addName().addGiven("NAMEAAA");
|
||||||
IIdType pId1 = myPatientDao.create(patient, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
@ -461,7 +466,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
patient.setId(pId1);
|
patient.setId(pId1);
|
||||||
patient.getText().setDivAsString("<div>DIVBBB</div>");
|
patient.getText().setDivAsString("<div>DIVBBB</div>");
|
||||||
patient.addName().addGiven("NAMEBBB");
|
patient.addName().addGiven("NAMEBBB");
|
||||||
myPatientDao.update(patient, null, false, new ServletRequestDetails());
|
myPatientDao.update(patient, null, false, mockSrd());
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
@ -470,7 +475,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEBBB"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEBBB"));
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(myPatientDao.search(map)), not(contains(toValues(pId1))));
|
assertThat(toUnqualifiedVersionlessIdValues(myPatientDao.search(map)), not(contains(toValues(pId1))));
|
||||||
|
|
||||||
myPatientDao.update(patient, null, true, new ServletRequestDetails());
|
myPatientDao.update(patient, null, true, mockSrd());
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
@ -498,18 +503,18 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addName().addGiven(methodName);
|
patient.addName().addGiven(methodName);
|
||||||
patient.addAddress().addLine("My fulltext address");
|
patient.addAddress().addLine("My fulltext address");
|
||||||
pId1 = myPatientDao.create(patient, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
|
|
||||||
Observation obs = new Observation();
|
Observation obs = new Observation();
|
||||||
obs.getSubject().setReferenceElement(pId1);
|
obs.getSubject().setReferenceElement(pId1);
|
||||||
obs.setValue(new StringType("This is the FULLtext of the observation"));
|
obs.setValue(new StringType("This is the FULLtext of the observation"));
|
||||||
IIdType oId1 = myObservationDao.create(obs, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType oId1 = myObservationDao.create(obs, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
obs = new Observation();
|
obs = new Observation();
|
||||||
obs.getSubject().setReferenceElement(pId1);
|
obs.getSubject().setReferenceElement(pId1);
|
||||||
obs.setValue(new StringType("Another fullText"));
|
obs.setValue(new StringType("Another fullText"));
|
||||||
IIdType oId2 = myObservationDao.create(obs, new ServletRequestDetails()).getId().toUnqualifiedVersionless();
|
IIdType oId2 = myObservationDao.create(obs, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
List<String> patients;
|
List<String> patients;
|
||||||
SearchParameterMap params;
|
SearchParameterMap params;
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.dstu3.model.BaseResource;
|
|
||||||
import org.hl7.fhir.dstu3.model.CodeType;
|
import org.hl7.fhir.dstu3.model.CodeType;
|
||||||
import org.hl7.fhir.dstu3.model.ConceptMap;
|
import org.hl7.fhir.dstu3.model.ConceptMap;
|
||||||
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
||||||
|
@ -52,6 +51,7 @@ import org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus;
|
||||||
import org.hl7.fhir.dstu3.model.Substance;
|
import org.hl7.fhir.dstu3.model.Substance;
|
||||||
import org.hl7.fhir.dstu3.model.TemporalPrecisionEnum;
|
import org.hl7.fhir.dstu3.model.TemporalPrecisionEnum;
|
||||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
|
@ -586,21 +586,21 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
params.put(BaseResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
|
params.put(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
|
||||||
List<IBaseResource> patients = toList(myPatientDao.search(params));
|
List<IBaseResource> patients = toList(myPatientDao.search(params));
|
||||||
assertEquals(1, patients.size());
|
assertEquals(1, patients.size());
|
||||||
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
|
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
params.put(BaseResource.SP_RES_LANGUAGE, new StringParam("en_US"));
|
params.put(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_US"));
|
||||||
List<Patient> patients = toList(myPatientDao.search(params));
|
List<Patient> patients = toList(myPatientDao.search(params));
|
||||||
assertEquals(1, patients.size());
|
assertEquals(1, patients.size());
|
||||||
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
|
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
|
||||||
params.put(BaseResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
|
params.put(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
|
||||||
List<Patient> patients = toList(myPatientDao.search(params));
|
List<Patient> patients = toList(myPatientDao.search(params));
|
||||||
assertEquals(0, patients.size());
|
assertEquals(0, patients.size());
|
||||||
}
|
}
|
||||||
|
@ -629,18 +629,18 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
|
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
|
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
|
||||||
params.setLastUpdated(new DateRangeParam(betweenTime, null));
|
params.setLastUpdated(new DateRangeParam(betweenTime, null));
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -648,7 +648,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
StringAndListParam and = new StringAndListParam();
|
StringAndListParam and = new StringAndListParam();
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, and);
|
params.add(IAnyResource.SP_RES_LANGUAGE, and);
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -656,7 +656,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
StringAndListParam and = new StringAndListParam();
|
StringAndListParam and = new StringAndListParam();
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, and);
|
params.add(IAnyResource.SP_RES_LANGUAGE, and);
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -664,7 +664,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
StringAndListParam and = new StringAndListParam();
|
StringAndListParam and = new StringAndListParam();
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, and);
|
params.add(IAnyResource.SP_RES_LANGUAGE, and);
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -672,7 +672,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
StringAndListParam and = new StringAndListParam();
|
StringAndListParam and = new StringAndListParam();
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, and);
|
params.add(IAnyResource.SP_RES_LANGUAGE, and);
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -681,7 +681,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
StringAndListParam and = new StringAndListParam();
|
StringAndListParam and = new StringAndListParam();
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, and);
|
params.add(IAnyResource.SP_RES_LANGUAGE, and);
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -689,7 +689,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
StringAndListParam and = new StringAndListParam();
|
StringAndListParam and = new StringAndListParam();
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
|
||||||
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
|
||||||
params.add(BaseResource.SP_RES_LANGUAGE, and);
|
params.add(IAnyResource.SP_RES_LANGUAGE, and);
|
||||||
params.add("_id", new StringParam(id1.getIdPart()));
|
params.add("_id", new StringParam(id1.getIdPart()));
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
|
||||||
}
|
}
|
||||||
|
@ -767,8 +767,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchLastUpdatedParamWithComparator() throws InterruptedException {
|
public void testSearchLastUpdatedParamWithComparator() throws InterruptedException {
|
||||||
String methodName = "testSearchLastUpdatedParamWithComparator";
|
|
||||||
|
|
||||||
IIdType id0;
|
IIdType id0;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -781,7 +779,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Thread.sleep(sleep);
|
Thread.sleep(sleep);
|
||||||
|
|
||||||
DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
|
|
||||||
IIdType id1a;
|
IIdType id1a;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -815,12 +812,12 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.setLastUpdated(new DateRangeParam(new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, startDateTime), new DateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, endDateTime)));
|
map.setLastUpdated(new DateRangeParam(new DateParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, startDateTime), new DateParam(ParamPrefixEnum.LESSTHAN_OR_EQUALS, endDateTime)));
|
||||||
ourLog.info("Searching: {}", map.getLastUpdated());
|
ourLog.info("Searching: {}", map.getLastUpdated());
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.setLastUpdated(new DateRangeParam(new DateParam(QuantityCompararatorEnum.GREATERTHAN, startDateTime), new DateParam(QuantityCompararatorEnum.LESSTHAN, endDateTime)));
|
map.setLastUpdated(new DateRangeParam(new DateParam(ParamPrefixEnum.GREATERTHAN, startDateTime), new DateParam(ParamPrefixEnum.LESSTHAN, endDateTime)));
|
||||||
ourLog.info("Searching: {}", map.getLastUpdated());
|
ourLog.info("Searching: {}", map.getLastUpdated());
|
||||||
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(map)), containsInAnyOrder(id1a, id1b));
|
||||||
|
|
||||||
|
@ -1373,7 +1370,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
QuantityParam param;
|
QuantityParam param;
|
||||||
Set<Long> found;
|
Set<Long> found;
|
||||||
param = new QuantityParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
|
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
|
||||||
found = myObservationDao.searchForIds("value-quantity", param);
|
found = myObservationDao.searchForIds("value-quantity", param);
|
||||||
int initialSize = found.size();
|
int initialSize = found.size();
|
||||||
|
|
||||||
|
@ -1384,19 +1381,19 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
myObservationDao.create(o, new ServletRequestDetails());
|
myObservationDao.create(o, new ServletRequestDetails());
|
||||||
|
|
||||||
param = new QuantityParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
|
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
|
||||||
found = myObservationDao.searchForIds("value-quantity", param);
|
found = myObservationDao.searchForIds("value-quantity", param);
|
||||||
assertEquals(1 + initialSize, found.size());
|
assertEquals(1 + initialSize, found.size());
|
||||||
|
|
||||||
param = new QuantityParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, methodName + "units");
|
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, methodName + "units");
|
||||||
found = myObservationDao.searchForIds("value-quantity", param);
|
found = myObservationDao.searchForIds("value-quantity", param);
|
||||||
assertEquals(1, found.size());
|
assertEquals(1, found.size());
|
||||||
|
|
||||||
param = new QuantityParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, null);
|
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, null);
|
||||||
found = myObservationDao.searchForIds("value-quantity", param);
|
found = myObservationDao.searchForIds("value-quantity", param);
|
||||||
assertEquals(1, found.size());
|
assertEquals(1, found.size());
|
||||||
|
|
||||||
param = new QuantityParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, methodName + "units");
|
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, methodName + "units");
|
||||||
found = myObservationDao.searchForIds("value-quantity", param);
|
found = myObservationDao.searchForIds("value-quantity", param);
|
||||||
assertEquals(1, found.size());
|
assertEquals(1, found.size());
|
||||||
|
|
||||||
|
@ -1406,8 +1403,8 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
public void testSearchWithEmptySort() {
|
public void testSearchWithEmptySort() {
|
||||||
SearchParameterMap criteriaUrl = new SearchParameterMap();
|
SearchParameterMap criteriaUrl = new SearchParameterMap();
|
||||||
DateRangeParam range = new DateRangeParam();
|
DateRangeParam range = new DateRangeParam();
|
||||||
range.setLowerBound(new DateParam(QuantityCompararatorEnum.GREATERTHAN, 1000000));
|
range.setLowerBound(new DateParam(ParamPrefixEnum.GREATERTHAN, 1000000));
|
||||||
range.setUpperBound(new DateParam(QuantityCompararatorEnum.LESSTHAN, 2000000));
|
range.setUpperBound(new DateParam(ParamPrefixEnum.LESSTHAN, 2000000));
|
||||||
criteriaUrl.setLastUpdated(range);
|
criteriaUrl.setLastUpdated(range);
|
||||||
criteriaUrl.setSort(new SortSpec(Constants.PARAM_LASTUPDATED, SortOrderEnum.ASC));
|
criteriaUrl.setSort(new SortSpec(Constants.PARAM_LASTUPDATED, SortOrderEnum.ASC));
|
||||||
IBundleProvider results = myObservationDao.search(criteriaUrl);
|
IBundleProvider results = myObservationDao.search(criteriaUrl);
|
||||||
|
@ -1555,7 +1552,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.add(BaseResource.SP_RES_ID, new StringParam(orgId.getIdPart()));
|
params.add(IAnyResource.SP_RES_ID, new StringParam(orgId.getIdPart()));
|
||||||
params.addInclude(Organization.INCLUDE_PARTOF.asNonRecursive());
|
params.addInclude(Organization.INCLUDE_PARTOF.asNonRecursive());
|
||||||
List<IIdType> resources = toUnqualifiedVersionlessIds(myOrganizationDao.search(params));
|
List<IIdType> resources = toUnqualifiedVersionlessIds(myOrganizationDao.search(params));
|
||||||
assertThat(resources, contains(orgId, parentOrgId));
|
assertThat(resources, contains(orgId, parentOrgId));
|
||||||
|
@ -1597,7 +1594,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.add(Organization.SP_RES_ID, new StringParam(orgId.getIdPart()));
|
params.add(IAnyResource.SP_RES_ID, new StringParam(orgId.getIdPart()));
|
||||||
params.addInclude(Organization.INCLUDE_PARTOF.asRecursive());
|
params.addInclude(Organization.INCLUDE_PARTOF.asRecursive());
|
||||||
List<IIdType> resources = toUnqualifiedVersionlessIds(myOrganizationDao.search(params));
|
List<IIdType> resources = toUnqualifiedVersionlessIds(myOrganizationDao.search(params));
|
||||||
ourLog.info(resources.toString());
|
ourLog.info(resources.toString());
|
||||||
|
|
|
@ -42,8 +42,10 @@ import org.hl7.fhir.dstu3.model.UriType;
|
||||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
@ -112,7 +114,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
||||||
// Try making the resource unparseable
|
// Try making the resource unparseable
|
||||||
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myTxManager);
|
TransactionTemplate template = new TransactionTemplate(myTxManager);
|
||||||
template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||||
template.execute(new TransactionCallback<ResourceTable>() {
|
template.execute(new TransactionCallback<ResourceTable>() {
|
||||||
@Override
|
@Override
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||||
|
@ -305,6 +307,100 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
myDaoConfig.setAllowInlineMatchUrlReferences(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionCreateInlineMatchUrlWithOneMatch() {
|
||||||
|
String methodName = "testTransactionCreateInlineMatchUrlWithOneMatch";
|
||||||
|
Bundle request = new Bundle();
|
||||||
|
|
||||||
|
myDaoConfig.setAllowInlineMatchUrlReferences(true);
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
p.setId("Patient/" + methodName);
|
||||||
|
IIdType id = myPatientDao.update(p, mySrd).getId();
|
||||||
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
|
Observation o = new Observation();
|
||||||
|
o.getCode().setText("Some Observation");
|
||||||
|
o.getSubject().setReference("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||||
|
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
|
||||||
|
|
||||||
|
Bundle resp = mySystemDao.transaction(myRequestDetails, request);
|
||||||
|
assertEquals(1, resp.getEntry().size());
|
||||||
|
|
||||||
|
BundleEntryComponent respEntry = resp.getEntry().get(0);
|
||||||
|
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
|
||||||
|
assertThat(respEntry.getResponse().getLocation(), containsString("Observation/"));
|
||||||
|
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||||
|
assertEquals("1", respEntry.getResponse().getEtag());
|
||||||
|
|
||||||
|
o = myObservationDao.read(new IdType(respEntry.getResponse().getLocationElement()), mySrd);
|
||||||
|
assertEquals(id.toVersionless().getValue(), o.getSubject().getReference());
|
||||||
|
assertEquals("1", o.getIdElement().getVersionIdPart());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionCreateInlineMatchUrlWithNoMatches() {
|
||||||
|
String methodName = "testTransactionCreateInlineMatchUrlWithNoMatches";
|
||||||
|
Bundle request = new Bundle();
|
||||||
|
|
||||||
|
myDaoConfig.setAllowInlineMatchUrlReferences(true);
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
myPatientDao.create(p, mySrd).getId();
|
||||||
|
|
||||||
|
p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
myPatientDao.create(p, mySrd).getId();
|
||||||
|
|
||||||
|
Observation o = new Observation();
|
||||||
|
o.getCode().setText("Some Observation");
|
||||||
|
o.getSubject().setReference("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||||
|
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mySystemDao.transaction(myRequestDetails, request);
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
assertEquals("Invalid match URL \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateInlineMatchUrlWithNoMatches\" - Multiple resources match this search", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionCreateInlineMatchUrlWithTwoMatches() {
|
||||||
|
String methodName = "testTransactionCreateInlineMatchUrlWithTwoMatches";
|
||||||
|
Bundle request = new Bundle();
|
||||||
|
|
||||||
|
myDaoConfig.setAllowInlineMatchUrlReferences(true);
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
myPatientDao.create(p, mySrd).getId();
|
||||||
|
|
||||||
|
p = new Patient();
|
||||||
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
myPatientDao.create(p, mySrd).getId();
|
||||||
|
|
||||||
|
Observation o = new Observation();
|
||||||
|
o.getCode().setText("Some Observation");
|
||||||
|
o.getSubject().setReference("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||||
|
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mySystemDao.transaction(myRequestDetails, request);
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
assertEquals("Invalid match URL \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateInlineMatchUrlWithTwoMatches\" - Multiple resources match this search", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionCreateMatchUrlWithTwoMatch() {
|
public void testTransactionCreateMatchUrlWithTwoMatch() {
|
||||||
String methodName = "testTransactionCreateMatchUrlWithTwoMatch";
|
String methodName = "testTransactionCreateMatchUrlWithTwoMatch";
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
|
||||||
retVal.setSubscriptionPollDelay(5000);
|
retVal.setSubscriptionPollDelay(5000);
|
||||||
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
||||||
retVal.setAllowMultipleDelete(true);
|
retVal.setAllowMultipleDelete(true);
|
||||||
|
retVal.setAllowInlineMatchUrlReferences(true);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
||||||
retVal.setSubscriptionPollDelay(5000);
|
retVal.setSubscriptionPollDelay(5000);
|
||||||
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
||||||
retVal.setAllowMultipleDelete(true);
|
retVal.setAllowMultipleDelete(true);
|
||||||
|
retVal.setAllowInlineMatchUrlReferences(true);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package ca.uhn.fhir.rest.client;
|
package ca.uhn.fhir.rest.client;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
@ -17,11 +19,9 @@ import org.apache.http.message.BasicStatusLine;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
|
||||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
|
@ -48,7 +48,7 @@ public class BinaryClientTest {
|
||||||
|
|
||||||
httpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
httpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||||
ctx.getRestfulClientFactory().setHttpClient(httpClient);
|
ctx.getRestfulClientFactory().setHttpClient(httpClient);
|
||||||
ctx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
|
|
||||||
httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class BinaryClientTest {
|
||||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
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().getContentType()).thenReturn(new BasicHeader("content-type", "foo/bar"));
|
||||||
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] {1,2,3,4}));
|
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 }));
|
||||||
|
|
||||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||||
Binary resp = client.read(new IdDt("http://foo/Patient/123"));
|
Binary resp = client.read(new IdDt("http://foo/Patient/123"));
|
||||||
|
@ -72,13 +72,6 @@ public class BinaryClientTest {
|
||||||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, resp.getContent());
|
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, resp.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
|
|
||||||
IClient c = Mockito.mock(IClient.class, new ReturnsDeepStubs());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate() throws Exception {
|
public void testCreate() throws Exception {
|
||||||
Binary res = new Binary();
|
Binary res = new Binary();
|
||||||
|
@ -92,29 +85,23 @@ public class BinaryClientTest {
|
||||||
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] {}));
|
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] {}));
|
||||||
|
|
||||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||||
MethodOutcome resp = client.create(res);
|
client.create(res);
|
||||||
|
|
||||||
assertEquals(HttpPost.class, capt.getValue().getClass());
|
assertEquals(HttpPost.class, capt.getValue().getClass());
|
||||||
HttpPost post = (HttpPost) capt.getValue();
|
HttpPost post = (HttpPost) capt.getValue();
|
||||||
assertEquals("http://foo/Binary", post.getURI().toString());
|
assertEquals("http://foo/Binary", post.getURI().toString());
|
||||||
|
|
||||||
assertEquals("text/plain", post.getEntity().getContentType().getValue());
|
assertEquals("text/plain", capt.getValue().getFirstHeader("Content-Type").getValue());
|
||||||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, IOUtils.toByteArray(post.getEntity().getContent()));
|
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, IOUtils.toByteArray(post.getEntity().getContent()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String createBundle() {
|
|
||||||
return ctx.newXmlParser().encodeBundleToString(new Bundle());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private interface IClient extends IBasicClient {
|
private interface IClient extends IBasicClient {
|
||||||
|
|
||||||
@Read(type=Binary.class)
|
@Read(type = Binary.class)
|
||||||
public Binary read(@IdParam IdDt theBinary);
|
public Binary read(@IdParam IdDt theBinary);
|
||||||
|
|
||||||
@Create(type=Binary.class)
|
@Create(type = Binary.class)
|
||||||
public MethodOutcome create(@ResourceParam Binary theBinary);
|
public MethodOutcome create(@ResourceParam Binary theBinary);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,8 +173,8 @@ public class DynamicSearchTest {
|
||||||
@Override
|
@Override
|
||||||
public List<RuntimeSearchParam> getSearchParameters() {
|
public List<RuntimeSearchParam> getSearchParameters() {
|
||||||
ArrayList<RuntimeSearchParam> retVal = new ArrayList<RuntimeSearchParam>();
|
ArrayList<RuntimeSearchParam> retVal = new ArrayList<RuntimeSearchParam>();
|
||||||
retVal.add(new RuntimeSearchParam("param1", "This is the first parameter", "Patient.param1", RestSearchParameterTypeEnum.STRING));
|
retVal.add(new RuntimeSearchParam("param1", "This is the first parameter", "Patient.param1", RestSearchParameterTypeEnum.STRING, null));
|
||||||
retVal.add(new RuntimeSearchParam("param2", "This is the second parameter", "Patient.param2", RestSearchParameterTypeEnum.DATE));
|
retVal.add(new RuntimeSearchParam("param2", "This is the second parameter", "Patient.param2", RestSearchParameterTypeEnum.DATE, null));
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ public class GenericClientDstu2Test {
|
||||||
client.fetchConformance().ofType(Conformance.class).execute();
|
client.fetchConformance().ofType(Conformance.class).execute();
|
||||||
assertEquals("http://example.com/fhir/metadata", capt.getAllValues().get(idx).getURI().toASCIIString());
|
assertEquals("http://example.com/fhir/metadata", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
client.fetchConformance().ofType(Conformance.class).encodedJson().execute();
|
client.fetchConformance().ofType(Conformance.class).encodedJson().execute();
|
||||||
|
@ -192,12 +192,12 @@ public class GenericClientDstu2Test {
|
||||||
assertEquals("FAMILY", resp.getName().get(0).getFamily().get(0).getValue());
|
assertEquals("FAMILY", resp.getName().get(0).getFamily().get(0).getValue());
|
||||||
assertEquals("http://" + methodName + ".example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
assertEquals("http://" + methodName + ".example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON));
|
||||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||||
assertEquals("http://" + methodName + ".example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toASCIIString());
|
assertEquals("http://" + methodName + ".example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON));
|
||||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
package ca.uhn.fhir.rest.client;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
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 java.util.Arrays;
|
||||||
|
|
||||||
|
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.Binary;
|
||||||
|
import org.hl7.fhir.dstu3.model.Conformance;
|
||||||
|
import org.hl7.fhir.dstu3.model.OperationOutcome;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
|
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.server.Constants;
|
||||||
|
import ca.uhn.fhir.util.VersionUtil;
|
||||||
|
|
||||||
|
public class GenericClientDstu3Test {
|
||||||
|
private static FhirContext ourCtx;
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClientDstu3Test.class);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] extractBodyAsByteArray(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
||||||
|
byte[] body = IOUtils.toByteArray(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent());
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractBodyAsString(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
||||||
|
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8");
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserAgentForConformance() throws Exception {
|
||||||
|
IParser p = ourCtx.newXmlParser();
|
||||||
|
|
||||||
|
Conformance conf = new Conformance();
|
||||||
|
conf.setCopyright("COPY");
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
|
||||||
|
client.fetchConformance().ofType(Conformance.class).execute();
|
||||||
|
assertEquals("http://example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
|
validateUserAgent(capt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserAgentForBinary() throws Exception {
|
||||||
|
IParser p = ourCtx.newXmlParser();
|
||||||
|
|
||||||
|
Conformance conf = new Conformance();
|
||||||
|
conf.setCopyright("COPY");
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
|
||||||
|
Binary bin = new Binary();
|
||||||
|
bin.setContentType("application/foo");
|
||||||
|
bin.setContent(new byte[] { 0, 1, 2, 3, 4 });
|
||||||
|
client.create().resource(bin).execute();
|
||||||
|
|
||||||
|
ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString());
|
||||||
|
|
||||||
|
assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
|
validateUserAgent(capt);
|
||||||
|
|
||||||
|
assertEquals("application/foo", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue());
|
||||||
|
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||||
|
assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, extractBodyAsByteArray(capt));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBinaryCreateWithNoContentType() 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"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
|
||||||
|
Binary bin = new Binary();
|
||||||
|
bin.setContent(new byte[] { 0, 1, 2, 3, 4 });
|
||||||
|
client.create().resource(bin).execute();
|
||||||
|
|
||||||
|
ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString());
|
||||||
|
|
||||||
|
assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
|
validateUserAgent(capt);
|
||||||
|
|
||||||
|
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||||
|
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||||
|
assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)).getContent());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBinaryCreateWithFhirContentType() 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"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
|
||||||
|
Patient pt = new Patient();
|
||||||
|
pt.getText().setDivAsString("A PATIENT");
|
||||||
|
|
||||||
|
Binary bin = new Binary();
|
||||||
|
bin.setContent(ourCtx.newJsonParser().encodeResourceToString(pt).getBytes("UTF-8"));
|
||||||
|
bin.setContentType(Constants.CT_FHIR_JSON);
|
||||||
|
client.create().resource(bin).execute();
|
||||||
|
|
||||||
|
ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString());
|
||||||
|
|
||||||
|
assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
|
validateUserAgent(capt);
|
||||||
|
|
||||||
|
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||||
|
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||||
|
Binary output = ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt));
|
||||||
|
assertEquals(Constants.CT_FHIR_JSON, output.getContentType());
|
||||||
|
|
||||||
|
Patient outputPt = (Patient) ourCtx.newJsonParser().parseResource(new String(output.getContent(), "UTF-8"));
|
||||||
|
assertEquals("<div>A PATIENT</div>", outputPt.getText().getDivAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateUserAgent(ArgumentCaptor<HttpUriRequest> capt) {
|
||||||
|
assertEquals(1, capt.getAllValues().get(0).getHeaders("User-Agent").length);
|
||||||
|
assertEquals(expectedUserAgent(), capt.getAllValues().get(0).getHeaders("User-Agent")[0].getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String expectedUserAgent() {
|
||||||
|
return "HAPI-FHIR/" + VersionUtil.getVersion() + " (FHIR Client)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
ourCtx = FhirContext.forDstu3();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.hl7.fhir.dstu3.model.Binary;
|
||||||
|
import org.hl7.fhir.dstu3.model.IdType;
|
||||||
|
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 ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.util.PortUtil;
|
||||||
|
|
||||||
|
public class CreateBinaryDstu3Test {
|
||||||
|
private static CloseableHttpClient ourClient;
|
||||||
|
private static int ourPort;
|
||||||
|
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||||
|
private static Server ourServer;
|
||||||
|
private static Binary ourLastBinary;
|
||||||
|
private static String ourLastBinaryString;
|
||||||
|
private static byte[] ourLastBinaryBytes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
ourLastBinary = null;
|
||||||
|
ourLastBinaryBytes = null;
|
||||||
|
ourLastBinaryString = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRawBytesNoContentType() throws Exception {
|
||||||
|
HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary");
|
||||||
|
post.setEntity(new ByteArrayEntity(new byte[] {0,1,2,3,4}));
|
||||||
|
ourClient.execute(post);
|
||||||
|
|
||||||
|
assertNull(ourLastBinary.getContentType());
|
||||||
|
assertArrayEquals(new byte[] {0,1,2,3,4}, ourLastBinary.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRawBytesBinaryContentType() throws Exception {
|
||||||
|
HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary");
|
||||||
|
post.setEntity(new ByteArrayEntity(new byte[] {0,1,2,3,4}));
|
||||||
|
post.addHeader("Content-Type", "application/foo");
|
||||||
|
ourClient.execute(post);
|
||||||
|
|
||||||
|
assertEquals("application/foo", ourLastBinary.getContentType());
|
||||||
|
assertArrayEquals(new byte[] {0,1,2,3,4}, ourLastBinary.getContent());
|
||||||
|
assertArrayEquals(new byte[] {0,1,2,3,4}, ourLastBinaryBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Technically the client shouldn't be doing it this way,
|
||||||
|
* but we'll be accepting
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRawBytesFhirContentType() throws Exception {
|
||||||
|
|
||||||
|
Binary b = new Binary();
|
||||||
|
b.setContentType("application/foo");
|
||||||
|
b.setContent(new byte[] {0,1,2,3,4});
|
||||||
|
String encoded = ourCtx.newJsonParser().encodeResourceToString(b);
|
||||||
|
|
||||||
|
HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary");
|
||||||
|
post.setEntity(new StringEntity(encoded));
|
||||||
|
post.addHeader("Content-Type", Constants.CT_FHIR_JSON);
|
||||||
|
ourClient.execute(post);
|
||||||
|
|
||||||
|
assertEquals("application/foo", ourLastBinary.getContentType());
|
||||||
|
assertArrayEquals(new byte[] {0,1,2,3,4}, ourLastBinary.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRawBytesFhirContentTypeContainingFhir() throws Exception {
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.getText().setDivAsString("A PATIENT");
|
||||||
|
|
||||||
|
Binary b = new Binary();
|
||||||
|
b.setContentType("application/xml+fhir");
|
||||||
|
b.setContent(ourCtx.newXmlParser().encodeResourceToString(p).getBytes("UTF-8"));
|
||||||
|
String encoded = ourCtx.newJsonParser().encodeResourceToString(b);
|
||||||
|
|
||||||
|
HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary");
|
||||||
|
post.setEntity(new StringEntity(encoded));
|
||||||
|
post.addHeader("Content-Type", Constants.CT_FHIR_JSON);
|
||||||
|
ourClient.execute(post);
|
||||||
|
|
||||||
|
assertEquals("application/xml+fhir", ourLastBinary.getContentType());
|
||||||
|
assertArrayEquals(b.getContent(), ourLastBinary.getContent());
|
||||||
|
assertEquals(encoded, ourLastBinaryString);
|
||||||
|
assertArrayEquals(encoded.getBytes("UTF-8"), ourLastBinaryBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws Exception {
|
||||||
|
ourServer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
ourPort = PortUtil.findFreePort();
|
||||||
|
ourServer = new Server(ourPort);
|
||||||
|
|
||||||
|
BinaryProvider binaryProvider = new BinaryProvider();
|
||||||
|
|
||||||
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
|
RestfulServer servlet = new RestfulServer(ourCtx);
|
||||||
|
servlet.setResourceProviders(binaryProvider);
|
||||||
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
|
ourServer.setHandler(proxyHandler);
|
||||||
|
ourServer.start();
|
||||||
|
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||||
|
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||||
|
builder.setConnectionManager(connectionManager);
|
||||||
|
ourClient = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BinaryProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
|
return Binary.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Create()
|
||||||
|
public MethodOutcome createBinary(@ResourceParam Binary theBinary, @ResourceParam String theBinaryString, @ResourceParam byte[] theBinaryBytes) {
|
||||||
|
ourLastBinary = theBinary;
|
||||||
|
ourLastBinaryString = theBinaryString;
|
||||||
|
ourLastBinaryBytes = theBinaryBytes;
|
||||||
|
return new MethodOutcome(new IdType("Binary/001/_history/002"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
package ca.uhn.fhir.tinder;
|
|
||||||
|
|
||||||
import org.apache.maven.plugin.AbstractMojo;
|
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
|
||||||
import org.apache.maven.plugin.MojoFailureException;
|
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.tinder.parser.CompartmentParser;
|
|
||||||
|
|
||||||
public class CompartmentGeneratorMojo extends AbstractMojo {
|
|
||||||
|
|
||||||
@Parameter(required = true)
|
|
||||||
private String fhirVersion;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
|
||||||
CompartmentParser p = new CompartmentParser(fhirVersion);
|
|
||||||
try {
|
|
||||||
p.parse();
|
|
||||||
} catch (MojoExecutionException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (MojoFailureException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new MojoFailureException("Failure during parse", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws MojoExecutionException, MojoFailureException {
|
|
||||||
CompartmentGeneratorMojo mojo = new CompartmentGeneratorMojo();
|
|
||||||
mojo.fhirVersion = "dstu2";
|
|
||||||
mojo.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -228,7 +228,7 @@ public class TinderStructuresMojo extends AbstractMojo {
|
||||||
String dtOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/composite";
|
String dtOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/composite";
|
||||||
|
|
||||||
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet("dstu2", ".");
|
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet("dstu2", ".");
|
||||||
rp.setBaseResourceNames(Arrays.asList( "supplyrequest"
|
rp.setBaseResourceNames(Arrays.asList( "patient", "auditevent" , "observation"
|
||||||
// //, "contract"
|
// //, "contract"
|
||||||
// "valueset", "organization", "location"
|
// "valueset", "organization", "location"
|
||||||
// , "observation", "conformance"
|
// , "observation", "conformance"
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package ca.uhn.fhir.tinder.model;
|
package ca.uhn.fhir.tinder.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Resource extends BaseRootType {
|
public class Resource extends BaseRootType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,4 +23,20 @@ public class Resource extends BaseRootType {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SearchParameter getSearchParameterByName(String theName) {
|
||||||
|
for (SearchParameter next : getSearchParameters()) {
|
||||||
|
if (next.getName().equalsIgnoreCase(theName)) {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public List<String> getSearchParameterNames() {
|
||||||
|
ArrayList<String> retVal = new ArrayList<String>();
|
||||||
|
for (SearchParameter next : getSearchParameters()) {
|
||||||
|
retVal.add(next.getName());
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
public class SearchParameter {
|
public class SearchParameter {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParameter.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParameter.class);
|
||||||
|
private List<String> myCompartments = new ArrayList<String>();
|
||||||
private List<String> myCompositeOf;
|
private List<String> myCompositeOf;
|
||||||
private List<String> myCompositeTypes;
|
private List<String> myCompositeTypes;
|
||||||
private String myDescription;
|
private String myDescription;
|
||||||
|
@ -18,7 +19,6 @@ public class SearchParameter {
|
||||||
private String myResourceName;
|
private String myResourceName;
|
||||||
private List<String> myTargetTypes;
|
private List<String> myTargetTypes;
|
||||||
private String myType;
|
private String myType;
|
||||||
|
|
||||||
private String myVersion;
|
private String myVersion;
|
||||||
|
|
||||||
public SearchParameter(String theVersion, String theResourceName) {
|
public SearchParameter(String theVersion, String theResourceName) {
|
||||||
|
@ -26,6 +26,14 @@ public class SearchParameter {
|
||||||
this.myResourceName = theResourceName;
|
this.myResourceName = theResourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCompartment(String theCompartment) {
|
||||||
|
myCompartments.add(theCompartment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCompartments() {
|
||||||
|
return myCompartments;
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getCompositeOf() {
|
public List<String> getCompositeOf() {
|
||||||
if (myCompositeOf == null) {
|
if (myCompositeOf == null) {
|
||||||
myCompositeOf = new ArrayList<String>();
|
myCompositeOf = new ArrayList<String>();
|
||||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Set;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
@ -404,7 +405,7 @@ public abstract class BaseStructureSpreadsheetParser extends BaseStructureParser
|
||||||
/**
|
/**
|
||||||
* Subclasses may override
|
* Subclasses may override
|
||||||
*/
|
*/
|
||||||
protected void postProcess(BaseElement theTarget) {
|
protected void postProcess(BaseElement theTarget) throws MojoFailureException {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,31 @@
|
||||||
package ca.uhn.fhir.tinder.parser;
|
package ca.uhn.fhir.tinder.parser;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.maven.plugin.MojoFailureException;
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.tinder.model.BaseElement;
|
||||||
|
import ca.uhn.fhir.tinder.model.Resource;
|
||||||
|
import ca.uhn.fhir.tinder.model.SearchParameter;
|
||||||
import ca.uhn.fhir.tinder.util.XMLUtils;
|
import ca.uhn.fhir.tinder.util.XMLUtils;
|
||||||
|
|
||||||
public class CompartmentParser {
|
public class CompartmentParser {
|
||||||
|
|
||||||
private String myVersion;
|
private String myVersion;
|
||||||
|
private Resource myResourceDef;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CompartmentParser.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CompartmentParser.class);
|
||||||
|
|
||||||
public CompartmentParser(String theVersion) {
|
public CompartmentParser(String theVersion, Resource theResourceDef) {
|
||||||
myVersion = theVersion;
|
myVersion = theVersion;
|
||||||
|
myResourceDef = theResourceDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parse() throws Exception {
|
public void parse() throws Exception {
|
||||||
|
@ -45,6 +56,67 @@ public class CompartmentParser {
|
||||||
throw new Exception("Failed to find worksheet with name 'Data Elements' in spreadsheet: " + resName);
|
throw new Exception("Failed to find worksheet with name 'Data Elements' in spreadsheet: " + resName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Element table = (Element) resourcesSheet.getElementsByTagName("Table").item(0);
|
||||||
|
NodeList rows = table.getElementsByTagName("Row");
|
||||||
|
|
||||||
|
Map<Integer, String> col2compartment = new HashMap<Integer, String>();
|
||||||
|
Element headerRow = (Element) rows.item(0);
|
||||||
|
for (int i = 1; i < headerRow.getElementsByTagName("Cell").getLength(); i++) {
|
||||||
|
Element cellElement = (Element) headerRow.getElementsByTagName("Cell").item(i);
|
||||||
|
Element dataElement = (Element) cellElement.getElementsByTagName("Data").item(0);
|
||||||
|
col2compartment.put(i, dataElement.getTextContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
Element row = null;
|
||||||
|
for (int i = 1; i < rows.getLength(); i++) {
|
||||||
|
Element nextRow = (Element) rows.item(i);
|
||||||
|
|
||||||
|
NodeList cells = nextRow.getElementsByTagName("Cell");
|
||||||
|
Element cellElement = (Element) cells.item(0);
|
||||||
|
Element dataElement = (Element) cellElement.getElementsByTagName("Data").item(0);
|
||||||
|
if (dataElement.getTextContent().equals(myResourceDef.getName())) {
|
||||||
|
row = nextRow;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row == null) {
|
||||||
|
ourLog.debug("No compartments for resource {}", myResourceDef.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList cells = row.getElementsByTagName("Cell");
|
||||||
|
for (int i = 1; i < cells.getLength(); i++) {
|
||||||
|
Element cellElement = (Element) cells.item(i);
|
||||||
|
int index = i;
|
||||||
|
if (cellElement.hasAttribute("Index")) {
|
||||||
|
index = Integer.parseInt(cellElement.getAttribute("Index"));
|
||||||
|
}
|
||||||
|
|
||||||
|
String compartment = col2compartment.get(index);
|
||||||
|
|
||||||
|
Element dataElement = (Element) cellElement.getElementsByTagName("Data").item(0);
|
||||||
|
String namesUnsplit = dataElement.getTextContent();
|
||||||
|
String[] namesSplit = namesUnsplit.split("\\|");
|
||||||
|
for (String nextName : namesSplit) {
|
||||||
|
nextName = nextName.trim();
|
||||||
|
if (isBlank(nextName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = nextName.split("\\.");
|
||||||
|
if (parts[0].equals("{def}")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Resource element = myResourceDef;
|
||||||
|
SearchParameter sp = element.getSearchParameterByName(parts[0]);
|
||||||
|
if (sp == null) {
|
||||||
|
throw new MojoFailureException("Can't find child named " + parts[0] + " - Valid names: " + element.getSearchParameterNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.addCompartment(compartment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import com.google.common.reflect.ClassPath.ClassInfo;
|
||||||
public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetParser {
|
public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetParser {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postProcess(BaseElement theTarget) {
|
protected void postProcess(BaseElement theTarget) throws MojoFailureException {
|
||||||
super.postProcess(theTarget);
|
super.postProcess(theTarget);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -26,12 +26,21 @@ public class ResourceGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postProcess(BaseElement theTarget) {
|
protected void postProcess(BaseElement theTarget) throws MojoFailureException {
|
||||||
super.postProcess(theTarget);
|
super.postProcess(theTarget);
|
||||||
|
|
||||||
if ("Bundle".equals(theTarget.getName())) {
|
if ("Bundle".equals(theTarget.getName())) {
|
||||||
addEverythingToSummary(theTarget);
|
addEverythingToSummary(theTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getVersion().equals("dstu2") && theTarget instanceof Resource) {
|
||||||
|
try {
|
||||||
|
new CompartmentParser(getVersion(), (Resource) theTarget).parse();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MojoFailureException(e.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEverythingToSummary(BaseElement theTarget) {
|
private void addEverythingToSummary(BaseElement theTarget) {
|
||||||
|
|
|
@ -56,6 +56,13 @@ public class ${className} extends ca.uhn.fhir.model.${version}.resource.BaseReso
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@SearchParamDefinition(name="${param.name}", path="${param.path}", description="${param.description}", type="${param.type}" #{if}($param.compositeOf.empty == false) , compositeOf={ #{foreach}($compositeOf in $param.compositeOf) "${compositeOf}"#{if}($foreach.hasNext), #{end}#{end} } #{end} )
|
@SearchParamDefinition(name="${param.name}", path="${param.path}", description="${param.description}", type="${param.type}" #{if}($param.compositeOf.empty == false) , compositeOf={ #{foreach}($compositeOf in $param.compositeOf) "${compositeOf}"#{if}($foreach.hasNext), #{end}#{end} } #{end} )
|
||||||
|
#if ($param.compartments.size() > 0)
|
||||||
|
@Compartments(providesMembershipIn={
|
||||||
|
#foreach ($compartment in $param.compartments)
|
||||||
|
@Compartment(name="$compartment") #{if}($foreach.hasNext), #{end}
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
#end
|
||||||
public static final String $param.constantName = "${param.name}";
|
public static final String $param.constantName = "${param.name}";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -59,6 +59,50 @@
|
||||||
<action type="add">
|
<action type="add">
|
||||||
JPA server now supports :above and :below qualifiers on URI search params
|
JPA server now supports :above and :below qualifiers on URI search params
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Add optional support (disabled by default for now) to JPA server to support
|
||||||
|
inline references containing search URLs. These URLs will be resolved when
|
||||||
|
a resource is being created/updated and replaced with the single matching
|
||||||
|
resource. This is being used as a part of the May 2016 Connectathon for
|
||||||
|
a testing scenario.
|
||||||
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
The server no longer adds a
|
||||||
|
<![CDATA[<code>WWW-Authenticate</code>]]>
|
||||||
|
header to the response if any resource provider code throws an
|
||||||
|
<![CDATA[<code>AuthenticationException</code>]]>. This header is
|
||||||
|
used for interactive authentication, which isn't generally
|
||||||
|
appropriate for FHIR. We added code to add this header a long time
|
||||||
|
ago for testing purposes and it never got removed. Please let us
|
||||||
|
know if you need the ability to add this header automatically. Thanks
|
||||||
|
to Lars Kristian Roland for pointing this out.
|
||||||
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
In the client, the create/update operations on a Binary resource
|
||||||
|
(which use the raw binary's content type as opposed to the FHIR
|
||||||
|
content type) were not including any request headers (Content-Type,
|
||||||
|
User-Agent, etc.) Thanks to Peter Van Houte of Agfa Healthcare for
|
||||||
|
reporting!
|
||||||
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
Handling of Binary resources containing embedded FHIR resources for
|
||||||
|
create/update/etc operations has been corrected per the FHIR rules
|
||||||
|
outlined at
|
||||||
|
<a href="http://hl7.org/fhir/binary.html">Binary Resource</a> in both
|
||||||
|
the client and server.
|
||||||
|
<![CDATA[<br/><br/>]]>
|
||||||
|
Essentially, if the Binary contains something
|
||||||
|
that isn't FHIR (e.g. an image with an image content-type) the
|
||||||
|
client will send the raw data with the image content type to the server. The
|
||||||
|
server will place the content type and raw data into a Binary resource instance
|
||||||
|
and pass those to the resource provider. This part was already correct previous
|
||||||
|
to 1.5.
|
||||||
|
<![CDATA[<br/><br/>]]>
|
||||||
|
On the other hand, if the Binary contains a FHIR content type, the Binary
|
||||||
|
is now sent by the client to the server as a Binary resource with a FHIR content-type,
|
||||||
|
and the embedded FHIR content is contained in the appropriate fields. The server
|
||||||
|
will pass this "outer" Binary resource to the resource provider code.
|
||||||
|
</action>
|
||||||
<action type="add">
|
<action type="add">
|
||||||
The RequestDetails and ActionRequestDetails objects which are passed to
|
The RequestDetails and ActionRequestDetails objects which are passed to
|
||||||
server interceptor methods and may also be used as server provider method
|
server interceptor methods and may also be used as server provider method
|
||||||
|
|
|
@ -115,8 +115,9 @@
|
||||||
Update methods must be annotated with the
|
Update methods must be annotated with the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Update.html">@Update</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Update.html">@Update</a>
|
||||||
annotation, and have a parameter annotated with the
|
annotation, and have a parameter annotated with the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@Resource</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@ResourceParam</a>
|
||||||
annotation. This parameter contains the resource instance to be created.
|
annotation. This parameter contains the resource instance to be created.
|
||||||
|
See the <a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@ResourceParam</a> for information on the types allowed for this parameter (resource types, String, byte[]).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
In addition, the method may optionally have a parameter annotated with the
|
In addition, the method may optionally have a parameter annotated with the
|
||||||
|
@ -316,8 +317,9 @@
|
||||||
Create methods must be annotated with the
|
Create methods must be annotated with the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Create.html">@Create</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Create.html">@Create</a>
|
||||||
annotation, and have a single parameter annotated with the
|
annotation, and have a single parameter annotated with the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@Resource</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@ResourceParam</a>
|
||||||
annotation. This parameter contains the resource instance to be created.
|
annotation. This parameter contains the resource instance to be created.
|
||||||
|
See the <a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@ResourceParam</a> for information on the types allowed for this parameter (resource types, String, byte[]).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Create methods must return an object of type
|
Create methods must return an object of type
|
||||||
|
@ -1104,7 +1106,7 @@
|
||||||
Validate methods must be annotated with the
|
Validate methods must be annotated with the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Validate.html">@Validate</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/annotation/Validate.html">@Validate</a>
|
||||||
annotation, and have a parameter annotated with the
|
annotation, and have a parameter annotated with the
|
||||||
<a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@Resource</a>
|
<a href="./apidocs/ca/uhn/fhir/rest/annotation/ResourceParam.html">@ResourceParam</a>
|
||||||
annotation. This parameter contains the resource instance to be created.
|
annotation. This parameter contains the resource instance to be created.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|
Loading…
Reference in New Issue