Merge branch 'hapi3_refactor' of github.com:jamesagnew/hapi-fhir into hapi3_refactor
This commit is contained in:
commit
95a607d155
|
@ -140,6 +140,11 @@ public enum FhirVersionEnum {
|
|||
String provideVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class attempts to read the FHIR version from the actual model
|
||||
* classes in order to supply an accurate version string even over time
|
||||
*
|
||||
*/
|
||||
private static class Dstu3Version implements IVersionProvider {
|
||||
|
||||
public Dstu3Version() {
|
||||
|
@ -147,7 +152,7 @@ public enum FhirVersionEnum {
|
|||
Class<?> c = Class.forName("org.hl7.fhir.dstu3.model.Constants");
|
||||
myVersion = (String) c.getDeclaredField("VERSION").get(null);
|
||||
} catch (Exception e) {
|
||||
myVersion = "UNKNOWN";
|
||||
myVersion = "3.0.1";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +172,7 @@ public enum FhirVersionEnum {
|
|||
Class<?> c = Class.forName("org.hl7.fhir.r4.model.Constants");
|
||||
myVersion = (String) c.getDeclaredField("VERSION").get(null);
|
||||
} catch (Exception e) {
|
||||
myVersion = "UNKNOWN";
|
||||
myVersion = "4.0.0";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -301,11 +301,16 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
b.append(myResourceType);
|
||||
}
|
||||
|
||||
if (b.length() > 0) {
|
||||
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
if (isNotBlank(myUnqualifiedId)) {
|
||||
b.append(myUnqualifiedId);
|
||||
} else if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
b.append(myUnqualifiedId);
|
||||
if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
b.append(Constants.PARAM_HISTORY);
|
||||
|
@ -381,7 +386,7 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return isBlank(getValue());
|
||||
return super.isBaseEmpty() && isBlank(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -523,7 +528,21 @@ public class IdDt extends UriDt implements /*IPrimitiveDatatype<String>, */IIdTy
|
|||
if (typeIndex == -1) {
|
||||
myResourceType = theValue.substring(0, idIndex);
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
|
||||
typeIndex = theValue.indexOf('/', typeIndex + 1);
|
||||
}
|
||||
if (typeIndex >= idIndex) {
|
||||
// e.g. http://example.org/foo
|
||||
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
|
||||
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
|
||||
// recreate the url
|
||||
myResourceType = myUnqualifiedId;
|
||||
myUnqualifiedId = null;
|
||||
super.setValue(null);
|
||||
myHaveComponentParts = true;
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
}
|
||||
|
||||
if (typeIndex > 4) {
|
||||
myBaseUrl = theValue.substring(0, typeIndex);
|
||||
|
|
|
@ -47,6 +47,8 @@ import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
|||
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.ID_DATATYPE;
|
||||
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.PRIMITIVE_DATATYPE;
|
||||
|
||||
/**
|
||||
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use
|
||||
|
@ -610,14 +612,28 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
|||
}
|
||||
|
||||
write(theEventWriter, "resourceType", resDef.getName());
|
||||
if (theResourceId != null && theResourceId.hasIdPart()) {
|
||||
write(theEventWriter, "id", theResourceId.getIdPart());
|
||||
if (theResourceId.hasFormatComment()) {
|
||||
beginObject(theEventWriter, "_id");
|
||||
writeCommentsPreAndPost(theResourceId, theEventWriter);
|
||||
theEventWriter.endObject();
|
||||
}
|
||||
}
|
||||
if (theResourceId != null && theResourceId.hasIdPart()) {
|
||||
write(theEventWriter, "id", theResourceId.getIdPart());
|
||||
final List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
|
||||
final List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
|
||||
// Undeclared extensions
|
||||
extractUndeclaredExtensions(theResourceId, extensions, modifierExtensions, null, null);
|
||||
boolean haveExtension = false;
|
||||
if (!extensions.isEmpty()) {
|
||||
haveExtension = true;
|
||||
}
|
||||
|
||||
if (theResourceId.hasFormatComment() || haveExtension) {
|
||||
beginObject(theEventWriter, "_id");
|
||||
if (theResourceId.hasFormatComment()) {
|
||||
writeCommentsPreAndPost(theResourceId, theEventWriter);
|
||||
}
|
||||
if (haveExtension) {
|
||||
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions);
|
||||
}
|
||||
theEventWriter.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
if (theResource instanceof IResource) {
|
||||
IResource resource = (IResource) theResource;
|
||||
|
@ -1013,41 +1029,78 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
|||
}
|
||||
}
|
||||
|
||||
private void parseExtension(ParserState<?> theState, JsonLikeArray theValues, boolean theIsModifier) {
|
||||
for (int i = 0; i < theValues.size(); i++) {
|
||||
JsonLikeObject nextExtObj = JsonLikeValue.asObject(theValues.get(i));
|
||||
JsonLikeValue jsonElement = nextExtObj.get("url");
|
||||
String url;
|
||||
if (null == jsonElement || !(jsonElement.isScalar())) {
|
||||
String parentElementName;
|
||||
if (theIsModifier) {
|
||||
parentElementName = "modifierExtension";
|
||||
} else {
|
||||
parentElementName = "extension";
|
||||
}
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation(parentElementName), "url");
|
||||
url = null;
|
||||
} else {
|
||||
url = getExtensionUrl(jsonElement.getAsString());
|
||||
}
|
||||
theState.enteringNewElementExtension(null, url, theIsModifier, getServerBaseUrl());
|
||||
for (String next : nextExtObj.keySet()) {
|
||||
if ("url".equals(next)) {
|
||||
continue;
|
||||
} else if ("extension".equals(next)) {
|
||||
JsonLikeArray jsonVal = JsonLikeValue.asArray(nextExtObj.get(next));
|
||||
parseExtension(theState, jsonVal, false);
|
||||
} else if ("modifierExtension".equals(next)) {
|
||||
JsonLikeArray jsonVal = JsonLikeValue.asArray(nextExtObj.get(next));
|
||||
parseExtension(theState, jsonVal, true);
|
||||
} else {
|
||||
JsonLikeValue jsonVal = nextExtObj.get(next);
|
||||
parseChildren(theState, next, jsonVal, null, null, false);
|
||||
}
|
||||
}
|
||||
theState.endingElement();
|
||||
}
|
||||
}
|
||||
private void parseExtension(ParserState<?> theState, JsonLikeArray theValues, boolean theIsModifier) {
|
||||
int allUnderscoreNames = 0;
|
||||
int handledUnderscoreNames = 0;
|
||||
|
||||
for (int i = 0; i < theValues.size(); i++) {
|
||||
JsonLikeObject nextExtObj = JsonLikeValue.asObject(theValues.get(i));
|
||||
JsonLikeValue jsonElement = nextExtObj.get("url");
|
||||
String url;
|
||||
if (null == jsonElement || !(jsonElement.isScalar())) {
|
||||
String parentElementName;
|
||||
if (theIsModifier) {
|
||||
parentElementName = "modifierExtension";
|
||||
} else {
|
||||
parentElementName = "extension";
|
||||
}
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation(parentElementName), "url");
|
||||
url = null;
|
||||
} else {
|
||||
url = getExtensionUrl(jsonElement.getAsString());
|
||||
}
|
||||
theState.enteringNewElementExtension(null, url, theIsModifier, getServerBaseUrl());
|
||||
for (String next : nextExtObj.keySet()) {
|
||||
if ("url".equals(next)) {
|
||||
continue;
|
||||
} else if ("extension".equals(next)) {
|
||||
JsonLikeArray jsonVal = JsonLikeValue.asArray(nextExtObj.get(next));
|
||||
parseExtension(theState, jsonVal, false);
|
||||
} else if ("modifierExtension".equals(next)) {
|
||||
JsonLikeArray jsonVal = JsonLikeValue.asArray(nextExtObj.get(next));
|
||||
parseExtension(theState, jsonVal, true);
|
||||
} else if (next.charAt(0) == '_') {
|
||||
allUnderscoreNames++;
|
||||
continue;
|
||||
} else {
|
||||
JsonLikeValue jsonVal = nextExtObj.get(next);
|
||||
String alternateName = '_' + next;
|
||||
JsonLikeValue alternateVal = nextExtObj.get(alternateName);
|
||||
if (alternateVal != null) {
|
||||
handledUnderscoreNames++;
|
||||
}
|
||||
parseChildren(theState, next, jsonVal, alternateVal, alternateName, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This happens if an element has an extension but no actual value. I.e.
|
||||
* if a resource has a "_status" element but no corresponding "status"
|
||||
* element. This could be used to handle a null value with an extension
|
||||
* for example.
|
||||
*/
|
||||
if (allUnderscoreNames > handledUnderscoreNames) {
|
||||
for (String alternateName : nextExtObj.keySet()) {
|
||||
if (alternateName.startsWith("_") && alternateName.length() > 1) {
|
||||
JsonLikeValue nextValue = nextExtObj.get(alternateName);
|
||||
if (nextValue != null) {
|
||||
if (nextValue.isObject()) {
|
||||
String nextName = alternateName.substring(1);
|
||||
if (nextExtObj.get(nextName) == null) {
|
||||
theState.enteringNewElement(null, nextName);
|
||||
parseAlternates(nextValue, theState, alternateName, alternateName);
|
||||
theState.endingElement();
|
||||
}
|
||||
} else {
|
||||
getErrorHandler().incorrectJsonType(null, alternateName, ValueType.OBJECT, null, nextValue.getJsonType(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
theState.endingElement();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFhirComments(JsonLikeValue theObject, ParserState<?> theState) {
|
||||
if (theObject.isArray()) {
|
||||
|
@ -1314,6 +1367,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
|||
} else {
|
||||
String childName = myDef.getChildNameByDatatype(myValue.getClass());
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName, false, myParent, false);
|
||||
managePrimitiveExtension(myValue, theResDef, theResource, theEventWriter, def, childName);
|
||||
}
|
||||
|
||||
theEventWriter.endObject();
|
||||
|
@ -1368,13 +1422,34 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
|||
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
|
||||
}
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true, myParent, false);
|
||||
managePrimitiveExtension(value, theResDef, theResource, theEventWriter, childDef, childName);
|
||||
}
|
||||
|
||||
// theEventWriter.name(myUndeclaredExtension.get);
|
||||
|
||||
theEventWriter.endObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void managePrimitiveExtension(final IBase theValue, final RuntimeResourceDefinition theResDef, final IBaseResource theResource, final JsonLikeWriter theEventWriter, final BaseRuntimeElementDefinition<?> def, final String childName) throws IOException {
|
||||
if (def.getChildType().equals(ID_DATATYPE) || def.getChildType().equals(PRIMITIVE_DATATYPE)) {
|
||||
final List<HeldExtension> extensions = new ArrayList<HeldExtension>(0);
|
||||
final List<HeldExtension> modifierExtensions = new ArrayList<HeldExtension>(0);
|
||||
// Undeclared extensions
|
||||
extractUndeclaredExtensions(theValue, extensions, modifierExtensions, myParent, null);
|
||||
// Declared extensions
|
||||
if (def != null) {
|
||||
extractDeclaredExtensions(theValue, def, extensions, modifierExtensions, myParent);
|
||||
}
|
||||
boolean haveContent = false;
|
||||
if (!extensions.isEmpty() || !modifierExtensions.isEmpty()) {
|
||||
haveContent = true;
|
||||
}
|
||||
if (haveContent) {
|
||||
beginObject(theEventWriter, '_' + childName);
|
||||
writeExtensionsAsDirectChild(theResource, theEventWriter, theResDef, extensions, modifierExtensions);
|
||||
theEventWriter.endObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,6 +422,7 @@ class ParserState<T> {
|
|||
push(newState);
|
||||
return;
|
||||
}
|
||||
case ID_DATATYPE:
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
|
||||
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
|
||||
|
@ -1155,13 +1156,19 @@ class ParserState<T> {
|
|||
String resourceName = myContext.getResourceDefinition(nextResource).getName();
|
||||
String bundleIdPart = nextResource.getId().getIdPart();
|
||||
if (isNotBlank(bundleIdPart)) {
|
||||
// if (isNotBlank(entryBaseUrl)) {
|
||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||
// } else {
|
||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||
// }
|
||||
// if (isNotBlank(entryBaseUrl)) {
|
||||
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
|
||||
// } else {
|
||||
IdDt previousId = nextResource.getId();
|
||||
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
|
||||
// Copy extensions
|
||||
if (!previousId.getAllUndeclaredExtensions().isEmpty()) {
|
||||
for (final ExtensionDt ext : previousId.getAllUndeclaredExtensions()) {
|
||||
nextResource.getId().addUndeclaredExtension(ext);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -184,9 +184,9 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
heldComments.clear();
|
||||
}
|
||||
parserState.endingElement();
|
||||
// if (parserState.isComplete()) {
|
||||
// return parserState.getObject();
|
||||
// }
|
||||
// if (parserState.isComplete()) {
|
||||
// return parserState.getObject();
|
||||
// }
|
||||
break;
|
||||
}
|
||||
case XMLStreamConstants.CHARACTERS: {
|
||||
|
@ -227,13 +227,17 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
|
||||
switch (childDef.getChildType()) {
|
||||
case ID_DATATYPE: {
|
||||
IIdType value = IIdType.class.cast(theElement);
|
||||
String encodedValue = "id".equals(childName) ? value.getIdPart() : value.getValue();
|
||||
theEventWriter.writeStartElement(childName);
|
||||
theEventWriter.writeAttribute("value", encodedValue);
|
||||
encodeExtensionsIfPresent(theResource, theEventWriter, theElement, theIncludedResource);
|
||||
theEventWriter.writeEndElement();
|
||||
break;
|
||||
IIdType value = IIdType.class.cast(theElement);
|
||||
String encodedValue = "id".equals(childName) ? value.getIdPart() : value.getValue();
|
||||
if (StringUtils.isNotBlank(encodedValue) || super.hasExtensions(value)) {
|
||||
theEventWriter.writeStartElement(childName);
|
||||
if (StringUtils.isNotBlank(encodedValue)) {
|
||||
theEventWriter.writeAttribute("value", encodedValue);
|
||||
}
|
||||
encodeExtensionsIfPresent(theResource, theEventWriter, theElement, theIncludedResource);
|
||||
theEventWriter.writeEndElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PRIMITIVE_DATATYPE: {
|
||||
IPrimitiveType<?> pd = IPrimitiveType.class.cast(theElement);
|
||||
|
@ -354,8 +358,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
}
|
||||
|
||||
if (nextChild instanceof RuntimeChildContainedResources) {
|
||||
encodeChildElementToStreamWriter(theResource, theEventWriter, null, nextChild.getChildNameByDatatype(null), nextChild.getChildElementDefinitionByDatatype(null), null, theContainedResource,
|
||||
nextChildElem);
|
||||
encodeChildElementToStreamWriter(theResource, theEventWriter, null, nextChild.getChildNameByDatatype(null), nextChild.getChildElementDefinitionByDatatype(null), null, theContainedResource, nextChildElem);
|
||||
} else {
|
||||
|
||||
List<? extends IBase> values = nextChild.getAccessor().getValues(theElement);
|
||||
|
@ -398,8 +401,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
}
|
||||
}
|
||||
|
||||
private void encodeExtension(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theContainedResource, CompositeChildElement nextChildElem, BaseRuntimeChildDefinition nextChild,
|
||||
IBase nextValue, String childName, String extensionUrl, BaseRuntimeElementDefinition<?> childDef)
|
||||
private void encodeExtension(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theContainedResource, CompositeChildElement nextChildElem, BaseRuntimeChildDefinition nextChild, IBase nextValue, String childName, String extensionUrl, BaseRuntimeElementDefinition<?> childDef)
|
||||
throws XMLStreamException {
|
||||
BaseRuntimeDeclaredChildDefinition extDef = (BaseRuntimeDeclaredChildDefinition) nextChild;
|
||||
if (extDef.isModifier()) {
|
||||
|
@ -434,8 +436,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
}
|
||||
}
|
||||
|
||||
private void encodeResourceToXmlStreamWriter(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, boolean theSubResource)
|
||||
throws XMLStreamException, DataFormatException {
|
||||
private void encodeResourceToXmlStreamWriter(IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theIncludedResource, boolean theSubResource) throws XMLStreamException, DataFormatException {
|
||||
IIdType resourceId = null;
|
||||
|
||||
if (StringUtils.isNotBlank(theResource.getIdElement().getIdPart())) {
|
||||
|
@ -470,13 +471,15 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
theEventWriter.writeDefaultNamespace(FHIR_NS);
|
||||
|
||||
if (theResource instanceof IAnyResource) {
|
||||
|
||||
// HL7.org Structures
|
||||
if (theResourceId != null) {
|
||||
writeCommentsPre(theEventWriter, theResourceId);
|
||||
writeOptionalTagWithValue(theEventWriter, "id", theResourceId.getIdPart());
|
||||
writeCommentsPost(theEventWriter, theResourceId);
|
||||
}
|
||||
if (theResourceId != null) {
|
||||
writeCommentsPre(theEventWriter, theResourceId);
|
||||
theEventWriter.writeStartElement("id");
|
||||
theEventWriter.writeAttribute("value", theResourceId.getIdPart());
|
||||
encodeExtensionsIfPresent(theResource, theEventWriter, theResourceId, false);
|
||||
theEventWriter.writeEndElement();
|
||||
writeCommentsPost(theEventWriter, theResourceId);
|
||||
}
|
||||
|
||||
encodeCompositeElementToStreamWriter(theResource, theResource, theEventWriter, theContainedResource, new CompositeChildElement(resDef));
|
||||
|
||||
|
@ -485,11 +488,16 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
// DSTU2+
|
||||
|
||||
IResource resource = (IResource) theResource;
|
||||
if (theResourceId != null) {
|
||||
writeCommentsPre(theEventWriter, theResourceId);
|
||||
writeOptionalTagWithValue(theEventWriter, "id", theResourceId.getIdPart());
|
||||
writeCommentsPost(theEventWriter, theResourceId);
|
||||
}
|
||||
if (theResourceId != null) {
|
||||
/* writeCommentsPre(theEventWriter, theResourceId);
|
||||
writeOptionalTagWithValue(theEventWriter, "id", theResourceId.getIdPart());
|
||||
writeCommentsPost(theEventWriter, theResourceId);*/
|
||||
theEventWriter.writeStartElement("id");
|
||||
theEventWriter.writeAttribute("value", theResourceId.getIdPart());
|
||||
encodeExtensionsIfPresent(theResource, theEventWriter, theResourceId, false);
|
||||
theEventWriter.writeEndElement();
|
||||
writeCommentsPost(theEventWriter, theResourceId);
|
||||
}
|
||||
|
||||
InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||
IdDt resourceId = resource.getId();
|
||||
|
|
|
@ -28,20 +28,20 @@ public interface IBaseBundle extends IBaseResource {
|
|||
* link.type field to indicate that the given link is for
|
||||
* the next page of results.
|
||||
*/
|
||||
public static final String LINK_NEXT = "next";
|
||||
String LINK_NEXT = "next";
|
||||
|
||||
/**
|
||||
* Constant for links provided in the bundle. This constant is used in the
|
||||
* link.type field to indicate that the given link is for
|
||||
* the previous page of results.
|
||||
*/
|
||||
public static final String LINK_PREV = "previous";
|
||||
String LINK_PREV = "previous";
|
||||
|
||||
/**
|
||||
* Constant for links provided in the bundle. This constant is used in the
|
||||
* link.type field to indicate that the given link is for
|
||||
* this bundle.
|
||||
*/
|
||||
public static final String LINK_SELF = "self";
|
||||
String LINK_SELF = "self";
|
||||
|
||||
}
|
||||
|
|
|
@ -1755,11 +1755,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
}
|
||||
|
||||
if (myReturnBundleType == null && myContext.getVersion().getVersion().isRi()) {
|
||||
throw new IllegalArgumentException("When using the client with HL7.org structures, you must specify "
|
||||
+ "the bundle return type for the client by adding \".returnBundle(org.hl7.fhir.instance.model.Bundle.class)\" to your search method call before the \".execute()\" method");
|
||||
}
|
||||
|
||||
IClientResponseHandler<? extends IBase> binding;
|
||||
binding = new ResourceResponseHandler(myReturnBundleType, getPreferResponseTypes(myResourceType));
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
private int myConnectionRequestTimeout = DEFAULT_CONNECTION_REQUEST_TIMEOUT;
|
||||
private int myConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||
private FhirContext myContext;
|
||||
private Map<Class<? extends IRestfulClient>, ClientInvocationHandlerFactory> myInvocationHandlers = new HashMap<Class<? extends IRestfulClient>, ClientInvocationHandlerFactory>();
|
||||
private Map<Class<? extends IRestfulClient>, ClientInvocationHandlerFactory> myInvocationHandlers = new HashMap<>();
|
||||
private ServerValidationModeEnum myServerValidationMode = DEFAULT_SERVER_VALIDATION_MODE;
|
||||
private int mySocketTimeout = DEFAULT_SOCKET_TIMEOUT;
|
||||
private String myProxyUsername;
|
||||
|
@ -82,9 +82,6 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
|
||||
/**
|
||||
* Return the proxy username to authenticate with the HTTP proxy
|
||||
*
|
||||
* @param The
|
||||
* proxy username
|
||||
*/
|
||||
protected String getProxyUsername() {
|
||||
return myProxyUsername;
|
||||
|
@ -92,9 +89,6 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
|
||||
/**
|
||||
* Return the proxy password to authenticate with the HTTP proxy
|
||||
*
|
||||
* @param The
|
||||
* proxy password
|
||||
*/
|
||||
protected String getProxyPassword() {
|
||||
return myProxyPassword;
|
||||
|
@ -128,8 +122,7 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends IRestfulClient> T instantiateProxy(Class<T> theClientType, InvocationHandler theInvocationHandler) {
|
||||
T proxy = (T) Proxy.newProxyInstance(theClientType.getClassLoader(), new Class[] { theClientType }, theInvocationHandler);
|
||||
return proxy;
|
||||
return (T) Proxy.newProxyInstance(theClientType.getClassLoader(), new Class[] { theClientType }, theInvocationHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,9 +155,7 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
myInvocationHandlers.put(theClientType, invocationHandler);
|
||||
}
|
||||
|
||||
T proxy = instantiateProxy(theClientType, invocationHandler.newInvocationHandler(this));
|
||||
|
||||
return proxy;
|
||||
return instantiateProxy(theClientType, invocationHandler.newInvocationHandler(this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,13 +322,14 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
FhirVersionEnum serverFhirVersionEnum = null;
|
||||
if (StringUtils.isBlank(serverFhirVersionString)) {
|
||||
// we'll be lenient and accept this
|
||||
ourLog.debug("Server conformance statement does not indicate the FHIR version");
|
||||
} else {
|
||||
if (serverFhirVersionString.startsWith("0.4") || serverFhirVersionString.startsWith("0.5") || serverFhirVersionString.startsWith("1.0.")) {
|
||||
if (serverFhirVersionString.equals(FhirVersionEnum.DSTU2.getFhirVersionString())) {
|
||||
serverFhirVersionEnum = FhirVersionEnum.DSTU2;
|
||||
} else if (serverFhirVersionString.startsWith("3.0.")) {
|
||||
} else if (serverFhirVersionString.equals(FhirVersionEnum.DSTU2_1.getFhirVersionString())) {
|
||||
serverFhirVersionEnum = FhirVersionEnum.DSTU2_1;
|
||||
} else if (serverFhirVersionString.equals(FhirVersionEnum.DSTU3.getFhirVersionString())) {
|
||||
serverFhirVersionEnum = FhirVersionEnum.DSTU3;
|
||||
} else if (serverFhirVersionString.startsWith("3.1.")) {
|
||||
serverFhirVersionEnum = FhirVersionEnum.R4;
|
||||
} else {
|
||||
// we'll be lenient and accept this
|
||||
ourLog.debug("Server conformance statement indicates unknown FHIR version: {}", serverFhirVersionString);
|
||||
|
|
|
@ -264,6 +264,10 @@
|
|||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-messaging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
|
|
|
@ -197,8 +197,16 @@ public class ResourceLink implements Serializable {
|
|||
public void setTargetResourceUrl(IIdType theTargetResourceUrl) {
|
||||
Validate.isTrue(theTargetResourceUrl.hasBaseUrl());
|
||||
Validate.isTrue(theTargetResourceUrl.hasResourceType());
|
||||
Validate.isTrue(theTargetResourceUrl.hasIdPart());
|
||||
|
||||
|
||||
if (theTargetResourceUrl.hasIdPart()) {
|
||||
// do nothing
|
||||
} else {
|
||||
// Must have set an url like http://example.org/something
|
||||
// We treat 'something' as the resource type because of fix for #659. Prior to #659 fix, 'something' was
|
||||
// treated as the id and 'example.org' was treated as the resource type
|
||||
// TODO: log a warning?
|
||||
}
|
||||
|
||||
myTargetResourceType = theTargetResourceUrl.getResourceType();
|
||||
myTargetResourceUrl = theTargetResourceUrl.getValue();
|
||||
}
|
||||
|
|
|
@ -80,7 +80,8 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
*/
|
||||
private void checkSubscriptions(IIdType idType, String resourceType, RestOperationTypeEnum theOperation) {
|
||||
//avoid a ConcurrentModificationException by copying to an array
|
||||
for (Object object : myRestHookSubscriptions.toArray()) {
|
||||
Object[] subscriptions = myRestHookSubscriptions.toArray();
|
||||
for (Object object : subscriptions) {
|
||||
if (object == null) {
|
||||
continue;
|
||||
}
|
||||
|
@ -330,8 +331,9 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti
|
|||
Subscription subscription = (Subscription) theResource;
|
||||
if (subscription.getChannel() != null
|
||||
&& subscription.getChannel().getTypeElement().getValueAsEnum() == SubscriptionChannelTypeEnum.REST_HOOK
|
||||
&& subscription.getStatusElement().getValueAsEnum() == SubscriptionStatusEnum.ACTIVE) {
|
||||
&& subscription.getStatusElement().getValueAsEnum() == SubscriptionStatusEnum.REQUESTED) {
|
||||
removeLocalSubscription(subscription.getIdElement().getIdPart());
|
||||
subscription.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
myRestHookSubscriptions.add(subscription);
|
||||
ourLog.info("Subscription was added. Id: " + subscription.getId());
|
||||
}
|
||||
|
|
|
@ -319,8 +319,9 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti
|
|||
Subscription subscription = (Subscription) theResource;
|
||||
if (subscription.getChannel() != null
|
||||
&& subscription.getChannel().getType() == Subscription.SubscriptionChannelType.RESTHOOK
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.ACTIVE) {
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.REQUESTED) {
|
||||
removeLocalSubscription(subscription.getIdElement().getIdPart());
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
myRestHookSubscriptions.add(subscription);
|
||||
ourLog.info("Subscription was added, id: {} - Have {}", subscription.getIdElement().getIdPart(), myRestHookSubscriptions.size());
|
||||
}
|
||||
|
|
|
@ -58,10 +58,10 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
private final static int MAX_THREADS = 1;
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestHookSubscriptionR4Interceptor.class);
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<>();
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
private final List<Subscription> myRestHookSubscriptions = new ArrayList<Subscription>();
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mySubscriptionDaoR4")
|
||||
|
@ -314,9 +314,10 @@ public class RestHookSubscriptionR4Interceptor extends BaseRestHookSubscriptionI
|
|||
Subscription subscription = (Subscription) theResource;
|
||||
if (subscription.getChannel() != null
|
||||
&& subscription.getChannel().getType() == Subscription.SubscriptionChannelType.RESTHOOK
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.ACTIVE) {
|
||||
&& subscription.getStatus() == Subscription.SubscriptionStatus.REQUESTED) {
|
||||
removeLocalSubscription(subscription.getIdElement().getIdPart());
|
||||
myRestHookSubscriptions.add(subscription);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
ourLog.info("Subscription was added, id: {} - Have {}", subscription.getIdElement().getIdPart(), myRestHookSubscriptions.size());
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ServerOperationInterceptorAdapter;
|
||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public abstract class BaseSubscriptionInterceptor extends ServerOperationInterceptorAdapter {
|
||||
|
||||
private static final Integer MAX_SUBSCRIPTION_RESULTS = 1000;
|
||||
private SubscribableChannel myProcessingChannel;
|
||||
private ExecutorService myExecutor;
|
||||
private boolean myAutoActivateSubscriptions = true;
|
||||
private int myExecutorThreadCount = 1;
|
||||
private MessageHandler mySubscriptionActivatingSubscriber;
|
||||
private MessageHandler mySubscriptionCheckingSubscriber;
|
||||
private ConcurrentHashMap<String, IBaseResource> myIdToSubscription = new ConcurrentHashMap<>();
|
||||
private Subscription.SubscriptionChannelType myChannelType = Subscription.SubscriptionChannelType.RESTHOOK;
|
||||
private Logger ourLog = LoggerFactory.getLogger(BaseSubscriptionInterceptor.class);
|
||||
|
||||
protected abstract IFhirResourceDao<?> getSubscriptionDao();
|
||||
|
||||
/**
|
||||
* Read the existing subscriptions from the database
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Scheduled(fixedDelay = 10000)
|
||||
public void initSubscriptions() {
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Subscription.SP_TYPE, new TokenParam(null, myChannelType.toCode()));
|
||||
map.add(Subscription.SP_STATUS, new TokenParam(null, Subscription.SubscriptionStatus.ACTIVE.toCode()));
|
||||
map.setLoadSynchronousUpTo(MAX_SUBSCRIPTION_RESULTS);
|
||||
|
||||
RequestDetails req = new ServletSubRequestDetails();
|
||||
req.setSubRequest(true);
|
||||
|
||||
IBundleProvider subscriptionBundleList = getSubscriptionDao().search(map, req);
|
||||
if (subscriptionBundleList.size() >= MAX_SUBSCRIPTION_RESULTS) {
|
||||
ourLog.error("Currently over " + MAX_SUBSCRIPTION_RESULTS + " subscriptions. Some subscriptions have not been loaded.");
|
||||
}
|
||||
|
||||
List<IBaseResource> resourceList = subscriptionBundleList.getResources(0, subscriptionBundleList.size());
|
||||
|
||||
Set<String> allIds = new HashSet<>();
|
||||
for (IBaseResource resource : resourceList) {
|
||||
String nextId = resource.getIdElement().getIdPart();
|
||||
allIds.add(nextId);
|
||||
myIdToSubscription.put(nextId, resource);
|
||||
}
|
||||
|
||||
for (String next : myIdToSubscription.keySet()) {
|
||||
if (!allIds.contains(next)) {
|
||||
myIdToSubscription.remove(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
|
||||
ThreadFactory threadFactory = new BasicThreadFactory.Builder()
|
||||
.namingPattern("subscription-%d")
|
||||
.daemon(false)
|
||||
.priority(Thread.NORM_PRIORITY)
|
||||
.build();
|
||||
myExecutor = new ThreadPoolExecutor(
|
||||
myExecutorThreadCount,
|
||||
myExecutorThreadCount,
|
||||
0L,
|
||||
TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(1000),
|
||||
threadFactory,
|
||||
rejectedExecutionHandler);
|
||||
|
||||
|
||||
if (myProcessingChannel == null) {
|
||||
myProcessingChannel = new ExecutorSubscribableChannel(myExecutor);
|
||||
}
|
||||
|
||||
if (myAutoActivateSubscriptions) {
|
||||
if (mySubscriptionActivatingSubscriber == null) {
|
||||
mySubscriptionActivatingSubscriber = new SubscriptionActivatingSubscriber(getSubscriptionDao(), myIdToSubscription, myChannelType, myProcessingChannel);
|
||||
}
|
||||
myProcessingChannel.subscribe(mySubscriptionActivatingSubscriber);
|
||||
}
|
||||
|
||||
if (mySubscriptionCheckingSubscriber == null) {
|
||||
mySubscriptionCheckingSubscriber = new SubscriptionCheckingSubscriber(getSubscriptionDao(), myIdToSubscription, myChannelType, myProcessingChannel);
|
||||
}
|
||||
myProcessingChannel.subscribe(mySubscriptionCheckingSubscriber);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@PreDestroy
|
||||
public void preDestroy() {
|
||||
if (myAutoActivateSubscriptions) {
|
||||
myProcessingChannel.unsubscribe(mySubscriptionActivatingSubscriber);
|
||||
}
|
||||
myProcessingChannel.unsubscribe(mySubscriptionCheckingSubscriber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resourceCreated(RequestDetails theRequest, IBaseResource theResource) {
|
||||
ResourceModifiedMessage msg = new ResourceModifiedMessage();
|
||||
msg.setId(theResource.getIdElement());
|
||||
msg.setOperationType(RestOperationTypeEnum.CREATE);
|
||||
msg.setNewPayload(theResource);
|
||||
submitResourceModified(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resourceDeleted(RequestDetails theRequest, IBaseResource theResource) {
|
||||
ResourceModifiedMessage msg = new ResourceModifiedMessage();
|
||||
msg.setId(theResource.getIdElement());
|
||||
msg.setOperationType(RestOperationTypeEnum.DELETE);
|
||||
submitResourceModified(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resourceUpdated(RequestDetails theRequest, IBaseResource theOldResource, IBaseResource theNewResource) {
|
||||
ResourceModifiedMessage msg = new ResourceModifiedMessage();
|
||||
msg.setId(theNewResource.getIdElement());
|
||||
msg.setOperationType(RestOperationTypeEnum.UPDATE);
|
||||
msg.setNewPayload(theNewResource);
|
||||
submitResourceModified(msg);
|
||||
}
|
||||
|
||||
private void submitResourceModified(ResourceModifiedMessage theMsg) {
|
||||
myProcessingChannel.send(new GenericMessage<>(theMsg));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class BaseSubscriptionSubscriber implements MessageHandler {
|
||||
static final String SUBSCRIPTION_STATUS = "Subscription.status";
|
||||
private static final String SUBSCRIPTION_TYPE = "Subscription.channel.type";
|
||||
private final IFhirResourceDao mySubscriptionDao;
|
||||
private final ConcurrentHashMap<String, IBaseResource> myIdToSubscription;
|
||||
private final Subscription.SubscriptionChannelType myChannelType;
|
||||
private final SubscribableChannel myProcessingChannel;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public BaseSubscriptionSubscriber(IFhirResourceDao<? extends IBaseResource> theSubscriptionDao, ConcurrentHashMap<String, IBaseResource> theIdToSubscription, Subscription.SubscriptionChannelType theChannelType, SubscribableChannel theProcessingChannel) {
|
||||
mySubscriptionDao = theSubscriptionDao;
|
||||
myIdToSubscription = theIdToSubscription;
|
||||
myChannelType = theChannelType;
|
||||
myProcessingChannel = theProcessingChannel;
|
||||
}
|
||||
|
||||
public Subscription.SubscriptionChannelType getChannelType() {
|
||||
return myChannelType;
|
||||
}
|
||||
|
||||
public FhirContext getContext() {
|
||||
return getSubscriptionDao().getContext();
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<String, IBaseResource> getIdToSubscription() {
|
||||
return myIdToSubscription;
|
||||
}
|
||||
|
||||
public SubscribableChannel getProcessingChannel() {
|
||||
return myProcessingChannel;
|
||||
}
|
||||
|
||||
public IFhirResourceDao getSubscriptionDao() {
|
||||
return mySubscriptionDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this subscription type (e.g. rest hook, websocket, etc) apply to this interceptor?
|
||||
*/
|
||||
protected boolean subscriptionTypeApplies(ResourceModifiedMessage theMsg) {
|
||||
FhirContext ctx = mySubscriptionDao.getContext();
|
||||
IBaseResource subscription = theMsg.getNewPayload();
|
||||
return subscriptionTypeApplies(ctx, subscription);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this subscription type (e.g. rest hook, websocket, etc) apply to this interceptor?
|
||||
*/
|
||||
protected boolean subscriptionTypeApplies(FhirContext theCtx, IBaseResource theSubscription) {
|
||||
IPrimitiveType<?> status = theCtx.newTerser().getSingleValueOrNull(theSubscription, SUBSCRIPTION_TYPE, IPrimitiveType.class);
|
||||
boolean subscriptionTypeApplies = false;
|
||||
if (getChannelType().toCode().equals(status.getValueAsString())) {
|
||||
subscriptionTypeApplies = true;
|
||||
}
|
||||
return subscriptionTypeApplies;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ResourceDeliveryMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
private IBaseResource mySubscription;
|
||||
private IBaseResource myPayoad;
|
||||
private RestOperationTypeEnum myOperationType;
|
||||
|
||||
public RestOperationTypeEnum getOperationType() {
|
||||
return myOperationType;
|
||||
}
|
||||
|
||||
public void setOperationType(RestOperationTypeEnum theOperationType) {
|
||||
myOperationType = theOperationType;
|
||||
}
|
||||
|
||||
public IBaseResource getPayoad() {
|
||||
return myPayoad;
|
||||
}
|
||||
|
||||
public void setPayoad(IBaseResource thePayoad) {
|
||||
myPayoad = thePayoad;
|
||||
}
|
||||
|
||||
public IBaseResource getSubscription() {
|
||||
return mySubscription;
|
||||
}
|
||||
|
||||
public void setSubscription(IBaseResource theSubscription) {
|
||||
mySubscription = theSubscription;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ResourceModifiedMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
private IIdType myId;
|
||||
private RestOperationTypeEnum myOperationType;
|
||||
private IBaseResource myNewPayload;
|
||||
|
||||
public IIdType getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
public void setId(IIdType theId) {
|
||||
myId = theId;
|
||||
}
|
||||
|
||||
|
||||
public RestOperationTypeEnum getOperationType() {
|
||||
return myOperationType;
|
||||
}
|
||||
|
||||
public void setOperationType(RestOperationTypeEnum theOperationType) {
|
||||
myOperationType = theOperationType;
|
||||
}
|
||||
|
||||
public IBaseResource getNewPayload() {
|
||||
return myNewPayload;
|
||||
}
|
||||
|
||||
public void setNewPayload(IBaseResource theNewPayload) {
|
||||
myNewPayload = theNewPayload;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class SubscriptionActivatingSubscriber extends BaseSubscriptionSubscriber {
|
||||
private Logger ourLog = LoggerFactory.getLogger(SubscriptionActivatingSubscriber.class);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public SubscriptionActivatingSubscriber(IFhirResourceDao<? extends IBaseResource> theSubscriptionDao, ConcurrentHashMap<String, IBaseResource> theIdToSubscription, Subscription.SubscriptionChannelType theChannelType, SubscribableChannel theProcessingChannel) {
|
||||
super(theSubscriptionDao, theIdToSubscription, theChannelType, theProcessingChannel);
|
||||
}
|
||||
|
||||
private void handleCreate(ResourceModifiedMessage theMsg) {
|
||||
if (!theMsg.getId().getResourceType().equals("Subscription")) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean subscriptionTypeApplies = subscriptionTypeApplies(theMsg);
|
||||
if (subscriptionTypeApplies == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
FhirContext ctx = getSubscriptionDao().getContext();
|
||||
IBaseResource subscription = theMsg.getNewPayload();
|
||||
IPrimitiveType<?> status = ctx.newTerser().getSingleValueOrNull(subscription, SUBSCRIPTION_STATUS, IPrimitiveType.class);
|
||||
String statusString = status.getValueAsString();
|
||||
|
||||
String oldStatus = Subscription.SubscriptionStatus.REQUESTED.toCode();
|
||||
if (oldStatus.equals(statusString)) {
|
||||
String newStatus = Subscription.SubscriptionStatus.ACTIVE.toCode();
|
||||
status.setValueAsString(newStatus);
|
||||
ourLog.info("Activating subscription {} from status {} to {}", subscription.getIdElement().toUnqualifiedVersionless().getValue(), oldStatus, newStatus);
|
||||
getSubscriptionDao().update(subscription);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> theMessage) throws MessagingException {
|
||||
|
||||
if (!(theMessage.getPayload() instanceof ResourceModifiedMessage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceModifiedMessage msg = (ResourceModifiedMessage) theMessage.getPayload();
|
||||
IIdType id = msg.getId();
|
||||
|
||||
switch (msg.getOperationType()) {
|
||||
case DELETE:
|
||||
getIdToSubscription().remove(id.getIdPart());
|
||||
return;
|
||||
case CREATE:
|
||||
handleCreate(msg);
|
||||
break;
|
||||
case UPDATE:
|
||||
handleUpdate(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleUpdate(ResourceModifiedMessage theMsg) {
|
||||
if (!theMsg.getId().getResourceType().equals("Subscription")) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean subscriptionTypeApplies = subscriptionTypeApplies(theMsg);
|
||||
if (subscriptionTypeApplies == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
FhirContext ctx = getSubscriptionDao().getContext();
|
||||
IBaseResource subscription = theMsg.getNewPayload();
|
||||
IPrimitiveType<?> status = ctx.newTerser().getSingleValueOrNull(subscription, SUBSCRIPTION_STATUS, IPrimitiveType.class);
|
||||
String statusString = status.getValueAsString();
|
||||
|
||||
if (Subscription.SubscriptionStatus.ACTIVE.toCode().equals(statusString)) {
|
||||
getIdToSubscription().put(theMsg.getId().getIdPart(), theMsg.getNewPayload());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SubscriptionCheckingSubscriber extends BaseSubscriptionSubscriber {
|
||||
private Logger ourLog = LoggerFactory.getLogger(SubscriptionCheckingSubscriber.class);
|
||||
|
||||
public SubscriptionCheckingSubscriber(IFhirResourceDao theSubscriptionDao, ConcurrentHashMap<String, IBaseResource> theIdToSubscription, Subscription.SubscriptionChannelType theChannelType, SubscribableChannel theProcessingChannel) {
|
||||
super(theSubscriptionDao, theIdToSubscription, theChannelType, theProcessingChannel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> theMessage) throws MessagingException {
|
||||
if (!(theMessage.getPayload() instanceof ResourceModifiedMessage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceModifiedMessage msg = (ResourceModifiedMessage) theMessage.getPayload();
|
||||
switch (msg.getOperationType()) {
|
||||
case CREATE:
|
||||
case UPDATE:
|
||||
break;
|
||||
default:
|
||||
// ignore anything else
|
||||
return;
|
||||
}
|
||||
|
||||
String resourceType = msg.getId().getResourceType();
|
||||
String resourceId = msg.getId().getIdPart();
|
||||
|
||||
for (IBaseResource nextSubscription : getIdToSubscription().values()) {
|
||||
|
||||
String nextSubscriptionId = nextSubscription.getIdElement().toUnqualifiedVersionless().getValue();
|
||||
IPrimitiveType<?> nextCriteria = getContext().newTerser().getSingleValueOrNull(nextSubscription, "Subscription.criteria", IPrimitiveType.class);
|
||||
String nextCriteriaString = nextCriteria != null ? nextCriteria.getValueAsString() : null;
|
||||
|
||||
if (StringUtils.isBlank(nextCriteriaString)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if the criteria matches the created object
|
||||
ourLog.info("Checking subscription {} for {} with criteria {}", nextSubscriptionId, resourceType, nextCriteriaString);
|
||||
|
||||
String criteriaResource = nextCriteriaString;
|
||||
int index = criteriaResource.indexOf("?");
|
||||
if (index != -1) {
|
||||
criteriaResource = criteriaResource.substring(0, criteriaResource.indexOf("?"));
|
||||
}
|
||||
|
||||
if (resourceType != null && nextCriteriaString != null && !criteriaResource.equals(resourceType)) {
|
||||
ourLog.info("Skipping subscription search for {} because it does not match the criteria {}", resourceType, nextCriteriaString);
|
||||
continue;
|
||||
}
|
||||
|
||||
// run the subscriptions query and look for matches, add the id as part of the criteria to avoid getting matches of previous resources rather than the recent resource
|
||||
String criteria = nextCriteriaString;
|
||||
criteria += "&_id=" + resourceType + "/" + resourceId;
|
||||
criteria = massageCriteria(criteria);
|
||||
|
||||
IBundleProvider results = performSearch(criteria);
|
||||
if (results.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// should just be one resource as it was filtered by the id
|
||||
for (IBaseResource nextBase : results.getResources(0, results.size())) {
|
||||
IAnyResource next = (IAnyResource) nextBase;
|
||||
ourLog.info("Found match: queueing rest-hook notification for resource: {}", next.getIdElement());
|
||||
|
||||
ResourceDeliveryMessage deliveryMsg = new ResourceDeliveryMessage();
|
||||
deliveryMsg.setPayoad(next);
|
||||
deliveryMsg.setSubscription(nextSubscription);
|
||||
deliveryMsg.setOperationType(msg.getOperationType());
|
||||
|
||||
getProcessingChannel().send(new GenericMessage<>(deliveryMsg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override
|
||||
*/
|
||||
protected String massageCriteria(String theCriteria) {
|
||||
return theCriteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search based on a query criteria
|
||||
*/
|
||||
protected IBundleProvider performSearch(String theCriteria) {
|
||||
RuntimeResourceDefinition responseResourceDef = getSubscriptionDao().validateCriteriaAndReturnResourceDefinition(theCriteria);
|
||||
SearchParameterMap responseCriteriaUrl = BaseHapiFhirDao.translateMatchUrl(getSubscriptionDao(), getSubscriptionDao().getContext(), theCriteria, responseResourceDef);
|
||||
|
||||
RequestDetails req = new ServletSubRequestDetails();
|
||||
req.setSubRequest(true);
|
||||
|
||||
IFhirResourceDao<? extends IBaseResource> responseDao = getSubscriptionDao().getDao(responseResourceDef.getImplementingClass());
|
||||
responseCriteriaUrl.setLoadSynchronousUpTo(1);
|
||||
|
||||
IBundleProvider responseResults = responseDao.search(responseCriteriaUrl, req);
|
||||
return responseResults;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionSubscriber {
|
||||
|
||||
public SubscriptionDeliveringRestHookSubscriber(IFhirResourceDao theSubscriptionDao, ConcurrentHashMap<String, IBaseResource> theIdToSubscription, Subscription.SubscriptionChannelType theChannelType, SubscribableChannel theProcessingChannel) {
|
||||
super(theSubscriptionDao, theIdToSubscription, theChannelType, theProcessingChannel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> theMessage) throws MessagingException {
|
||||
if (!(theMessage.getPayload() instanceof ResourceDeliveryMessage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceDeliveryMessage msg = (ResourceDeliveryMessage) theMessage.getPayload();
|
||||
|
||||
if (!subscriptionTypeApplies(getContext(), msg.getSubscription())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -57,11 +57,8 @@ public class SubscriptionWebsocketHandlerR4 extends TextWebSocketHandler impleme
|
|||
private static IFhirResourceDaoSubscription<Subscription> ourSubscriptionDao;
|
||||
|
||||
private ScheduledFuture<?> myScheduleFuture;
|
||||
|
||||
private IState myState = new InitialState();
|
||||
|
||||
private IIdType mySubscriptionId;
|
||||
|
||||
private Long mySubscriptionPid;
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -116,7 +116,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
server.start();
|
||||
|
||||
ourClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
|
||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
ourClient.registerInterceptor(new LoggingInterceptor());
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
|
@ -160,4 +160,4 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.entity.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.*;
|
||||
|
@ -2059,12 +2060,12 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
Observation o = new Observation();
|
||||
o.getCode().setText("testSearchWithInvalidSort");
|
||||
myObservationDao.create(o, mySrd);
|
||||
ourClient
|
||||
.search()
|
||||
.forResource(Observation.class)
|
||||
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
|
||||
.prettyPrint()
|
||||
.execute();
|
||||
IBaseBundle bundle = ourClient
|
||||
.search()
|
||||
.forResource(Observation.class)
|
||||
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
|
||||
.prettyPrint()
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -151,7 +151,7 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {
|
|||
myFhirCtx.getRestfulClientFactory().setSocketTimeout(5000000);
|
||||
ourClient = myFhirCtx.newRestfulGenericClient(ourServerBase);
|
||||
if (shouldLogClient()) {
|
||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
ourClient.registerInterceptor(new LoggingInterceptor());
|
||||
}
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
|
@ -195,4 +195,4 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.provider.BaseResourceProviderDstu2Test;
|
||||
|
@ -38,6 +21,19 @@ import ca.uhn.fhir.rest.server.IResourceProvider;
|
|||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test the rest-hook subscriptions
|
||||
|
@ -51,12 +47,19 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
private static String ourListenerServerBase;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestDstu2Test.class);
|
||||
private static List<Observation> ourUpdatedObservations = Lists.newArrayList();
|
||||
private List<IIdType> mySubscriptionIds = new ArrayList<IIdType>();
|
||||
|
||||
@After
|
||||
public void afterUnregisterRestHookListener() {
|
||||
for (IIdType next : mySubscriptionIds){
|
||||
ourClient.delete().resourceById(next).execute();
|
||||
}
|
||||
mySubscriptionIds.clear();
|
||||
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
ourLog.info("Deleting all subscriptions");
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourClient.delete().resourceConditionalByUrl("Observation?code:missing=false").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
|
@ -77,7 +80,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
private Subscription createSubscription(String criteria, String payload, String endpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
|
||||
subscription.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
subscription.setStatus(SubscriptionStatusEnum.REQUESTED);
|
||||
subscription.setCriteria(criteria);
|
||||
|
||||
Channel channel = new Channel();
|
||||
|
@ -88,6 +91,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute();
|
||||
subscription.setId(methodOutcome.getId().getIdPart());
|
||||
mySubscriptionIds.add(methodOutcome.getId());
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
@ -136,9 +140,9 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/" + subscription2.getId())).execute();
|
||||
|
@ -147,7 +151,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -160,7 +164,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -174,7 +178,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
@ -222,9 +226,9 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(ourCreatedObservations.toString(), 2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription/" + subscription2.getId())).execute();
|
||||
|
@ -233,7 +237,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -246,7 +250,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -260,7 +264,7 @@ public class RestHookTestDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
|
|
@ -1,57 +1,63 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.subscription;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.provider.dstu3.BaseResourceProviderDstu3Test;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.provider.dstu3.BaseResourceProviderDstu3Test;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test the rest-hook subscriptions
|
||||
*/
|
||||
public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
||||
|
||||
private static List<String> ourContentTypes = new ArrayList<String>();
|
||||
private static List<Observation> ourCreatedObservations = Lists.newArrayList();
|
||||
private static int ourListenerPort;
|
||||
private static RestfulServer ourListenerRestServer;
|
||||
private static Server ourListenerServer;
|
||||
private static String ourListenerServerBase;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestDstu3Test.class);
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestDstu2Test.class);
|
||||
private static List<Observation> ourUpdatedObservations = Lists.newArrayList();
|
||||
private List<IIdType> mySubscriptionIds = new ArrayList<>();
|
||||
private static List<String> ourContentTypes = new ArrayList<>();
|
||||
|
||||
@After
|
||||
public void afterUnregisterRestHookListener() {
|
||||
for (IIdType next : mySubscriptionIds){
|
||||
ourClient.delete().resourceById(next).execute();
|
||||
}
|
||||
mySubscriptionIds.clear();
|
||||
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
ourLog.info("Deleting all subscriptions");
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourClient.delete().resourceConditionalByUrl("Observation?code:missing=false").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
|
||||
ourRestServer.unregisterInterceptor(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
|
@ -85,7 +91,7 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
private Subscription createSubscription(String theCriteria, String thePayload, String theEndpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
|
||||
subscription.setCriteria(theCriteria);
|
||||
|
||||
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
||||
|
@ -96,6 +102,7 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute();
|
||||
subscription.setId(methodOutcome.getId().getIdPart());
|
||||
mySubscriptionIds.add(methodOutcome.getId());
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
@ -163,21 +170,20 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
subscriptionTemp.setCriteria(criteria1);
|
||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||
|
||||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
||||
ourClient.delete().resourceById(new IdType("Subscription/" + subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -190,7 +196,7 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -204,7 +210,7 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
@ -232,7 +238,6 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationXml() throws Exception {
|
||||
String payload = "application/xml";
|
||||
|
@ -258,21 +263,20 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
subscriptionTemp.setCriteria(criteria1);
|
||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||
|
||||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(ourCreatedObservations.toString(), 2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
||||
ourClient.delete().resourceById(new IdType("Subscription/" + subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -285,7 +289,7 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -299,17 +303,17 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
Assert.assertFalse(observation1.getId().isEmpty());
|
||||
Assert.assertFalse(observation2.getId().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void startListenerServer() throws Exception {
|
||||
ourListenerPort = RandomServerPortProvider.findFreePort();
|
||||
ourListenerPort = PortUtil.findFreePort();
|
||||
ourListenerRestServer = new RestfulServer(FhirContext.forDstu3());
|
||||
ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context";
|
||||
|
||||
|
|
|
@ -1,57 +1,63 @@
|
|||
|
||||
package ca.uhn.fhir.jpa.subscription.r4;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.*;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.provider.r4.BaseResourceProviderR4Test;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.jpa.subscription.RestHookTestDstu2Test;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.junit.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Test the rest-hook subscriptions
|
||||
*/
|
||||
public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
||||
|
||||
private static List<String> ourContentTypes = new ArrayList<String>();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestDstu2Test.class);
|
||||
private static List<Observation> ourCreatedObservations = Lists.newArrayList();
|
||||
private static int ourListenerPort;
|
||||
private static RestfulServer ourListenerRestServer;
|
||||
private static Server ourListenerServer;
|
||||
private static String ourListenerServerBase;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestHookTestR4Test.class);
|
||||
|
||||
private static List<Observation> ourUpdatedObservations = Lists.newArrayList();
|
||||
private static List<String> ourContentTypes = new ArrayList<>();
|
||||
private List<IIdType> mySubscriptionIds = new ArrayList<>();
|
||||
|
||||
@After
|
||||
public void afterUnregisterRestHookListener() {
|
||||
for (IIdType next : mySubscriptionIds) {
|
||||
ourClient.delete().resourceById(next).execute();
|
||||
}
|
||||
mySubscriptionIds.clear();
|
||||
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
ourLog.info("Deleting all subscriptions");
|
||||
ourClient.delete().resourceConditionalByUrl("Subscription?status=active").execute();
|
||||
ourClient.delete().resourceConditionalByUrl("Observation?code:missing=false").execute();
|
||||
ourLog.info("Done deleting all subscriptions");
|
||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||
|
||||
|
||||
ourRestServer.unregisterInterceptor(ourRestHookSubscriptionInterceptor);
|
||||
}
|
||||
|
||||
|
@ -66,7 +72,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
ourUpdatedObservations.clear();
|
||||
ourContentTypes.clear();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionInvalidCriteria() throws Exception {
|
||||
String payload = "application/xml";
|
||||
|
@ -81,11 +87,10 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private Subscription createSubscription(String theCriteria, String thePayload, String theEndpoint) {
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.ACTIVE);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
|
||||
subscription.setCriteria(theCriteria);
|
||||
|
||||
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
||||
|
@ -96,6 +101,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute();
|
||||
subscription.setId(methodOutcome.getId().getIdPart());
|
||||
mySubscriptionIds.add(methodOutcome.getId());
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
@ -117,7 +123,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
return observation;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationFhirJson() throws Exception {
|
||||
String payload = "application/fhir+json";
|
||||
|
@ -137,7 +143,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
assertEquals(0, ourUpdatedObservations.size());
|
||||
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationJson() throws Exception {
|
||||
String payload = "application/json";
|
||||
|
@ -156,28 +162,27 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
assertEquals(1, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
assertEquals(Constants.CT_FHIR_JSON_NEW, ourContentTypes.get(0));
|
||||
|
||||
|
||||
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
|
||||
Assert.assertNotNull(subscriptionTemp);
|
||||
|
||||
subscriptionTemp.setCriteria(criteria1);
|
||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||
|
||||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
||||
ourClient.delete().resourceById(new IdType("Subscription/" + subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -190,7 +195,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -204,7 +209,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
|
@ -232,7 +237,6 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRestHookSubscriptionApplicationXml() throws Exception {
|
||||
String payload = "application/xml";
|
||||
|
@ -251,28 +255,27 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
assertEquals(1, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
assertEquals(Constants.CT_FHIR_XML_NEW, ourContentTypes.get(0));
|
||||
|
||||
|
||||
Subscription subscriptionTemp = ourClient.read(Subscription.class, subscription2.getId());
|
||||
Assert.assertNotNull(subscriptionTemp);
|
||||
|
||||
subscriptionTemp.setCriteria(criteria1);
|
||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||
|
||||
|
||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see two subscription notifications
|
||||
// Should see one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(ourCreatedObservations.toString(), 2, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
ourClient.delete().resourceById(new IdDt("Subscription", subscription2.getId())).execute();
|
||||
|
||||
ourClient.delete().resourceById(new IdType("Subscription/" + subscription2.getId())).execute();
|
||||
|
||||
Observation observationTemp3 = sendObservation(code, "SNOMED-CT");
|
||||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3 = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -285,7 +288,7 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
// Should see no subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(0, ourUpdatedObservations.size());
|
||||
|
||||
Observation observation3a = ourClient.read(Observation.class, observationTemp3.getId());
|
||||
|
@ -299,17 +302,17 @@ public class RestHookTestR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
// Should see only one subscription notification
|
||||
Thread.sleep(500);
|
||||
assertEquals(4, ourCreatedObservations.size());
|
||||
assertEquals(3, ourCreatedObservations.size());
|
||||
assertEquals(1, ourUpdatedObservations.size());
|
||||
|
||||
Assert.assertFalse(subscription1.getId().equals(subscription2.getId()));
|
||||
Assert.assertFalse(observation1.getId().isEmpty());
|
||||
Assert.assertFalse(observation2.getId().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void startListenerServer() throws Exception {
|
||||
ourListenerPort = RandomServerPortProvider.findFreePort();
|
||||
ourListenerPort = PortUtil.findFreePort();
|
||||
ourListenerRestServer = new RestfulServer(FhirContext.forR4());
|
||||
ourListenerServerBase = "http://localhost:" + ourListenerPort + "/fhir/context";
|
||||
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
package ca.uhn.fhir.jpa.z;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
|
||||
public class ResourceMinimizerMojo {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceMinimizerMojo.class);
|
||||
|
||||
private String fhirVersion;
|
||||
private long myByteCount;
|
||||
private FhirContext myCtx;
|
||||
private int myFileCount;
|
||||
private File targetDirectory;
|
||||
|
||||
public void execute() throws Exception {
|
||||
ourLog.info("Starting resource minimizer");
|
||||
|
||||
if (myCtx != null) {
|
||||
// nothing
|
||||
} else if ("DSTU2".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forDstu2();
|
||||
} else if ("HL7ORG_DSTU2".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forDstu2Hl7Org();
|
||||
} else if ("DSTU2_1".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forDstu2_1();
|
||||
} else if ("DSTU3".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forDstu3();
|
||||
} else if ("R4".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forR4();
|
||||
} else {
|
||||
throw new Exception("Unknown version: " + fhirVersion);
|
||||
}
|
||||
|
||||
ourLog.info("Looking for files in directory: {}", targetDirectory.getAbsolutePath());
|
||||
|
||||
Collection<File> files = FileUtils.listFiles(targetDirectory, new String[]{"xml", "json"}, true);
|
||||
for (File nextFile : files) {
|
||||
ourLog.debug("Checking file: {}", nextFile);
|
||||
|
||||
String inputString;
|
||||
try {
|
||||
inputString = IOUtils.toString(new FileInputStream(nextFile), "UTF-8");
|
||||
} catch (IOException e) {
|
||||
throw new Exception("Failed to read file: " + nextFile, e);
|
||||
}
|
||||
|
||||
IParser parser = EncodingEnum.detectEncoding(inputString).newParser(myCtx);
|
||||
IBaseResource input = parser.parseResource(inputString);
|
||||
|
||||
if (input instanceof IResource) {
|
||||
((IResource) input).getText().getDiv().setValueAsString((String) null);
|
||||
((IResource) input).getText().getStatus().setValueAsString((String) null);
|
||||
if (input instanceof Bundle) {
|
||||
for (Entry nextEntry : ((Bundle) input).getEntry()) {
|
||||
if (nextEntry.getResource() != null) {
|
||||
nextEntry.getResource().getText().getDiv().setValueAsString((String) null);
|
||||
nextEntry.getResource().getText().getStatus().setValueAsString((String) null);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
minimizeResource((IBaseResource) input);
|
||||
}
|
||||
|
||||
String outputString = parser.setPrettyPrint(true).encodeResourceToString(input);
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (String nextLine : outputString.split("\\n")) {
|
||||
int i;
|
||||
for (i = 0; i < nextLine.length(); i++) {
|
||||
if (nextLine.charAt(i) != ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
b.append(StringUtils.leftPad("", i / 3, ' '));
|
||||
b.append(nextLine.substring(i));
|
||||
b.append("\n");
|
||||
}
|
||||
outputString = b.toString();
|
||||
|
||||
if (!inputString.equals(outputString)) {
|
||||
ourLog.info("Trimming contents of resource: {} - From {} to {}", nextFile, FileUtils.byteCountToDisplaySize(inputString.length()), FileUtils.byteCountToDisplaySize(outputString.length()));
|
||||
myByteCount += (inputString.length() - outputString.length());
|
||||
myFileCount++;
|
||||
try {
|
||||
String f = nextFile.getAbsolutePath();
|
||||
Writer w = new OutputStreamWriter(new FileOutputStream(f, false), "UTF-8");
|
||||
w = new BufferedWriter(w);
|
||||
w.append(outputString);
|
||||
w.close();
|
||||
} catch (IOException e) {
|
||||
throw new Exception("Failed to write " + nextFile, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void minimizeResource(IBaseResource theInput) {
|
||||
if (theInput instanceof IBaseBundle) {
|
||||
for (IBaseResource next : BundleUtil.toListOfResources(myCtx, (IBaseBundle) theInput)) {
|
||||
minimizeResource(next);
|
||||
}
|
||||
}
|
||||
|
||||
BaseRuntimeElementCompositeDefinition<?> element = (BaseRuntimeElementCompositeDefinition) myCtx.getElementDefinition(theInput.getClass());
|
||||
BaseRuntimeChildDefinition textElement = element.getChildByName("text");
|
||||
if (textElement != null) {
|
||||
textElement.getMutator().setValue(theInput, null);
|
||||
}
|
||||
}
|
||||
|
||||
public long getByteCount() {
|
||||
return myByteCount;
|
||||
}
|
||||
|
||||
public int getFileCount() {
|
||||
return myFileCount;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
FhirContext ctxDstu2 = FhirContext.forDstu2();
|
||||
// FhirContext ctxDstu2_1 = FhirContext.forDstu2_1();
|
||||
FhirContext ctxDstu3 = FhirContext.forDstu3();
|
||||
FhirContext ctxR4 = FhirContext.forR4();
|
||||
|
||||
LoggerContext loggerContext = ((ch.qos.logback.classic.Logger) ourLog).getLoggerContext();
|
||||
URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(loggerContext);
|
||||
System.out.println(mainURL);
|
||||
// or even
|
||||
ourLog.info("Logback used '{}' as the configuration file.", mainURL);
|
||||
|
||||
int fileCount = 0;
|
||||
long byteCount = 0;
|
||||
|
||||
ResourceMinimizerMojo m = new ResourceMinimizerMojo();
|
||||
|
||||
m.myCtx = ctxDstu2;
|
||||
m.targetDirectory = new File("./hapi-tinder-plugin/src/main/resources/vs/dstu2");
|
||||
m.fhirVersion = "DSTU2";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2/src/main/resources/org/hl7/fhir/instance/model/valueset");
|
||||
m.fhirVersion = "DSTU2";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2/src/main/resources/org/hl7/fhir/instance/model/profile");
|
||||
m.fhirVersion = "DSTU2";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu3;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/profile");
|
||||
m.fhirVersion = "DSTU3";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu3;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/valueset");
|
||||
m.fhirVersion = "DSTU3";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu2_1;
|
||||
// m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2.1/src/main/resources/org/hl7/fhir/dstu2016may/model/profile");
|
||||
// m.fhirVersion = "DSTU2_1";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
//
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu2_1;
|
||||
// m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2.1/src/main/resources/org/hl7/fhir/dstu2016may/model/valueset");
|
||||
// m.fhirVersion = "DSTU2_1";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxR4;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile");
|
||||
m.fhirVersion = "R4";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxR4;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset");
|
||||
m.fhirVersion = "R4";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
ourLog.info("Trimmed {} files", fileCount);
|
||||
ourLog.info("Trimmed {} bytes", FileUtils.byteCountToDisplaySize(byteCount));
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,7 @@ import java.util.*;
|
|||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
|
@ -98,7 +99,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
|||
|
||||
retVal.setPublisher(myPublisher);
|
||||
retVal.setDate(conformanceDate());
|
||||
retVal.setFhirVersion("0.0.82-3059"); // TODO: pull from model
|
||||
retVal.setFhirVersion(FhirVersionEnum.DSTU1.getFhirVersionString());
|
||||
retVal.setAcceptUnknown(false); // TODO: make this configurable - this is a fairly big effort since the parser needs to be modified to actually allow it
|
||||
|
||||
retVal.getImplementation().setDescription(myServerConfiguration.getImplementationDescription());
|
||||
|
|
|
@ -84,7 +84,38 @@ public class IdDtTest {
|
|||
assertEquals("foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo1() {
|
||||
IdDt id = new IdDt("http://my.org/foo");
|
||||
assertEquals("http://my.org/foo", id.getValueAsString());
|
||||
assertEquals(null, id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("foo", id.getResourceType());
|
||||
assertEquals("http://my.org", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo2() {
|
||||
IdDt id = new IdDt("http://my.org/a/b/c/foo");
|
||||
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("c/foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("c", id.getResourceType());
|
||||
assertEquals("http://my.org/a/b", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectIsIdPartValid() {
|
||||
assertTrue(new IdDt("0").isIdPartValid());
|
||||
|
|
|
@ -358,11 +358,16 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
b.append(myResourceType);
|
||||
}
|
||||
|
||||
if (b.length() > 0) {
|
||||
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
if (isNotBlank(myUnqualifiedId)) {
|
||||
b.append(myUnqualifiedId);
|
||||
} else if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
b.append(myUnqualifiedId);
|
||||
if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
b.append("_history");
|
||||
|
@ -554,7 +559,21 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
if (typeIndex == -1) {
|
||||
myResourceType = theValue.substring(0, idIndex);
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
|
||||
typeIndex = theValue.indexOf('/', typeIndex + 1);
|
||||
}
|
||||
if (typeIndex >= idIndex) {
|
||||
// e.g. http://example.org/foo
|
||||
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
|
||||
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
|
||||
// recreate the url
|
||||
myResourceType = myUnqualifiedId;
|
||||
myUnqualifiedId = null;
|
||||
super.setValue(null);
|
||||
myHaveComponentParts = true;
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
}
|
||||
|
||||
if (typeIndex > 4) {
|
||||
myBaseUrl = theValue.substring(0, typeIndex);
|
||||
|
|
|
@ -92,6 +92,37 @@ public class IdTypeDstu2_1Test {
|
|||
assertEquals("foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo1() {
|
||||
IdType id = new IdType("http://my.org/foo");
|
||||
assertEquals("http://my.org/foo", id.getValueAsString());
|
||||
assertEquals(null, id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("foo", id.getResourceType());
|
||||
assertEquals("http://my.org", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo2() {
|
||||
IdType id = new IdType("http://my.org/a/b/c/foo");
|
||||
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("c/foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("c", id.getResourceType());
|
||||
assertEquals("http://my.org/a/b", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectLocal() {
|
||||
|
|
|
@ -1873,6 +1873,26 @@ public class JsonParserDstu2_1Test {
|
|||
Assert.assertThat(message, containsString("contained"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
|
||||
|
||||
IParser parser = ourCtx.newJsonParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@AfterClass
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.parser.FooMessageHeaderWithExplicitField.FooMessageSourceComponent;
|
||||
import ca.uhn.fhir.parser.IParserErrorHandler.IParseLocation;
|
||||
import ca.uhn.fhir.parser.PatientWithCustomCompositeExtension.FooParentExtension;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hamcrest.collection.IsEmptyCollection;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hamcrest.text.StringContainsInOrder;
|
||||
import org.hl7.fhir.dstu2016may.model.*;
|
||||
import org.hl7.fhir.dstu2016may.model.Address.AddressUse;
|
||||
import org.hl7.fhir.dstu2016may.model.*;
|
||||
import org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu2016may.model.Bundle.BundleType;
|
||||
import org.hl7.fhir.dstu2016may.model.ContactPoint.ContactPointSystem;
|
||||
|
@ -32,20 +33,20 @@ import org.junit.*;
|
|||
import org.mockito.ArgumentCaptor;
|
||||
import org.xmlunit.builder.DiffBuilder;
|
||||
import org.xmlunit.builder.Input;
|
||||
import org.xmlunit.diff.*;
|
||||
import org.xmlunit.diff.ComparisonControllers;
|
||||
import org.xmlunit.diff.DefaultNodeMatcher;
|
||||
import org.xmlunit.diff.Diff;
|
||||
import org.xmlunit.diff.ElementSelectors;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.parser.FooMessageHeaderWithExplicitField.FooMessageSourceComponent;
|
||||
import ca.uhn.fhir.parser.IParserErrorHandler.IParseLocation;
|
||||
import ca.uhn.fhir.parser.PatientWithCustomCompositeExtension.FooParentExtension;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class XmlParserDstu2_1Test {
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2_1();
|
||||
|
@ -2662,6 +2663,26 @@ public class XmlParserDstu2_1Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
|
||||
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Map.Entry;
|
|||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
|
@ -162,7 +163,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
|||
|
||||
retVal.setPublisher(myPublisher);
|
||||
retVal.setDate(conformanceDate());
|
||||
retVal.setFhirVersion("1.0.2"); // TODO: pull from model
|
||||
retVal.setFhirVersion(FhirVersionEnum.DSTU2.getFhirVersionString());
|
||||
retVal.setAcceptUnknown(UnknownContentCodeEnum.UNKNOWN_EXTENSIONS); // TODO: make this configurable - this is a fairly big effort since the parser
|
||||
// needs to be modified to actually allow it
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ public class BaseResourceReferenceDtTest {
|
|||
new ResourceReferenceDt("http://foo/123123").loadResource(client);
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
assertEquals("Unknown resource name \"foo\" (this name is not known in FHIR version \"DSTU2\")", e.getMessage());
|
||||
assertEquals("Unknown resource name \"123123\" (this name is not known in FHIR version \"DSTU2\")", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,121 +1,206 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by Sébastien Rivière 12/04/2017
|
||||
*/
|
||||
public class ElementWithExtensionDstu2Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu2Test.class);
|
||||
private static FhirContext ctx = FhirContext.forDstu2();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu2Test.class);
|
||||
private final FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExtensionOnPrimitiveExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
parser.setServerBaseUrl("http://foo");
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
@Test
|
||||
public void testExtensionOnPrimitiveExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final HumanNameDt name = patient.getNameFirstRep();
|
||||
name.addFamily(new StringDt("family"));
|
||||
name.getFamilyFirstRep().addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||
|
||||
ourLog.info(json);
|
||||
final StringDt stringExt = new StringDt();
|
||||
stringExt.setValue("myStringExt");
|
||||
stringExt.addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||
final ExtensionDt ext = new ExtensionDt();
|
||||
ext.setValue(stringExt);
|
||||
ext.setUrl("/myExt");
|
||||
patient.addUndeclaredExtension(ext);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnPrimitiveExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
parser.setServerBaseUrl("http://foo");
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
patient.setPetName(new StringDt("myPet"));
|
||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
|
||||
ourLog.info(xml);
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||
}
|
||||
ourLog.info(json);
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExtensionOnIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
parser.setServerBaseUrl("http://foo");
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getName().get(0).getFamilyFirstRep().getUndeclaredExtensions().size());
|
||||
assertEquals(1, ((StringDt) patient.getUndeclaredExtensionsByUrl("/myExt").get(0).getValue()).getUndeclaredExtensions().size());
|
||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
ourLog.info(json);
|
||||
@Test
|
||||
public void testExtensionOnPrimitiveExtensionWithNullValueJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getId().getUndeclaredExtensions().size());
|
||||
}
|
||||
ourLog.info(json);
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExtensionOnIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
parser.setServerBaseUrl("http://foo");
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getId().getUndeclaredExtensions().size());
|
||||
}
|
||||
@Test
|
||||
public void testExtensionOnPrimitiveExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExtensionOnIDDatatypeExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
parser.setServerBaseUrl("http://foo");
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
final HumanNameDt name = patient.getNameFirstRep();
|
||||
name.addFamily(new StringDt("family"));
|
||||
name.getFamilyFirstRep().addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||
|
||||
ourLog.info(json);
|
||||
final StringDt stringExt = new StringDt();
|
||||
stringExt.setValue("myStringExt");
|
||||
stringExt.addUndeclaredExtension(new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK")));
|
||||
final ExtensionDt ext = new ExtensionDt();
|
||||
ext.setValue(stringExt);
|
||||
ext.setUrl("/myExt");
|
||||
patient.addUndeclaredExtension(ext);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExtensionOnIDDatatypeExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
parser.setServerBaseUrl("http://foo");
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
patient.setPetName(new StringDt("myPet"));
|
||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||
}
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getName().get(0).getFamilyFirstRep().getUndeclaredExtensions().size());
|
||||
assertEquals(1, ((StringDt) patient.getUndeclaredExtensionsByUrl("/myExt").get(0).getValue()).getUndeclaredExtensions().size());
|
||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnPrimitiveExtensionWithNullValueXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getPetName().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getPetName().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getId().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testExtensionOnIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getId().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnIDDatatypeExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.setCustomId(new IdDt("3"));
|
||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnIDDatatypeExtensionNullValueJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnIDDatatypeExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.setCustomId(new IdDt("4"));
|
||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnIDDatatypeExtensionNullValueXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getCustomId().addUndeclaredExtension(false, "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringDt("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getCustomId().getUndeclaredExtensions().size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1948,4 +1948,24 @@ public class JsonParserDstu2Test {
|
|||
assertEquals("myName", ((StringDt) newPatient.getUndeclaredExtensionsByUrl("http://www.example.com/petname").get(0).getValue()).getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addUndeclaredExtension(false, "x1").setValue(new ResourceReferenceDt(refVal));
|
||||
|
||||
IParser parser = ourCtx.newJsonParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<ExtensionDt> extlst = fhirPat.getUndeclaredExtensionsByUrl("x1");
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((ResourceReferenceDt) extlst.get(0).getValue()).getReference().getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hamcrest.text.StringContainsInOrder;
|
|||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
@ -2790,6 +2791,26 @@ public class XmlParserDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addUndeclaredExtension(false, "x1").setValue(new ResourceReferenceDt(refVal));
|
||||
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<ExtensionDt> extlst = fhirPat.getUndeclaredExtensionsByUrl("x1");
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((ResourceReferenceDt) extlst.get(0).getValue()).getReference().getValue());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -68,7 +68,7 @@ public class ClientServerValidationDstu2Test {
|
|||
@Test
|
||||
public void testClientUsesInterceptors() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.5.0");
|
||||
conf.setFhirVersion("1.0.2");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -110,7 +110,7 @@ public class ClientServerValidationDstu2Test {
|
|||
@Test
|
||||
public void testForceConformanceCheck() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.5.0");
|
||||
conf.setFhirVersion("1.0.2");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -254,6 +254,44 @@ public class ClientServerValidationDstu2Test {
|
|||
verify(myHttpClient, times(4)).execute(Matchers.any(HttpUriRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsAppropriateVersionForDstu2() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("1.0.2");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
||||
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<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myFirstResponse) {
|
||||
myFirstResponse = false;
|
||||
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
||||
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||
|
||||
// don't load the conformance until the first time the client is actually used
|
||||
assertTrue(myFirstResponse);
|
||||
client.read(new UriDt("http://foo/Patient/123"));
|
||||
assertFalse(myFirstResponse);
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
|
||||
// Conformance only loaded once, then 3 reads
|
||||
verify(myHttpClient, times(4)).execute(Matchers.any(HttpUriRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsWrongVersionForDstu2() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
|
|
|
@ -351,11 +351,16 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
b.append(myResourceType);
|
||||
}
|
||||
|
||||
if (b.length() > 0) {
|
||||
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
if (isNotBlank(myUnqualifiedId)) {
|
||||
b.append(myUnqualifiedId);
|
||||
} else if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
b.append(myUnqualifiedId);
|
||||
if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
b.append("_history");
|
||||
|
@ -431,7 +436,7 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return isBlank(getValue());
|
||||
return super.isEmpty() && isBlank(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -547,7 +552,21 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
if (typeIndex == -1) {
|
||||
myResourceType = theValue.substring(0, idIndex);
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
|
||||
typeIndex = theValue.indexOf('/', typeIndex + 1);
|
||||
}
|
||||
if (typeIndex >= idIndex) {
|
||||
// e.g. http://example.org/foo
|
||||
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
|
||||
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
|
||||
// recreate the url
|
||||
myResourceType = myUnqualifiedId;
|
||||
myUnqualifiedId = null;
|
||||
super.setValue(null);
|
||||
myHaveComponentParts = true;
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
}
|
||||
|
||||
if (typeIndex > 4) {
|
||||
myBaseUrl = theValue.substring(0, typeIndex);
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu3.model.DomainResource;
|
||||
import org.hl7.fhir.dstu3.model.Narrative;
|
||||
import org.hl7.fhir.dstu3.model.Resource;
|
||||
import org.junit.AfterClass;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class MinimizeResources {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MinimizeResources.class);
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
|
||||
Collection<File> xml = FileUtils.listFiles(new File("../hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/profile"), new String[] {"xml"}, false);
|
||||
for (File next : xml) {
|
||||
ourLog.info("Checking: {}", next.getAbsoluteFile());
|
||||
|
||||
String inputFile = IOUtils.toString(new FileReader(next));
|
||||
Bundle bundle = (Bundle) ourCtx.newXmlParser().parseResource(inputFile);
|
||||
for (BundleEntryComponent nextEntry : bundle.getEntry()) {
|
||||
Resource resource;
|
||||
resource = nextEntry.getResource();
|
||||
if (resource instanceof DomainResource) {
|
||||
((DomainResource) resource).setText(new Narrative());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(bundle);
|
||||
if (!output.equals(inputFile)) {
|
||||
ourLog.info("Rewriting {}", next.getAbsolutePath());
|
||||
|
||||
FileWriter writer = new FileWriter(next, false);
|
||||
writer.append(output);
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -92,6 +92,38 @@ public class IdTypeDstu3Test {
|
|||
assertEquals("foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo1() {
|
||||
IdType id = new IdType("http://my.org/foo");
|
||||
assertEquals("http://my.org/foo", id.getValueAsString());
|
||||
assertEquals(null, id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("foo", id.getResourceType());
|
||||
assertEquals("http://my.org", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo2() {
|
||||
IdType id = new IdType("http://my.org/a/b/c/foo");
|
||||
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("c/foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("c", id.getResourceType());
|
||||
assertEquals("http://my.org/a/b", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectLocal() {
|
||||
IdType id;
|
||||
|
|
|
@ -1,116 +1,225 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Created by Sébastien Rivière 12/04/2017
|
||||
*/
|
||||
public class ElementWithExtensionDstu3Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu3Test.class);
|
||||
private static final FhirContext ctx = FhirContext.forDstu3();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ca.uhn.fhir.parser.ElementWithExtensionDstu3Test.class);
|
||||
private final FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNullFlavorPrimitiveExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final HumanName name = patient.getNameFirstRep();
|
||||
name.setFamily("family");
|
||||
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
ourLog.info(json);
|
||||
patient.setPetName(new StringType("myPet"));
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
final StringType stringExt = new StringType();
|
||||
stringExt.setValue("myStringExt");
|
||||
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final Extension ext = new Extension();
|
||||
ext.setValue(stringExt);
|
||||
ext.setUrl("/myExt");
|
||||
patient.addExtension(ext);
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNullFlavorPrimitiveExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNullFlavorIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionNullValueJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
ourLog.info(json);
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||
}
|
||||
ourLog.info(json);
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNullFlavorIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
ourLog.info(xml);
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final HumanName name = patient.getNameFirstRep();
|
||||
name.setFamily("family");
|
||||
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||
}
|
||||
patient.setPetName(new StringType("myPet"));
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNullFlavorExtensionIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
final StringType stringExt = new StringType();
|
||||
stringExt.setValue("myStringExt");
|
||||
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final Extension ext = new Extension();
|
||||
ext.setValue(stringExt);
|
||||
ext.setUrl("/myExt");
|
||||
patient.addExtension(ext);
|
||||
|
||||
ourLog.info(json);
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||
}
|
||||
ourLog.info(xml);
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNullFlavorExtensionIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||
}
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionNullValueXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNullFlavorIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorExtensionIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.setCustomId(new IdType(("4")));
|
||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ctx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorExtensionIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
patient.setCustomId(new IdType(("4")));
|
||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnResourceIdXml(){
|
||||
Patient p = new Patient();
|
||||
p.setActive(true);
|
||||
p.getIdElement().setValue("123");
|
||||
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||
|
||||
IParser parser = ctx.newXmlParser();
|
||||
String encoded = parser.encodeResourceToString(p);
|
||||
assertThat(encoded, containsString("http://foo"));
|
||||
assertThat(encoded, containsString("FOO"));
|
||||
|
||||
p = (Patient) parser.parseResource(encoded);
|
||||
assertEquals("Patient/123", p.getId());
|
||||
Extension ex = p.getIdElement().getExtension().get(0);
|
||||
assertEquals("http://foo", ex.getUrl());
|
||||
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnResourceIdJson(){
|
||||
Patient p = new Patient();
|
||||
p.setActive(true);
|
||||
p.getIdElement().setValue("123");
|
||||
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||
|
||||
IParser parser = ctx.newJsonParser();
|
||||
String encoded = parser.encodeResourceToString(p);
|
||||
assertThat(encoded, containsString("http://foo"));
|
||||
assertThat(encoded, containsString("FOO"));
|
||||
|
||||
p = (Patient) parser.parseResource(encoded);
|
||||
assertEquals("Patient/123", p.getId());
|
||||
Extension ex = p.getIdElement().getExtension().get(0);
|
||||
assertEquals("http://foo", ex.getUrl());
|
||||
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2414,6 +2414,26 @@ public class JsonParserDstu3Test {
|
|||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
|
||||
|
||||
IParser parser = ourCtx.newJsonParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -11,42 +11,42 @@ import org.hl7.fhir.dstu3.model.StringType;
|
|||
@ResourceDef()
|
||||
public class MyPatientWithCustomUrlExtension extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "petName")
|
||||
@Extension(url = "/petname", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The name of the patient's favourite pet")
|
||||
private StringType myPetName;
|
||||
@Child(name = "petName")
|
||||
@Extension(url = "/petname", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The name of the patient's favourite pet")
|
||||
private StringType myPetName;
|
||||
|
||||
@Child(name = "customid")
|
||||
@Extension(url = "/customid", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The customid of the patient's ")
|
||||
private IdType myCustomId;
|
||||
@Child(name = "customid")
|
||||
@Extension(url = "/customid", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The customid of the patient's ")
|
||||
private IdType myCustomId;
|
||||
|
||||
public StringType getPetName() {
|
||||
if (myPetName == null) {
|
||||
myPetName = new StringType();
|
||||
public StringType getPetName() {
|
||||
if (myPetName == null) {
|
||||
myPetName = new StringType();
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
public void setPetName(final StringType thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && myPetName.isEmpty();
|
||||
}
|
||||
|
||||
public IdType getCustomId() {
|
||||
if (myCustomId == null) {
|
||||
myCustomId = new IdType();
|
||||
public void setPetName(final StringType thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
return myCustomId;
|
||||
}
|
||||
|
||||
public void setCustomId(final IdType myCustomId) {
|
||||
this.myCustomId = myCustomId;
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && getCustomId().isEmpty() && getPetName().isEmpty();
|
||||
}
|
||||
|
||||
public IdType getCustomId() {
|
||||
if (myCustomId == null) {
|
||||
myCustomId = new IdType();
|
||||
}
|
||||
return myCustomId;
|
||||
}
|
||||
|
||||
public void setCustomId(final IdType myCustomId) {
|
||||
this.myCustomId = myCustomId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3334,6 +3334,26 @@ public class XmlParserDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
|
||||
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<Extension> extlst = fhirPat.getExtensionsByUrl("x1");
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.util.jar.Manifest;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.*;
|
||||
import org.hl7.fhir.instance.model.Conformance.*;
|
||||
|
@ -158,7 +159,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
|||
|
||||
retVal.setPublisher(myPublisher);
|
||||
retVal.setDate(conformanceDate());
|
||||
retVal.setFhirVersion("1.0.2"); // TODO: pull from model
|
||||
retVal.setFhirVersion(FhirVersionEnum.DSTU2_HL7ORG.getFhirVersionString());
|
||||
retVal.setAcceptUnknown(UnknownContentCode.EXTENSIONS); // TODO: make this configurable - this is a fairly big effort since the parser
|
||||
// needs to be modified to actually allow it
|
||||
|
||||
|
|
|
@ -380,11 +380,16 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
b.append(myResourceType);
|
||||
}
|
||||
|
||||
if (b.length() > 0) {
|
||||
if (b.length() > 0 && isNotBlank(myUnqualifiedId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
if (isNotBlank(myUnqualifiedId)) {
|
||||
b.append(myUnqualifiedId);
|
||||
} else if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
}
|
||||
|
||||
b.append(myUnqualifiedId);
|
||||
if (isNotBlank(myUnqualifiedVersionId)) {
|
||||
b.append('/');
|
||||
b.append("_history");
|
||||
|
@ -571,7 +576,21 @@ public final class IdType extends UriType implements IPrimitiveType<String>, IId
|
|||
if (typeIndex == -1) {
|
||||
myResourceType = theValue.substring(0, idIndex);
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
if (typeIndex > 0 && '/' == theValue.charAt(typeIndex - 1)) {
|
||||
typeIndex = theValue.indexOf('/', typeIndex + 1);
|
||||
}
|
||||
if (typeIndex >= idIndex) {
|
||||
// e.g. http://example.org/foo
|
||||
// 'foo' was the id but we're making that the resource type. Nullify the id part because we don't have an id.
|
||||
// Also set null value to the super.setValue() and enable myHaveComponentParts so it forces getValue() to properly
|
||||
// recreate the url
|
||||
myResourceType = myUnqualifiedId;
|
||||
myUnqualifiedId = null;
|
||||
super.setValue(null);
|
||||
myHaveComponentParts = true;
|
||||
} else {
|
||||
myResourceType = theValue.substring(typeIndex + 1, idIndex);
|
||||
}
|
||||
|
||||
if (typeIndex > 4) {
|
||||
myBaseUrl = theValue.substring(0, typeIndex);
|
||||
|
|
|
@ -83,7 +83,55 @@ public class IdTypeTest {
|
|||
assertEquals("Patient/cid:Patient-72/_history/1", id2.getIdPart());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNormal() {
|
||||
IdType id = new IdType("foo");
|
||||
assertEquals("foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals(null, id.getResourceType());
|
||||
assertEquals(null, id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo1() {
|
||||
IdType id = new IdType("http://my.org/foo");
|
||||
assertEquals("http://my.org/foo", id.getValueAsString());
|
||||
assertEquals(null, id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("foo", id.getResourceType());
|
||||
assertEquals("http://my.org", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo2() {
|
||||
IdType id = new IdType("http://my.org/a/b/c/foo");
|
||||
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("c/foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("c", id.getResourceType());
|
||||
assertEquals("http://my.org/a/b", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetermineBase() {
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import net.sf.json.JSON;
|
||||
import net.sf.json.JSONSerializer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hamcrest.core.IsNot;
|
||||
import org.hamcrest.core.StringContains;
|
||||
|
@ -22,19 +22,23 @@ import org.hl7.fhir.instance.model.Narrative.NarrativeStatus;
|
|||
import org.hl7.fhir.instance.model.Patient.ContactComponent;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ValueSetCodeSystemComponent;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.INarrative;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.junit.*;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import net.sf.json.JSON;
|
||||
import net.sf.json.JSONSerializer;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class JsonParserHl7OrgDstu2Test {
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2Hl7Org();
|
||||
|
@ -1274,6 +1278,26 @@ public class JsonParserHl7OrgDstu2Test {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
|
||||
|
||||
IParser parser = ourCtx.newJsonParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<Extension> extlst = fhirPat.getExtension();
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
|
||||
}
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public static class MyPatientWithOneDeclaredAddressExtension extends Patient {
|
||||
|
||||
|
|
|
@ -21,6 +21,24 @@ import org.hl7.fhir.instance.model.Identifier.IdentifierUse;
|
|||
import org.hl7.fhir.instance.model.Narrative.NarrativeStatus;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.junit.*;
|
||||
import org.hl7.fhir.instance.model.Observation;
|
||||
import org.hl7.fhir.instance.model.Organization;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.hl7.fhir.instance.model.PrimitiveType;
|
||||
import org.hl7.fhir.instance.model.Reference;
|
||||
import org.hl7.fhir.instance.model.Resource;
|
||||
import org.hl7.fhir.instance.model.SimpleQuantity;
|
||||
import org.hl7.fhir.instance.model.Specimen;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.INarrative;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xmlunit.builder.DiffBuilder;
|
||||
import org.xmlunit.builder.Input;
|
||||
|
@ -1738,6 +1756,26 @@ public class XmlParserHl7OrgDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
|
||||
String refVal = "http://my.org/FooBar";
|
||||
|
||||
Patient fhirPat = new Patient();
|
||||
fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
|
||||
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
|
||||
String output = parser.encodeResourceToString(fhirPat);
|
||||
System.out.println("output: " + output);
|
||||
|
||||
// Deserialize then check that valueReference value is still correct
|
||||
fhirPat = parser.parseResource(Patient.class, output);
|
||||
|
||||
List<Extension> extlst = fhirPat.getExtension();
|
||||
Assert.assertEquals(1, extlst.size());
|
||||
Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forDstu2Hl7Org();
|
||||
|
|
|
@ -57,46 +57,9 @@ public class ClientServerValidationTestHl7OrgDstu2 {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsAppropriateVersionForDstu2_040() throws Exception {
|
||||
public void testServerReturnsAppropriateVersionForDstu2() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.5.0");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
||||
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<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myFirstResponse) {
|
||||
myFirstResponse=false;
|
||||
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
||||
}
|
||||
}});
|
||||
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||
|
||||
// don't load the conformance until the first time the client is actually used
|
||||
assertTrue(myFirstResponse);
|
||||
client.read(new UriDt("http://foo/Patient/123"));
|
||||
assertFalse(myFirstResponse);
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||
|
||||
// Conformance only loaded once, then 3 reads
|
||||
verify(myHttpClient, times(4)).execute(Matchers.any(HttpUriRequest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerReturnsAppropriateVersionForDstu2_050() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.5.0");
|
||||
conf.setFhirVersion("1.0.2");
|
||||
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -133,7 +96,7 @@ public class ClientServerValidationTestHl7OrgDstu2 {
|
|||
@Test
|
||||
public void testServerReturnsWrongVersionForDstu2() throws Exception {
|
||||
Conformance conf = new Conformance();
|
||||
conf.setFhirVersion("0.80");
|
||||
conf.setFhirVersion("0.0.82");
|
||||
String msg = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -150,7 +113,7 @@ public class ClientServerValidationTestHl7OrgDstu2 {
|
|||
fail();
|
||||
} catch (FhirClientInappropriateForServerException e) {
|
||||
String out = e.toString();
|
||||
String want = "The server at base URL \"http://foo/metadata\" returned a conformance statement indicating that it supports FHIR version \"0.80\" which corresponds to DSTU1, but this client is configured to use DSTU2_HL7ORG (via the FhirContext)";
|
||||
String want = "The server at base URL \"http://foo/metadata\" returned a conformance statement indicating that it supports FHIR version \"0.0.82\" which corresponds to DSTU1, but this client is configured to use DSTU2_HL7ORG (via the FhirContext)";
|
||||
ourLog.info(out);
|
||||
ourLog.info(want);
|
||||
assertThat(out, containsString(want));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,138 +0,0 @@
|
|||
package org.hl7.fhir.r4.model.api;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 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%
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base interface for ID datatype.
|
||||
*
|
||||
* <p>
|
||||
* <b>Concrete Implementations:</b> This interface is often returned and/or accepted by methods in HAPI's API
|
||||
* where either {@link ca.uhn.fhir.model.primitive.IdDt} (the HAPI structure ID type) or
|
||||
* <code>org.hl7.fhir.instance.model.IdType</code> (the RI structure ID type) will be used, depending on
|
||||
* which version of the strctures your application is using.
|
||||
* </p>
|
||||
*/
|
||||
public interface IIdType {
|
||||
|
||||
void applyTo(IBaseResource theResource);
|
||||
|
||||
/**
|
||||
* Returns the server base URL if this ID contains one. For example, the base URL is
|
||||
* the 'http://example.com/fhir' in the following ID: <code>http://example.com/fhir/Patient/123/_history/55</code>
|
||||
*/
|
||||
String getBaseUrl();
|
||||
|
||||
/**
|
||||
* Returns only the logical ID part of this ID. For example, given the ID
|
||||
* "http://example,.com/fhir/Patient/123/_history/456", this method would
|
||||
* return "123".
|
||||
*/
|
||||
String getIdPart();
|
||||
|
||||
/**
|
||||
* Returns the ID part of this ID (e.g. in the ID http://example.com/Patient/123/_history/456 this would be the
|
||||
* part "123") parsed as a {@link Long}.
|
||||
*
|
||||
* @throws NumberFormatException If the value can't be parsed as a long
|
||||
*/
|
||||
Long getIdPartAsLong();
|
||||
|
||||
String getResourceType();
|
||||
|
||||
/**
|
||||
* Returns the value of this ID. Note that this value may be a fully qualified URL, a relative/partial URL, or a simple ID. Use {@link #getIdPart()} to get just the ID portion.
|
||||
*
|
||||
* @see #getIdPart()
|
||||
*/
|
||||
String getValue();
|
||||
|
||||
String getVersionIdPart();
|
||||
|
||||
/**
|
||||
* Returns the version ID part of this ID (e.g. in the ID http://example.com/Patient/123/_history/456 this would be the
|
||||
* part "456") parsed as a {@link Long}.
|
||||
*
|
||||
* @throws NumberFormatException If the value can't be parsed as a long
|
||||
*/
|
||||
Long getVersionIdPartAsLong();
|
||||
|
||||
boolean hasBaseUrl();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this ID contains an actual ID part. For example, the ID part is
|
||||
* the '123' in the following ID: <code>http://example.com/fhir/Patient/123/_history/55</code>
|
||||
*/
|
||||
boolean hasIdPart();
|
||||
|
||||
boolean hasResourceType();
|
||||
|
||||
boolean hasVersionIdPart();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this ID contains an absolute URL (in other words, a URL starting with "http://" or "https://"
|
||||
*/
|
||||
boolean isAbsolute();
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the {@link #getIdPart() ID part of this object} is valid according to the FHIR rules for valid IDs.
|
||||
* <p>
|
||||
* The FHIR specification states:
|
||||
* <code>Any combination of upper or lower case ASCII letters ('A'..'Z', and 'a'..'z', numerals ('0'..'9'), '-' and '.', with a length limit of 64 characters. (This might be an integer, an un-prefixed OID, UUID or any other identifier pattern that meets these constraints.) regex: [A-Za-z0-9\-\.]{1,64}</code>
|
||||
* </p>
|
||||
*/
|
||||
boolean isIdPartValid();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the {@link #getIdPart() ID part of this object} contains
|
||||
* only numbers
|
||||
*/
|
||||
boolean isIdPartValidLong();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the ID is a local reference (in other words, it begins with the '#' character)
|
||||
*/
|
||||
boolean isLocal();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the {@link #getVersionIdPart() version ID part of this object} contains
|
||||
* only numbers
|
||||
*/
|
||||
boolean isVersionIdPartValidLong();
|
||||
|
||||
IIdType setValue(String theString);
|
||||
|
||||
IIdType toUnqualified();
|
||||
|
||||
IIdType toUnqualifiedVersionless();
|
||||
|
||||
IIdType toVersionless();
|
||||
|
||||
IIdType withResourceType(String theResName);
|
||||
|
||||
IIdType withServerBase(String theServerBase, String theResourceName);
|
||||
|
||||
IIdType withVersion(String theVersion);
|
||||
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Created by Sébastien Rivière 12/04/2017
|
||||
*/
|
||||
public class ElementWithExtensionR4Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ElementWithExtensionR4Test.class);
|
||||
private static FhirContext ourCtx = FhirContext.forR4();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final HumanName name = patient.getNameFirstRep();
|
||||
name.setFamily("family");
|
||||
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
patient.setPetName(new StringType("myPet"));
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final StringType stringExt = new StringType();
|
||||
stringExt.setValue("myStringExt");
|
||||
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final Extension ext = new Extension();
|
||||
ext.setValue(stringExt);
|
||||
ext.setUrl("/myExt");
|
||||
patient.addExtension(ext);
|
||||
|
||||
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionNullValueJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final HumanName name = patient.getNameFirstRep();
|
||||
name.setFamily("family");
|
||||
name.getFamilyElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
patient.setPetName(new StringType("myPet"));
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final StringType stringExt = new StringType();
|
||||
stringExt.setValue("myStringExt");
|
||||
stringExt.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final Extension ext = new Extension();
|
||||
ext.setValue(stringExt);
|
||||
ext.setUrl("/myExt");
|
||||
patient.addExtension(ext);
|
||||
|
||||
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getName().get(0).getFamilyElement().getExtension().size());
|
||||
assertEquals(1, patient.getExtensionsByUrl("/myExt").get(0).getValue().getExtension().size());
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNullFlavorPrimitiveExtensionNullValueXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
|
||||
patient.getExtensionsByUrl("/petname");
|
||||
patient.getPetName().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getPetName().getExtension().size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNullFlavorIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.getIdElement().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getIdElement().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorExtensionIDDatatypeJson() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
patient.setCustomId(new IdType(("4")));
|
||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
final IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
final String json = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(json);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, json);
|
||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullFlavorExtensionIDDatatypeXml() throws Exception {
|
||||
MyPatientWithCustomUrlExtension patient = new MyPatientWithCustomUrlExtension();
|
||||
patient.setId("1");
|
||||
final IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
patient.setCustomId(new IdType(("4")));
|
||||
patient.getCustomId().addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor", new StringType("UNK"));
|
||||
|
||||
final String xml = parser.encodeResourceToString(patient);
|
||||
|
||||
ourLog.info(xml);
|
||||
|
||||
patient = parser.parseResource(MyPatientWithCustomUrlExtension.class, xml);
|
||||
assertEquals(1, patient.getCustomId().getExtension().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnResourceIdXml(){
|
||||
Patient p = new Patient();
|
||||
p.setActive(true);
|
||||
p.getIdElement().setValue("123");
|
||||
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
String encoded = parser.encodeResourceToString(p);
|
||||
assertThat(encoded, containsString("http://foo"));
|
||||
assertThat(encoded, containsString("FOO"));
|
||||
|
||||
p = (Patient) parser.parseResource(encoded);
|
||||
assertEquals("Patient/123", p.getId());
|
||||
Extension ex = p.getIdElement().getExtension().get(0);
|
||||
assertEquals("http://foo", ex.getUrl());
|
||||
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensionOnResourceIdJson(){
|
||||
Patient p = new Patient();
|
||||
p.setActive(true);
|
||||
p.getIdElement().setValue("123");
|
||||
p.getIdElement().addExtension().setUrl("http://foo").setValue(new StringType("FOO"));
|
||||
|
||||
IParser parser = ourCtx.newJsonParser();
|
||||
String encoded = parser.encodeResourceToString(p);
|
||||
assertThat(encoded, containsString("http://foo"));
|
||||
assertThat(encoded, containsString("FOO"));
|
||||
|
||||
p = (Patient) parser.parseResource(encoded);
|
||||
assertEquals("Patient/123", p.getId());
|
||||
Extension ex = p.getIdElement().getExtension().get(0);
|
||||
assertEquals("http://foo", ex.getUrl());
|
||||
assertEquals("FOO", ex.getValueAsPrimitive().getValueAsString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
|
||||
@ResourceDef()
|
||||
public class MyPatientWithCustomUrlExtension extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "petName")
|
||||
@Extension(url = "/petname", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The name of the patient's favourite pet")
|
||||
private StringType myPetName;
|
||||
|
||||
@Child(name = "customid")
|
||||
@Extension(url = "/customid", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The customid of the patient's ")
|
||||
private IdType myCustomId;
|
||||
|
||||
public StringType getPetName() {
|
||||
if (myPetName == null) {
|
||||
myPetName = new StringType();
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
public void setPetName(final StringType thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && getCustomId().isEmpty() && getPetName().isEmpty();
|
||||
}
|
||||
|
||||
public IdType getCustomId() {
|
||||
if (myCustomId == null) {
|
||||
myCustomId = new IdType();
|
||||
}
|
||||
return myCustomId;
|
||||
}
|
||||
|
||||
public void setCustomId(final IdType myCustomId) {
|
||||
this.myCustomId = myCustomId;
|
||||
}
|
||||
}
|
|
@ -243,7 +243,7 @@ public class ClientR4Test {
|
|||
CapabilityStatement cs = new CapabilityStatement();
|
||||
cs.getPublisherElement().setValue("Health Intersections");
|
||||
String msg = ourCtx.newXmlParser().encodeResourceToString(cs);
|
||||
|
||||
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
@ -389,11 +389,11 @@ public class ClientR4Test {
|
|||
String msg = getPatient();
|
||||
|
||||
ourLog.info(msg);
|
||||
|
||||
|
||||
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"));
|
||||
Header[] headers = new Header[] {
|
||||
Header[] headers = new Header[] {
|
||||
new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"),
|
||||
new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333")
|
||||
};
|
||||
|
@ -1138,7 +1138,7 @@ public class ClientR4Test {
|
|||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().setDiagnostics("ALL GOOD");
|
||||
String resp = ourCtx.newJsonParser().encodeResourceToString(oo);
|
||||
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:foo").setValue("123");
|
||||
|
||||
|
@ -1161,12 +1161,12 @@ public class ClientR4Test {
|
|||
assertNull(response.getResource());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testVRead() throws Exception {
|
||||
|
||||
//@formatter:off
|
||||
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
+ "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
|
||||
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
|
||||
|
@ -1216,7 +1216,7 @@ public class ClientR4Test {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
private static String getPatientFeedWithOneResult() {
|
||||
static String getPatientFeedWithOneResult() {
|
||||
return getPatientFeedWithOneResult(ourCtx);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ public class ClientServerValidationDstu1Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testServerReturnsWrongVersionDstu() throws Exception {
|
||||
CapabilityStatement conf = new CapabilityStatement();
|
||||
conf.setFhirVersion("0.4.0");
|
||||
|
|
|
@ -108,7 +108,31 @@ public class GenericClientR4Test {
|
|||
return capt;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testSearchWithNoExplicitBundleReturnType() throws Exception {
|
||||
|
||||
String msg = ClientR4Test.getPatientFeedWithOneResult();
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
||||
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()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
// httpResponse = new BasicHttpResponse(statusline, catalog, locale)
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://foo");
|
||||
Bundle response = (Bundle) client.search().forResource(Patient.class).execute();
|
||||
|
||||
assertEquals("http://foo/Patient", capt.getValue().getURI().toString());
|
||||
Patient patient = (Patient) response.getEntry().get(0).getResource();
|
||||
assertEquals("PRP1660", patient.getIdentifier().get(0).getValueElement().getValue());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderWithEncodingSpecified() throws Exception {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
|
|
|
@ -0,0 +1,336 @@
|
|||
package org.hl7.fhir.r4.model;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class IdTypeR4Test {
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IdTypeR4Test.class);
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo1() {
|
||||
IdType id = new IdType("http://my.org/foo");
|
||||
assertEquals("http://my.org/foo", id.getValueAsString());
|
||||
assertEquals(null, id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("foo", id.getResourceType());
|
||||
assertEquals("http://my.org", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/foo//_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaseUrlFoo2() {
|
||||
IdType id = new IdType("http://my.org/a/b/c/foo");
|
||||
assertEquals("http://my.org/a/b/c/foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("c/foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("c/foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals("c", id.getResourceType());
|
||||
assertEquals("http://my.org/a/b", id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("http://my.org/a/b/c/foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUuid() {
|
||||
IdType id = new IdType("urn:uuid:1234-5678");
|
||||
assertEquals("urn:uuid:1234-5678", id.getValueAsString());
|
||||
assertEquals("urn:uuid:1234-5678", id.getIdPart());
|
||||
assertEquals("urn:uuid:1234-5678", id.toUnqualified().getValueAsString());
|
||||
assertEquals("urn:uuid:1234-5678", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals(null, id.getResourceType());
|
||||
assertEquals(null, id.getBaseUrl());
|
||||
|
||||
assertEquals("urn:uuid:1234-5678", id.withResourceType("Patient").getValue());
|
||||
assertEquals("urn:uuid:1234-5678", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("urn:uuid:1234-5678", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOid() {
|
||||
IdType id = new IdType("urn:oid:1.2.3.4");
|
||||
assertEquals("urn:oid:1.2.3.4", id.getValueAsString());
|
||||
assertEquals("urn:oid:1.2.3.4", id.getIdPart());
|
||||
assertEquals("urn:oid:1.2.3.4", id.toUnqualified().getValueAsString());
|
||||
assertEquals("urn:oid:1.2.3.4", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals(null, id.getResourceType());
|
||||
assertEquals(null, id.getBaseUrl());
|
||||
|
||||
assertEquals("urn:oid:1.2.3.4", id.withResourceType("Patient").getValue());
|
||||
assertEquals("urn:oid:1.2.3.4", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("urn:oid:1.2.3.4", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocal() {
|
||||
IdType id = new IdType("#foo");
|
||||
assertEquals("#foo", id.getValueAsString());
|
||||
assertEquals("#foo", id.getIdPart());
|
||||
assertEquals("#foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("#foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals(null, id.getResourceType());
|
||||
assertEquals(null, id.getBaseUrl());
|
||||
|
||||
assertEquals("#foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("#foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("#foo", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormal() {
|
||||
IdType id = new IdType("foo");
|
||||
assertEquals("foo", id.getValueAsString());
|
||||
assertEquals("foo", id.getIdPart());
|
||||
assertEquals("foo", id.toUnqualified().getValueAsString());
|
||||
assertEquals("foo", id.toUnqualifiedVersionless().getValueAsString());
|
||||
assertEquals(null, id.getVersionIdPart());
|
||||
assertEquals(null, id.getResourceType());
|
||||
assertEquals(null, id.getBaseUrl());
|
||||
|
||||
assertEquals("Patient/foo", id.withResourceType("Patient").getValue());
|
||||
assertEquals("http://foo/Patient/foo", id.withServerBase("http://foo", "Patient").getValue());
|
||||
assertEquals("foo/_history/2", id.withVersion("2").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectLocal() {
|
||||
IdType id;
|
||||
|
||||
id = new IdType("#123");
|
||||
assertEquals("#123", id.getValue());
|
||||
assertTrue(id.isLocal());
|
||||
|
||||
id = new IdType("#Medication/499059CE-CDD4-48BC-9014-528A35D15CED/_history/1");
|
||||
assertEquals("#Medication/499059CE-CDD4-48BC-9014-528A35D15CED/_history/1", id.getValue());
|
||||
assertTrue(id.isLocal());
|
||||
|
||||
id = new IdType("http://example.com/Patient/33#123");
|
||||
assertEquals("http://example.com/Patient/33#123", id.getValue());
|
||||
assertFalse(id.isLocal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorsWithNullArguments() {
|
||||
IdType id = new IdType(null, null, null);
|
||||
assertEquals(null, id.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectLocalBase() {
|
||||
assertEquals("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57", new IdType("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57").getValue());
|
||||
assertEquals(null, new IdType("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57").getBaseUrl());
|
||||
assertEquals("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57", new IdType("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57").getIdPart());
|
||||
|
||||
assertEquals("cid:180f219f-97a8-486d-99d9-ed631fe4fc57", new IdType("cid:180f219f-97a8-486d-99d9-ed631fe4fc57").getValue());
|
||||
assertEquals(null, new IdType("cid:180f219f-97a8-486d-99d9-ed631fe4fc57").getBaseUrl());
|
||||
assertEquals("cid:180f219f-97a8-486d-99d9-ed631fe4fc57", new IdType("cid:180f219f-97a8-486d-99d9-ed631fe4fc57").getIdPart());
|
||||
|
||||
assertEquals("#180f219f-97a8-486d-99d9-ed631fe4fc57", new IdType("#180f219f-97a8-486d-99d9-ed631fe4fc57").getValue());
|
||||
assertEquals(null, new IdType("#180f219f-97a8-486d-99d9-ed631fe4fc57").getBaseUrl());
|
||||
assertEquals("#180f219f-97a8-486d-99d9-ed631fe4fc57", new IdType("#180f219f-97a8-486d-99d9-ed631fe4fc57").getIdPart());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #67
|
||||
*/
|
||||
@Test
|
||||
public void testComplicatedLocal() {
|
||||
IdType id = new IdType("#Patient/cid:Patient-72/_history/1");
|
||||
assertTrue(id.isLocal());
|
||||
assertEquals(null, id.getBaseUrl());
|
||||
assertNull(id.getResourceType());
|
||||
assertNull(id.getVersionIdPart());
|
||||
assertEquals("#Patient/cid:Patient-72/_history/1", id.getIdPart());
|
||||
|
||||
IdType id2 = new IdType("#Patient/cid:Patient-72/_history/1");
|
||||
assertEquals(id, id2);
|
||||
|
||||
id2 = id2.toUnqualified();
|
||||
assertTrue(id2.isLocal());
|
||||
assertNull(id2.getBaseUrl());
|
||||
assertNull(id2.getResourceType());
|
||||
assertNull(id2.getVersionIdPart());
|
||||
assertEquals("#Patient/cid:Patient-72/_history/1", id2.getIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetermineBase() {
|
||||
|
||||
IdType rr;
|
||||
|
||||
rr = new IdType("http://foo/fhir/Organization/123");
|
||||
assertEquals("http://foo/fhir", rr.getBaseUrl());
|
||||
|
||||
rr = new IdType("http://foo/fhir/Organization/123/_history/123");
|
||||
assertEquals("http://foo/fhir", rr.getBaseUrl());
|
||||
|
||||
rr = new IdType("Organization/123/_history/123");
|
||||
assertEquals(null, rr.getBaseUrl());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueAbsolute() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("http://foo/fhir/Organization/123");
|
||||
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals("Organization", ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigDecimalIds() {
|
||||
|
||||
IdType id = new IdType(new BigDecimal("123"));
|
||||
assertEquals(id.getIdPartAsBigDecimal(), new BigDecimal("123"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueAbsoluteWithVersion() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("http://foo/fhir/Organization/123/_history/999");
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals("Organization", ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
assertEquals(null, ref.getReferenceElement().getVersionIdPart());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testViewMethods() {
|
||||
IdType i = new IdType("http://foo/fhir/Organization/123/_history/999");
|
||||
assertEquals("Organization/123/_history/999", i.toUnqualified().getValue());
|
||||
assertEquals("http://foo/fhir/Organization/123", i.toVersionless().getValue());
|
||||
assertEquals("Organization/123", i.toUnqualifiedVersionless().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueWithVersion() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("/123/_history/999");
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals(null, ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
assertEquals(null, ref.getReferenceElement().getVersionIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueMissingType1() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("/123");
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals(null, ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueMissingType2() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("123");
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals(null, ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueRelative1() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("Organization/123");
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals("Organization", ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeParts() {
|
||||
IdType id = new IdType("http://foo", "Patient", "123", "456");
|
||||
assertEquals("http://foo/Patient/123/_history/456", id.getValue());
|
||||
assertEquals("http://foo/Patient/123/_history/9", id.withVersion("9").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseValueRelative2() {
|
||||
Patient patient = new Patient();
|
||||
IdType rr = new IdType();
|
||||
rr.setValue("/Organization/123");
|
||||
patient.setManagingOrganization(new Reference(rr));
|
||||
|
||||
Patient actual = parseAndEncode(patient);
|
||||
Reference ref = actual.getManagingOrganization();
|
||||
assertEquals("Organization", ref.getReferenceElement().getResourceType());
|
||||
assertEquals("123", ref.getReferenceElement().getIdPart());
|
||||
|
||||
}
|
||||
|
||||
private Patient parseAndEncode(Patient patient) {
|
||||
String encoded = ourCtx.newXmlParser().encodeResourceToString(patient);
|
||||
ourLog.info("\n" + encoded);
|
||||
return ourCtx.newXmlParser().parseResource(Patient.class, encoded);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = FhirContext.forR4();
|
||||
}
|
||||
|
||||
}
|
|
@ -70,14 +70,88 @@ function addSearchControls(theConformance, theSearchParamType, theSearchParamNam
|
|||
)
|
||||
);
|
||||
} else if (theSearchParamType == 'token') {
|
||||
|
||||
var tokenQualifiers = new Array();
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[0].name='Matches';
|
||||
tokenQualifiers[0].value='';
|
||||
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[1].name='Text';
|
||||
tokenQualifiers[1].value=':text';
|
||||
tokenQualifiers[1].description='The search parameter is processed as a string that searches text associated with the code/value.';
|
||||
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[2].name='Not';
|
||||
tokenQualifiers[2].value=':not';
|
||||
tokenQualifiers[2].description='Reverse the code matching described in the paragraph above. Note that this includes resources that have no value for the parameter.';
|
||||
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[3].name='Above';
|
||||
tokenQualifiers[3].value=':above';
|
||||
tokenQualifiers[3].description='The search parameter is a concept with the form [system]|[code], and the search parameter tests whether the coding in a resource subsumes the specified search code. For example, the search concept has an is-a relationship with the coding in the resource, and this includes the coding itself.';
|
||||
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[4].name='Below';
|
||||
tokenQualifiers[4].value=':below';
|
||||
tokenQualifiers[4].description='The search parameter is a concept with the form [system]|[code], and the search parameter tests whether the coding in a resource is subsumed by the specified search code. For example, the coding in the resource has an is-a relationship with the search concept, and this includes the coding itself.';
|
||||
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[5].name='In';
|
||||
tokenQualifiers[5].value=':in';
|
||||
tokenQualifiers[5].description='The search parameter is a URI (relative or absolute) that identifies a value set, and the search parameter tests whether the coding is in the specified value set. The reference may be literal (to an address where the value set can be found) or logical (a reference to ValueSet.url). If the server can treat the reference as a literal URL, it does, else it tries to match known logical ValueSet.url values.';
|
||||
|
||||
tokenQualifiers.push(new Object());
|
||||
tokenQualifiers[6].name='Not-in';
|
||||
tokenQualifiers[6].value=':not-in';
|
||||
tokenQualifiers[6].description='The search parameter is a URI (relative or absolute) that identifies a value set, and the search parameter tests whether the coding is not in the specified value set.';
|
||||
|
||||
|
||||
var tokenQualifierInput = $('<input />', { id: 'param.' + theRowNum + '.qualifier', type: 'hidden' });
|
||||
$('#search-param-rowopts-' + theContainerRowNum).append(
|
||||
$('<div />', { 'class': 'col-sm-3' }).append(
|
||||
$('<input />', { id: 'param.' + theRowNum + '.0', placeholder: 'system/namespace', type: 'text', 'class': 'form-control' })
|
||||
),
|
||||
$('<div />', { 'class': 'col-sm-3' }).append(
|
||||
$('<input />', { id: 'param.' + theRowNum + '.1', placeholder: 'value', type: 'text', 'class': 'form-control' })
|
||||
tokenQualifierInput
|
||||
);
|
||||
|
||||
function clickTokenFunction(value, name){
|
||||
return function(){
|
||||
tokenQualifierInput.val(value);
|
||||
tokenQualifierLabel.text(name);
|
||||
}
|
||||
};
|
||||
var tokenQualifierLabel = $('<span>' + tokenQualifiers[0].name + '</span>');
|
||||
var tokenQualifierDropdown = $('<ul />', {'class':'dropdown-menu', role:'menu'});
|
||||
for (var i = 0; i < tokenQualifiers.length; i++) {
|
||||
var qualName = tokenQualifiers[i].name;
|
||||
var nextValue = tokenQualifiers[i].value;
|
||||
var nextLink = $('<a>' + tokenQualifiers[i].name+'</a>');
|
||||
tokenQualifierDropdown.append($('<li />').append(nextLink));
|
||||
nextLink.click(clickTokenFunction(nextValue, qualName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
$('#search-param-rowopts-' + theContainerRowNum).append(
|
||||
$('<div />', { 'class': 'col-sm-6' }).append(
|
||||
$('<div />', { 'class':'input-group'}).append(
|
||||
$('<div />', {'class':'input-group-btn'}).append(
|
||||
$('<button />', {'class':'btn btn-default dropdown-toggle', 'data-toggle':'dropdown'}).append(
|
||||
tokenQualifierLabel,
|
||||
$('<span class="caret" style="margin-left: 5px;"></span>')
|
||||
),
|
||||
tokenQualifierDropdown
|
||||
),
|
||||
$('<div />', { 'class':'input-group-addon', 'style':'padding:6px;'} ).append(
|
||||
$('<span>System</span>')
|
||||
),
|
||||
$('<input />', { type:'text', 'class':'form-control', id: 'param.' + theRowNum + '.0', placeholder: "(opt)" }),
|
||||
$('<div />', { 'class':'input-group-addon', 'style':'padding:6px;'} ).append(
|
||||
$('<span>Code</span>')
|
||||
),
|
||||
$('<input />', { type:'text', 'class':'form-control', id: 'param.' + theRowNum + '.1', placeholder: "(opt)" })
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
} else if (theSearchParamType == 'string') {
|
||||
var placeholderText = 'value';
|
||||
var qualifiers = new Array();
|
||||
|
@ -93,17 +167,23 @@ function addSearchControls(theConformance, theSearchParamType, theSearchParamNam
|
|||
qualifierInput
|
||||
);
|
||||
|
||||
|
||||
var matchesLabel = $('<span>' + qualifiers[0].name + '</span>');
|
||||
var qualifierDropdown = $('<ul />', {'class':'dropdown-menu', role:'menu'});
|
||||
|
||||
function clickFunction(value, name){
|
||||
return function(){
|
||||
qualifierInput.val(value);
|
||||
matchesLabel.text(name);
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < qualifiers.length; i++) {
|
||||
var nextLink = $('<a>' + qualifiers[i].name+'</a>');
|
||||
var qualName = qualifiers[i].name;
|
||||
var nextValue = qualifiers[i].value;
|
||||
qualifierDropdown.append($('<li />').append(nextLink));
|
||||
nextLink.click(function(){
|
||||
qualifierInput.val(nextValue);
|
||||
matchesLabel.text(qualName);
|
||||
});
|
||||
nextLink.click(clickFunction(nextValue, qualName));
|
||||
}
|
||||
|
||||
$('#search-param-rowopts-' + theContainerRowNum).append(
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
@ -99,8 +99,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
@ -97,8 +97,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[^\s]+([\s][^\s]+)*"/>
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[^\s]+([\s][^\s]+)*"/>
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1]))?)?"/>
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1]))?)?"/>
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?)?)?"/>
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?)?)?"/>
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?([0]|([1-9][0-9]*))(\.[0-9]+)?"/>
|
||||
|
@ -102,8 +102,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?([0]|([1-9][0-9]*))(\.[0-9]+)?"/>
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[A-Za-z0-9\-\.]{1,64}"/>
|
||||
|
@ -102,8 +102,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[A-Za-z0-9\-\.]{1,64}"/>
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
@ -99,8 +99,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?([0]|([1-9][0-9]*))"/>
|
||||
|
@ -104,8 +104,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="-?([0]|([1-9][0-9]*))"/>
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
@ -99,8 +99,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="urn:oid:(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*"/>
|
||||
|
@ -102,8 +102,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="urn:oid:(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*"/>
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[1-9][0-9]*"/>
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[1-9][0-9]*"/>
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?"/>
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?"/>
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[0]|([1-9][0-9]*)"/>
|
||||
|
@ -100,8 +100,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="[0]|([1-9][0-9]*)"/>
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
@ -99,8 +99,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<code>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type">
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
<max value="1"/>
|
||||
</base>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"/>
|
||||
|
@ -102,8 +102,8 @@
|
|||
<min value="0"/>
|
||||
<max value="1"/>
|
||||
<!-- Note: primitive values do not have an assigned type
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
e.g. this is compiler magic
|
||||
XML and JSON types provided by extension -->
|
||||
<type>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-regex">
|
||||
<valueString value="urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"/>
|
||||
|
|
|
@ -56749,14 +56749,14 @@
|
|||
<contained>
|
||||
<ConceptMap xmlns="http://hl7.org/fhir">
|
||||
<id value="map"/>
|
||||
<name value="NHIN / V3 Mapping"/>
|
||||
<status value="draft"/>
|
||||
<sourceReference>
|
||||
<reference value="http://hl7.org/fhir/ValueSet/nhin-purposeofuse"/>
|
||||
</sourceReference>
|
||||
<targetReference>
|
||||
<reference value="http://hl7.org/fhir/ValueSet/v3-PurposeOfUse"/>
|
||||
</targetReference>
|
||||
<name value="NHIN / V3 Mapping"/>
|
||||
<status value="draft"/>
|
||||
<group>
|
||||
<source value="http://healthit.gov/nhin/purposeofuse"/>
|
||||
<target value="http://hl7.org/fhir/v3/ActReason"/>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,10 @@ import java.io.*;
|
|||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -11,6 +15,7 @@ import org.apache.maven.plugin.*;
|
|||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -51,6 +56,8 @@ public class ResourceMinimizerMojo extends AbstractMojo {
|
|||
myCtx = FhirContext.forDstu2_1();
|
||||
} else if ("DSTU3".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forDstu3();
|
||||
} else if ("R4".equals(fhirVersion)) {
|
||||
myCtx = FhirContext.forR4();
|
||||
} else {
|
||||
throw new MojoFailureException("Unknown version: " + fhirVersion);
|
||||
}
|
||||
|
@ -82,30 +89,8 @@ public class ResourceMinimizerMojo extends AbstractMojo {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (input instanceof org.hl7.fhir.dstu3.model.Bundle) {
|
||||
for (org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent nextEntry : ((org.hl7.fhir.dstu3.model.Bundle) input).getEntry()) {
|
||||
if (nextEntry.getResource() instanceof org.hl7.fhir.dstu3.model.DomainResource) {
|
||||
((org.hl7.fhir.dstu3.model.DomainResource) nextEntry.getResource()).getText().getDiv().setValueAsString((String) null);
|
||||
((org.hl7.fhir.dstu3.model.DomainResource) nextEntry.getResource()).getText().getStatusElement().setValueAsString((String) null);
|
||||
}
|
||||
}
|
||||
} else if (input instanceof org.hl7.fhir.dstu2016may.model.Bundle) {
|
||||
for (org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent nextEntry : ((org.hl7.fhir.dstu2016may.model.Bundle) input).getEntry()) {
|
||||
if (nextEntry.getResource() instanceof org.hl7.fhir.dstu2016may.model.DomainResource) {
|
||||
((org.hl7.fhir.dstu2016may.model.DomainResource) nextEntry.getResource()).getText().getDiv().setValueAsString((String) null);
|
||||
((org.hl7.fhir.dstu2016may.model.DomainResource) nextEntry.getResource()).getText().getStatusElement().setValueAsString((String) null);
|
||||
}
|
||||
}
|
||||
} else if (input instanceof org.hl7.fhir.dstu3.model.DomainResource) {
|
||||
try {
|
||||
((org.hl7.fhir.dstu3.model.DomainResource) input).getText().setDivAsString(null);
|
||||
((org.hl7.fhir.dstu3.model.DomainResource) input).getText().getStatusElement().setValueAsString(null);
|
||||
} catch (Exception e) {
|
||||
ourLog.error("Failed to clear narrative", e);
|
||||
}
|
||||
} else {
|
||||
ourLog.info("Ignoring type: " + input.getClass());
|
||||
continue;
|
||||
minimizeResource((IBaseResource)input);
|
||||
}
|
||||
|
||||
String outputString = parser.setPrettyPrint(true).encodeResourceToString(input);
|
||||
|
@ -143,6 +128,20 @@ public class ResourceMinimizerMojo extends AbstractMojo {
|
|||
}
|
||||
}
|
||||
|
||||
private void minimizeResource(IBaseResource theInput) {
|
||||
if (theInput instanceof IBaseBundle) {
|
||||
for (IBaseResource next : BundleUtil.toListOfResources(myCtx, (IBaseBundle) theInput)) {
|
||||
minimizeResource(next);
|
||||
}
|
||||
}
|
||||
|
||||
BaseRuntimeElementCompositeDefinition<?> element = (BaseRuntimeElementCompositeDefinition) myCtx.getElementDefinition(theInput.getClass());
|
||||
BaseRuntimeChildDefinition textElement = element.getChildByName("text");
|
||||
if (textElement != null) {
|
||||
textElement.getMutator().setValue(theInput, null);
|
||||
}
|
||||
}
|
||||
|
||||
public long getByteCount() {
|
||||
return myByteCount;
|
||||
}
|
||||
|
@ -153,9 +152,10 @@ public class ResourceMinimizerMojo extends AbstractMojo {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
FhirContext ctxDstu2 = FhirContext.forDstu2();
|
||||
// FhirContext ctxDstu2_1 = FhirContext.forDstu2_1();
|
||||
// FhirContext ctxDstu3 = FhirContext.forDstu3();
|
||||
|
||||
FhirContext ctxDstu2_1 = FhirContext.forDstu2_1();
|
||||
FhirContext ctxDstu3 = FhirContext.forDstu3();
|
||||
FhirContext ctxR4 = FhirContext.forR4();
|
||||
|
||||
LoggerContext loggerContext = ((ch.qos.logback.classic.Logger) ourLog).getLoggerContext();
|
||||
URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(loggerContext);
|
||||
System.out.println(mainURL);
|
||||
|
@ -166,59 +166,76 @@ public class ResourceMinimizerMojo extends AbstractMojo {
|
|||
long byteCount = 0;
|
||||
|
||||
ResourceMinimizerMojo m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu2;
|
||||
// m.targetDirectory = new File("../hapi-tinder-plugin/src/main/resources/vs/dstu2");
|
||||
// m.fhirVersion = "DSTU2";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
//
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu2;
|
||||
// m.targetDirectory = new File("../hapi-fhir-validation-resources-dstu2/src/main/resources/org/hl7/fhir/instance/model/valueset");
|
||||
// m.fhirVersion = "DSTU2";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
//
|
||||
m = new ResourceMinimizerMojo();
|
||||
|
||||
m.myCtx = ctxDstu2;
|
||||
m.targetDirectory = new File("../hapi-fhir-validation-resources-dstu2/src/main/resources/org/hl7/fhir/instance/model/profile");
|
||||
m.targetDirectory = new File("./hapi-tinder-plugin/src/main/resources/vs/dstu2");
|
||||
m.fhirVersion = "DSTU2";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu3;
|
||||
// m.targetDirectory = new File("../hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/profile");
|
||||
// m.fhirVersion = "DSTU3";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2/src/main/resources/org/hl7/fhir/instance/model/valueset");
|
||||
m.fhirVersion = "DSTU2";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu3;
|
||||
// m.targetDirectory = new File("../hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/valueset");
|
||||
// m.fhirVersion = "DSTU3";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2/src/main/resources/org/hl7/fhir/instance/model/profile");
|
||||
m.fhirVersion = "DSTU2";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu2_1;
|
||||
// m.targetDirectory = new File("../hapi-fhir-validation-resources-dstu2.1/src/main/resources/org/hl7/fhir/dstu2016may/model/profile");
|
||||
// m.fhirVersion = "DSTU2_1";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
//
|
||||
// m = new ResourceMinimizerMojo();
|
||||
// m.myCtx = ctxDstu2_1;
|
||||
// m.targetDirectory = new File("../hapi-fhir-validation-resources-dstu2.1/src/main/resources/org/hl7/fhir/dstu2016may/model/valueset");
|
||||
// m.fhirVersion = "DSTU2_1";
|
||||
// m.execute();
|
||||
// byteCount += m.getByteCount();
|
||||
// fileCount += m.getFileCount();
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu3;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/profile");
|
||||
m.fhirVersion = "DSTU3";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu3;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/dstu3/model/valueset");
|
||||
m.fhirVersion = "DSTU3";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2_1;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2.1/src/main/resources/org/hl7/fhir/dstu2016may/model/profile");
|
||||
m.fhirVersion = "DSTU2_1";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2_1;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-dstu2.1/src/main/resources/org/hl7/fhir/dstu2016may/model/valueset");
|
||||
m.fhirVersion = "DSTU2_1";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2_1;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile");
|
||||
m.fhirVersion = "R4";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
m = new ResourceMinimizerMojo();
|
||||
m.myCtx = ctxDstu2_1;
|
||||
m.targetDirectory = new File("./hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset");
|
||||
m.fhirVersion = "R4";
|
||||
m.execute();
|
||||
byteCount += m.getByteCount();
|
||||
fileCount += m.getFileCount();
|
||||
|
||||
ourLog.info("Trimmed {} files", fileCount);
|
||||
ourLog.info("Trimmed {} bytes", FileUtils.byteCountToDisplaySize(byteCount));
|
||||
|
|
12
pom.xml
12
pom.xml
|
@ -346,6 +346,18 @@
|
|||
<id>SarenCurrie</id>
|
||||
<name>Saren Currie</name>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>dconlan</id>
|
||||
<name>dconlan</name>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>psbrandt</id>
|
||||
<name>Pascal Brandt</name>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>InfiniteLoop90</id>
|
||||
<name>Clayton Bodendein</name>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
|
|
|
@ -269,6 +269,33 @@
|
|||
correctly validated if the element contained only a profiled extension. Thanks
|
||||
to Sébastien Rivière for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="701">
|
||||
Testing UI now has a dropdown for modifiers on token search. Thanks
|
||||
to GitHub user @dconlan for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="688">
|
||||
When parsing an incomplete ID with the form <![CDATA[<code>http://my.org/Foo</code>]]> into
|
||||
IdDt and IdType objects, the Foo portion will now be treated as the resource type.
|
||||
Previously my.org was treated as the resource type and Foo was treated as the ID. Thanks
|
||||
to GitHub user @CarthageKing for the pull request!
|
||||
</action>
|
||||
<action type="fix" issue="695">
|
||||
Extensions on ID datatypes were not parsed or serialized correctly. Thanks to
|
||||
Stephen Rivière for the pull request!
|
||||
</action>
|
||||
<action type="fix" issue="710">
|
||||
Fix a bug in REST Hook Subscription interceptors which prevented subscriptions
|
||||
from being activated. Thanks to Jeff Chung for the pull request!
|
||||
</action>
|
||||
<action type="fix" issue="708">
|
||||
Fix broken links in usage pattern diagram on website. Thanks to
|
||||
Pascal Brandt for the pull request!
|
||||
</action>
|
||||
<action type="fix" issue="706">
|
||||
Fix incorrect FHIR Version Strings that were being outputted and verified in the
|
||||
client for some versions of FHIR. Thanks to Clayton Bodendein for the
|
||||
pull request!
|
||||
</action>
|
||||
</release>
|
||||
<release version="2.5" date="2017-06-08">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue