Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e040ef3f43
|
@ -65,7 +65,6 @@
|
|||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
|
|
@ -15,26 +15,6 @@
|
|||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (1).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
|
|
|
@ -37,25 +37,20 @@ public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
|
|||
public BoundCodeDt() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
public BoundCodeDt(IValueSetEnumBinder<T> theBinder) {
|
||||
Validate.notNull(theBinder, "theBinder must not be null");
|
||||
myBinder = theBinder;
|
||||
}
|
||||
|
||||
|
||||
public BoundCodeDt(IValueSetEnumBinder<T> theBinder, T theValue) {
|
||||
Validate.notNull(theBinder, "theBinder must not be null");
|
||||
myBinder = theBinder;
|
||||
setValueAsEnum(theValue);
|
||||
}
|
||||
|
||||
public void setValueAsEnum(T theValue) {
|
||||
Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeDt() should not be called!");
|
||||
if (theValue==null) {
|
||||
setValue(null);
|
||||
} else {
|
||||
setValue(myBinder.toCodeString(theValue));
|
||||
}
|
||||
public IValueSetEnumBinder<T> getBinder() {
|
||||
return myBinder;
|
||||
}
|
||||
|
||||
public T getValueAsEnum() {
|
||||
|
@ -66,4 +61,13 @@ public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
|
|||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public void setValueAsEnum(T theValue) {
|
||||
Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeDt() should not be called!");
|
||||
if (theValue==null) {
|
||||
setValue(null);
|
||||
} else {
|
||||
setValue(myBinder.toCodeString(theValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,6 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isBaseEmpty() && (getValue() == null || getValue().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor which accepts a string code
|
||||
*
|
||||
|
@ -65,27 +60,25 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
setValueAsString(theTextDiv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a textual DIV and parses it into XHTML events which are stored internally.
|
||||
* <p>
|
||||
* <b>Formatting note:</b> The text will be trimmed {@link String#trim()}. If the text does not start with an HTML tag (generally this would be a div tag), a div tag will be automatically placed
|
||||
* surrounding the text.
|
||||
* </p>
|
||||
* <p>
|
||||
* Also note that if the parsed text contains any entities (&foo;) which are not a part of the entities defined in core XML (e.g. &sect; which
|
||||
* is valid in XHTML 1.0 but not in XML 1.0) they will be parsed and converted to their equivalent unicode character.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void setValueAsString(String theValue) throws DataFormatException {
|
||||
if (theValue == null || theValue.isEmpty()) {
|
||||
super.setValueAsString(null);
|
||||
} else {
|
||||
String value = theValue.trim();
|
||||
if (value.charAt(0) != '<') {
|
||||
value = "<div>" + value + "</div>";
|
||||
protected String encode(List<XMLEvent> theValue) {
|
||||
try {
|
||||
StringWriter w = new StringWriter();
|
||||
XMLEventWriter ew = XmlUtil.createXmlFragmentWriter(w);
|
||||
|
||||
for (XMLEvent next : getValue()) {
|
||||
if (next.isCharacters()) {
|
||||
ew.add(next);
|
||||
} else {
|
||||
ew.add(next);
|
||||
}
|
||||
}
|
||||
super.setValueAsString(value);
|
||||
ew.close();
|
||||
return w.toString();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new DataFormatException("Problem with the contained XML events", e);
|
||||
} catch (FactoryConfigurationError e) {
|
||||
throw new ConfigurationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +86,11 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
return getValue() != null && getValue().size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isBaseEmpty() && (getValue() == null || getValue().isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<XMLEvent> parse(String theValue) {
|
||||
String val = theValue.trim();
|
||||
|
@ -128,24 +126,27 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a textual DIV and parses it into XHTML events which are stored internally.
|
||||
* <p>
|
||||
* <b>Formatting note:</b> The text will be trimmed {@link String#trim()}. If the text does not start with an HTML tag (generally this would be a div tag), a div tag will be automatically placed
|
||||
* surrounding the text.
|
||||
* </p>
|
||||
* <p>
|
||||
* Also note that if the parsed text contains any entities (&foo;) which are not a part of the entities defined in core XML (e.g. &sect; which is valid in XHTML 1.0 but not in XML 1.0) they
|
||||
* will be parsed and converted to their equivalent unicode character.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
protected String encode(List<XMLEvent> theValue) {
|
||||
try {
|
||||
StringWriter w = new StringWriter();
|
||||
XMLEventWriter ew = XmlUtil.createXmlWriter(w);
|
||||
for (XMLEvent next : getValue()) {
|
||||
if (next.isCharacters()) {
|
||||
ew.add(next);
|
||||
} else {
|
||||
ew.add(next);
|
||||
}
|
||||
public void setValueAsString(String theValue) throws DataFormatException {
|
||||
if (theValue == null || theValue.isEmpty()) {
|
||||
super.setValueAsString(null);
|
||||
} else {
|
||||
String value = theValue.trim();
|
||||
if (value.charAt(0) != '<') {
|
||||
value = "<div>" + value + "</div>";
|
||||
}
|
||||
ew.close();
|
||||
return w.toString();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new DataFormatException("Problem with the contained XML events", e);
|
||||
} catch (FactoryConfigurationError e) {
|
||||
throw new ConfigurationException(e);
|
||||
super.setValueAsString(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.apache.http.client.methods.HttpRequestBase;
|
|||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -100,6 +101,7 @@ import ca.uhn.fhir.rest.gclient.IOperation;
|
|||
import ca.uhn.fhir.rest.gclient.IOperationUnnamed;
|
||||
import ca.uhn.fhir.rest.gclient.IOperationUntyped;
|
||||
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInput;
|
||||
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
|
||||
import ca.uhn.fhir.rest.gclient.IParam;
|
||||
import ca.uhn.fhir.rest.gclient.IQuery;
|
||||
import ca.uhn.fhir.rest.gclient.IRead;
|
||||
|
@ -229,7 +231,8 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return delete(theType, new IdDt(theId));
|
||||
}
|
||||
|
||||
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches, Boolean thePrettyPrint, SummaryEnum theSummary, EncodingEnum theEncoding, Set<String> theSubsetElements) {
|
||||
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches, Boolean thePrettyPrint,
|
||||
SummaryEnum theSummary, EncodingEnum theEncoding, Set<String> theSubsetElements) {
|
||||
String resName = toResourceName(theType);
|
||||
IIdType id = theId;
|
||||
if (!id.hasBaseUrl()) {
|
||||
|
@ -906,6 +909,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
myCriterionList.add((ICriterionInternal) theCriterion);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDeleteWithQuery resourceConditionalByType(Class<? extends IBaseResource> theResourceType) {
|
||||
Validate.notNull(theResourceType, "theResourceType can not be null");
|
||||
myCriterionList = new CriterionList();
|
||||
myResourceType = myContext.getResourceDefinition(theResourceType).getName();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
|
@ -1353,13 +1364,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private class OperationInternal extends BaseClientExecutable implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput {
|
||||
private class OperationInternal extends BaseClientExecutable implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput, IOperationUntypedWithInputAndPartialOutput {
|
||||
|
||||
private IIdType myId;
|
||||
private String myOperationName;
|
||||
private IBaseParameters myParameters;
|
||||
private Class<? extends IBaseResource> myType;
|
||||
private boolean myUseHttpGet;
|
||||
private RuntimeResourceDefinition myParametersDef;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
|
@ -1455,6 +1467,51 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseParameters> IOperationUntypedWithInputAndPartialOutput<T> withParameter(Class<T> theParameterType, String theName, IBase theValue) {
|
||||
Validate.notNull(theParameterType, "theParameterType must not be null");
|
||||
Validate.notEmpty(theName, "theName must not be null");
|
||||
Validate.notNull(theValue, "theValue must not be null");
|
||||
|
||||
myParametersDef = myContext.getResourceDefinition(theParameterType);
|
||||
myParameters = (IBaseParameters) myParametersDef.newInstance();
|
||||
|
||||
addParam(theName, theValue);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addParam(String theName, IBase theValue) {
|
||||
BaseRuntimeChildDefinition parameterChild = myParametersDef.getChildByName("parameter");
|
||||
BaseRuntimeElementCompositeDefinition<?> parameterElem = (BaseRuntimeElementCompositeDefinition<?>) parameterChild.getChildByName("parameter");
|
||||
|
||||
IBase parameter = parameterElem.newInstance();
|
||||
parameterChild.getMutator().addValue(myParameters, parameter);
|
||||
|
||||
IPrimitiveType<String> name = (IPrimitiveType<String>) myContext.getElementDefinition("string").newInstance();
|
||||
name.setValue(theName);
|
||||
parameterElem.getChildByName("name").getMutator().setValue(parameter, name);
|
||||
|
||||
if (theValue instanceof IBaseDatatype) {
|
||||
String childElementName = "value" + StringUtils.capitalize(myContext.getElementDefinition(theValue.getClass()).getName());
|
||||
parameterElem.getChildByName(childElementName).getMutator().setValue(parameter, theValue);
|
||||
} else if (theValue instanceof IBaseResource) {
|
||||
parameterElem.getChildByName("resource").getMutator().setValue(parameter, theValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to handle parameter of type " + theValue.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOperationUntypedWithInputAndPartialOutput andParameter(String theName, IBase theValue) {
|
||||
Validate.notEmpty(theName, "theName must not be null");
|
||||
Validate.notNull(theValue, "theValue must not be null");
|
||||
addParam(theName, theValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class OperationOutcomeResponseHandler implements IClientResponseHandler<BaseOperationOutcome> {
|
||||
|
@ -1506,7 +1563,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
private RuntimeResourceDefinition myType;
|
||||
|
||||
@Override
|
||||
public Object execute() {//AAA
|
||||
public Object execute() {// AAA
|
||||
if (myId.hasVersionIdPart()) {
|
||||
return doReadOrVRead(myType.getImplementingClass(), myId, true, myNotModifiedHandler, myIfVersionMatches, myPrettyPrint, mySummaryMode, myParamEncoding, getSubsetElements());
|
||||
} else {
|
||||
|
@ -1693,7 +1750,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
BaseRuntimeElementCompositeDefinition<?> textElement = (BaseRuntimeElementCompositeDefinition<?>) textChild.getChildByName("text");
|
||||
IBase textInstance = textElement.newInstance();
|
||||
textChild.getMutator().addValue(instance, textInstance);
|
||||
|
||||
|
||||
BaseRuntimeChildDefinition divChild = textElement.getChildByName("div");
|
||||
BaseRuntimeElementDefinition<?> divElement = divChild.getChildByName("div");
|
||||
IPrimitiveType<?> divInstance = (IPrimitiveType<?>) divElement.newInstance();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -43,8 +44,15 @@ public interface IDelete {
|
|||
IDeleteTyped resourceConditionalByUrl(String theSearchUrl);
|
||||
|
||||
/**
|
||||
* Delete using a conditional/match URL. The query parameters will be added in the next part of the call chain.
|
||||
* @since HAPI 0.9 / FHIR DSTU 2
|
||||
*/
|
||||
IDeleteWithQuery resourceConditionalByType(String theResourceType);
|
||||
|
||||
/**
|
||||
* Delete using a conditional/match URL. The query parameters will be added in the next part of the call chain.
|
||||
* @since HAPI 1.3
|
||||
*/
|
||||
IDeleteWithQuery resourceConditionalByType(Class<? extends IBaseResource> theResourceType);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -40,4 +42,16 @@ public interface IOperationUntyped {
|
|||
*/
|
||||
<T extends IBaseParameters> IOperationUntypedWithInput<T> withNoParameters(Class<T> theOutputParameterType);
|
||||
|
||||
/**
|
||||
* Use chained method calls to construct a Parameters input. This form is a convenience
|
||||
* in order to allow simple method chaining to be used to build up a parameters
|
||||
* resource for the input of an operation without needing to manually construct one.
|
||||
*
|
||||
* @param theParameterType The type to use for the output parameters (this should be set to
|
||||
* <code>Parameters.class</code> drawn from the version of the FHIR structures you are using)
|
||||
* @param theName The first parameter name
|
||||
* @param theValue The first parameter value
|
||||
*/
|
||||
<T extends IBaseParameters> IOperationUntypedWithInputAndPartialOutput<T> withParameter(Class<T> theParameterType, String theName, IBase theValue);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%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%
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
|
||||
public interface IOperationUntypedWithInputAndPartialOutput<T extends IBaseParameters> extends IOperationUntypedWithInput<T> {
|
||||
|
||||
/**
|
||||
* Use chained method calls to construct a Parameters input. This form is a convenience
|
||||
* in order to allow simple method chaining to be used to build up a parameters
|
||||
* resource for the input of an operation without needing to manually construct one.
|
||||
*
|
||||
* @param theName The first parameter name
|
||||
* @param theValue The first parameter value
|
||||
*/
|
||||
IOperationUntypedWithInputAndPartialOutput<T> andParameter(String theName, IBase theValue);
|
||||
|
||||
}
|
|
@ -73,6 +73,10 @@ public abstract class BaseServerResponseException extends RuntimeException {
|
|||
private String myResponseMimeType;
|
||||
private int myStatusCode;
|
||||
|
||||
public static void main (String[] args) {
|
||||
BaseServerResponseException.class.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
|
|
@ -43,11 +43,13 @@ import ca.uhn.fhir.util.OperationOutcomeUtil;
|
|||
|
||||
public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
||||
|
||||
public static final String PROCESSING = "processing";
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptor.class);
|
||||
private Class<?>[] myReturnStackTracesForExceptionTypes;
|
||||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theRequest, HttpServletResponse theResponse)
|
||||
throws ServletException, IOException {
|
||||
|
||||
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
|
||||
|
||||
|
@ -116,12 +118,20 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
|||
ourLog.error("Failure during REST processing", theException);
|
||||
populateDetails(ctx, theException, oo);
|
||||
} else if (theException instanceof BaseServerResponseException) {
|
||||
ourLog.warn("Failure during REST processing: {}", theException);
|
||||
int statusCode = ((BaseServerResponseException) theException).getStatusCode();
|
||||
|
||||
// No stack traces for non-server internal errors
|
||||
if (statusCode < 500) {
|
||||
ourLog.warn("Failure during REST processing: {}", theException.toString());
|
||||
} else {
|
||||
ourLog.warn("Failure during REST processing: {}", theException);
|
||||
}
|
||||
|
||||
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
|
||||
populateDetails(ctx, theException, oo);
|
||||
if (baseServerResponseException.getAdditionalMessages() != null) {
|
||||
for (String next : baseServerResponseException.getAdditionalMessages()) {
|
||||
OperationOutcomeUtil.addIssue(ctx, oo, "error", next);
|
||||
OperationOutcomeUtil.addIssue(ctx, oo, "error", next, null, PROCESSING);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -143,19 +153,18 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
|||
for (Class<?> next : myReturnStackTracesForExceptionTypes) {
|
||||
if (next.isAssignableFrom(theException.getClass())) {
|
||||
String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException);
|
||||
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", detailsValue);
|
||||
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", detailsValue, null, PROCESSING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", theException.getMessage());
|
||||
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", theException.getMessage(), null, PROCESSING);
|
||||
}
|
||||
|
||||
/**
|
||||
* If any server methods throw an exception which extends any of the given exception types, the exception stack trace
|
||||
* will be returned to the user. This can be useful for helping to diagnose issues, but may not be desirable for
|
||||
* production situations.
|
||||
* If any server methods throw an exception which extends any of the given exception types, the exception stack trace will be returned to the user. This can be useful for helping to diagnose
|
||||
* issues, but may not be desirable for production situations.
|
||||
*
|
||||
* @param theExceptionTypes
|
||||
* The exception types for which to return the stack trace to the user.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -24,6 +26,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import java.net.URLEncoder;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -38,6 +41,7 @@ import ca.uhn.fhir.rest.method.RequestDetails;
|
|||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
|
||||
/**
|
||||
* Server interceptor which logs each request using a defined format
|
||||
|
@ -67,8 +71,8 @@ import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
|||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestHeader.XXXX}</td>
|
||||
* <td>The value of the HTTP request header named XXXX. For example, a substitution variable named
|
||||
* "${requestHeader.x-forwarded-for} will yield the value of the first header named "x-forwarded-for", or "" if none.</td>
|
||||
* <td>The value of the HTTP request header named XXXX. For example, a substitution variable named "${requestHeader.x-forwarded-for} will yield the value of the first header named "x-forwarded-for
|
||||
* ", or "" if none.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestParameters}</td>
|
||||
|
@ -82,15 +86,52 @@ import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
|||
* <td>${servletPath}</td>
|
||||
* <td>The part of thre requesting URL that corresponds to the particular Servlet being called (see {@link HttpServletRequest#getServletPath()})</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestUrl}</td>
|
||||
* <td>The complete URL of the request</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${requestVerb}</td>
|
||||
* <td>The HTTP verb of the request</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>${exceptionMessage}</td>
|
||||
* <td>Applies only to an error message: The message from {@link Exception#getMessage()}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
public class LoggingInterceptor extends InterceptorAdapter {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(LoggingInterceptor.class);
|
||||
|
||||
private String myErrorMessageFormat = "ERROR - ${idOrResourceName}";
|
||||
private boolean myLogExceptions;
|
||||
private Logger myLogger = ourLog;
|
||||
private String myMessageFormat = "${operationType} - ${idOrResourceName}";
|
||||
|
||||
/**
|
||||
* Get the log message format to be used when logging exceptions
|
||||
*/
|
||||
public String getErrorMessageFormat() {
|
||||
return myErrorMessageFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
|
||||
throws ServletException, IOException {
|
||||
if (myLogExceptions) {
|
||||
// Perform any string substitutions from the message format
|
||||
StrLookup<?> lookup = new MyLookup(theServletRequest, theException, theRequestDetails);
|
||||
StrSubstitutor subs = new StrSubstitutor(lookup, "${", "}", '\\');
|
||||
|
||||
// Actuall log the line
|
||||
String line = subs.replace(myErrorMessageFormat);
|
||||
myLogger.info(line);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean incomingRequestPostProcessed(final RequestDetails theRequestDetails, final HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException {
|
||||
|
||||
|
@ -105,6 +146,28 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should exceptions be logged by this logger
|
||||
*/
|
||||
public boolean isLogExceptions() {
|
||||
return myLogExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log message format to be used when logging exceptions
|
||||
*/
|
||||
public void setErrorMessageFormat(String theErrorMessageFormat) {
|
||||
Validate.notBlank(theErrorMessageFormat, "Message format can not be null/empty");
|
||||
myErrorMessageFormat = theErrorMessageFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should exceptions be logged by this logger
|
||||
*/
|
||||
public void setLogExceptions(boolean theLogExceptions) {
|
||||
myLogExceptions = theLogExceptions;
|
||||
}
|
||||
|
||||
public void setLogger(Logger theLogger) {
|
||||
Validate.notNull(theLogger, "Logger can not be null");
|
||||
myLogger = theLogger;
|
||||
|
@ -125,12 +188,20 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
}
|
||||
|
||||
private static final class MyLookup extends StrLookup<String> {
|
||||
private final Throwable myException;
|
||||
private final HttpServletRequest myRequest;
|
||||
private final RequestDetails myRequestDetails;
|
||||
|
||||
private MyLookup(HttpServletRequest theRequest, RequestDetails theRequestDetails) {
|
||||
myRequest = theRequest;
|
||||
myRequestDetails = theRequestDetails;
|
||||
myException = null;
|
||||
}
|
||||
|
||||
public MyLookup(HttpServletRequest theServletRequest, BaseServerResponseException theException, RequestDetails theRequestDetails) {
|
||||
myException = theException;
|
||||
myRequestDetails = theRequestDetails;
|
||||
myRequest = theServletRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -204,6 +275,12 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
} else {
|
||||
return "";
|
||||
}
|
||||
} else if (theKey.equals("exceptionMessage")) {
|
||||
return myException != null ? myException.getMessage() : null;
|
||||
} else if (theKey.equals("requestUrl")) {
|
||||
return myRequest.getRequestURL().toString();
|
||||
} else if (theKey.equals("requestVerb")) {
|
||||
return myRequest.getMethod();
|
||||
}
|
||||
|
||||
return "!VAL!";
|
||||
|
|
|
@ -42,22 +42,23 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
*/
|
||||
public class OperationOutcomeUtil {
|
||||
|
||||
/**
|
||||
* Add an issue to an OperationOutcome
|
||||
*
|
||||
* @param theCtx
|
||||
* The fhir context
|
||||
* @param theOperationOutcome
|
||||
* The OO resource to add to
|
||||
* @param theSeverity
|
||||
* The severity (e.g. "error")
|
||||
* @param theDetails
|
||||
* The details string
|
||||
*/
|
||||
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails) {
|
||||
IBase issue = createIssue(theCtx, theOperationOutcome);
|
||||
populateDetails(theCtx, issue, theSeverity, theDetails, null);
|
||||
}
|
||||
// /**
|
||||
// * Add an issue to an OperationOutcome
|
||||
// *
|
||||
// * @param theCtx
|
||||
// * The fhir context
|
||||
// * @param theOperationOutcome
|
||||
// * The OO resource to add to
|
||||
// * @param theSeverity
|
||||
// * The severity (e.g. "error")
|
||||
// * @param theDetails
|
||||
// * The details string
|
||||
// * @param theCode
|
||||
// */
|
||||
// public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theCode) {
|
||||
// IBase issue = createIssue(theCtx, theOperationOutcome);
|
||||
// populateDetails(theCtx, issue, theSeverity, theDetails, null, theCode);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Add an issue to an OperationOutcome
|
||||
|
@ -70,10 +71,11 @@ public class OperationOutcomeUtil {
|
|||
* The severity (e.g. "error")
|
||||
* @param theDetails
|
||||
* The details string
|
||||
* @param theCode
|
||||
*/
|
||||
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theLocation) {
|
||||
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theLocation, String theCode) {
|
||||
IBase issue = createIssue(theCtx, theOperationOutcome);
|
||||
populateDetails(theCtx, issue, theSeverity, theDetails, theLocation);
|
||||
populateDetails(theCtx, issue, theSeverity, theDetails, theLocation, theCode);
|
||||
}
|
||||
|
||||
private static IBase createIssue(FhirContext theCtx, IBaseResource theOutcome) {
|
||||
|
@ -145,11 +147,16 @@ public class OperationOutcomeUtil {
|
|||
}
|
||||
}
|
||||
|
||||
private static void populateDetails(FhirContext theCtx, IBase theIssue, String theSeverity, String theDetails, String theLocation) {
|
||||
private static void populateDetails(FhirContext theCtx, IBase theIssue, String theSeverity, String theDetails, String theLocation, String theCode) {
|
||||
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(theIssue.getClass());
|
||||
BaseRuntimeChildDefinition detailsChild;
|
||||
if (theCtx.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||
detailsChild = issueElement.getChildByName("diagnostics");
|
||||
|
||||
BaseRuntimeChildDefinition codeChild = issueElement.getChildByName("code");
|
||||
IPrimitiveType<?> codeElem = (IPrimitiveType<?>) codeChild.getChildByName("code").newInstance(codeChild.getInstanceConstructorArguments());
|
||||
codeElem.setValueAsString(theCode);
|
||||
codeChild.getMutator().addValue(theIssue, codeElem);
|
||||
} else {
|
||||
detailsChild = issueElement.getChildByName("details");
|
||||
}
|
||||
|
|
|
@ -173,17 +173,22 @@ public class UrlUtil {
|
|||
*/
|
||||
//@formatter:on
|
||||
public static UrlParts parseUrl(String theUrl) {
|
||||
String url = theUrl;
|
||||
if (url.matches("\\/[a-zA-Z]+\\?.*")) {
|
||||
url = url.substring(1);
|
||||
}
|
||||
|
||||
UrlParts retVal = new UrlParts();
|
||||
|
||||
int nextStart = 0;
|
||||
boolean nextIsHistory = false;
|
||||
|
||||
for (int idx = 0; idx < theUrl.length(); idx++) {
|
||||
char nextChar = theUrl.charAt(idx);
|
||||
boolean atEnd = (idx + 1) == theUrl.length();
|
||||
for (int idx = 0; idx < url.length(); idx++) {
|
||||
char nextChar = url.charAt(idx);
|
||||
boolean atEnd = (idx + 1) == url.length();
|
||||
if (nextChar == '?' || nextChar == '/' || atEnd) {
|
||||
int endIdx = atEnd ? idx + 1 : idx;
|
||||
String nextSubstring = theUrl.substring(nextStart, endIdx);
|
||||
String nextSubstring = url.substring(nextStart, endIdx);
|
||||
if (retVal.getResourceType() == null) {
|
||||
retVal.setResourceType(nextSubstring);
|
||||
} else if (retVal.getResourceId() == null) {
|
||||
|
@ -194,12 +199,12 @@ public class UrlUtil {
|
|||
if (nextSubstring.equals(Constants.URL_TOKEN_HISTORY)) {
|
||||
nextIsHistory = true;
|
||||
} else {
|
||||
throw new InvalidRequestException("Invalid FHIR resource URL: " + theUrl);
|
||||
throw new InvalidRequestException("Invalid FHIR resource URL: " + url);
|
||||
}
|
||||
}
|
||||
if (nextChar == '?') {
|
||||
if (theUrl.length() > idx + 1) {
|
||||
retVal.setParams(theUrl.substring(idx + 1, theUrl.length()));
|
||||
if (url.length() > idx + 1) {
|
||||
retVal.setParams(url.substring(idx + 1, url.length()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ public class XmlUtil {
|
|||
private static volatile XMLInputFactory ourInputFactory;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
|
||||
private static volatile XMLOutputFactory ourOutputFactory;
|
||||
private static XMLOutputFactory ourFragmentOutputFactory;
|
||||
private static final Map<String, Integer> VALID_ENTITY_NAMES;
|
||||
private static final ExtendedEntityReplacingXmlResolver XML_RESOLVER = new ExtendedEntityReplacingXmlResolver();
|
||||
|
||||
|
@ -1539,6 +1540,12 @@ public class XmlUtil {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static XMLEventWriter createXmlFragmentWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
XMLOutputFactory outputFactory = getOrCreateFragmentOutputFactory();
|
||||
XMLEventWriter retVal = outputFactory.createXMLEventWriter(theWriter);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static XMLEventWriter createXmlWriter(Writer theWriter) throws FactoryConfigurationError, XMLStreamException {
|
||||
XMLOutputFactory outputFactory = getOrCreateOutputFactory();
|
||||
XMLEventWriter retVal = outputFactory.createXMLEventWriter(theWriter);
|
||||
|
@ -1589,40 +1596,55 @@ public class XmlUtil {
|
|||
return ourInputFactory;
|
||||
}
|
||||
|
||||
private static XMLOutputFactory getOrCreateFragmentOutputFactory() throws FactoryConfigurationError {
|
||||
XMLOutputFactory retVal = ourFragmentOutputFactory;
|
||||
if (retVal == null) {
|
||||
retVal = createOutputFactory();
|
||||
retVal.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
|
||||
ourFragmentOutputFactory = retVal;
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
private static XMLOutputFactory getOrCreateOutputFactory() throws FactoryConfigurationError {
|
||||
if (ourOutputFactory == null) {
|
||||
|
||||
try {
|
||||
// Detect if we're running with the Android lib, and force repackaged Woodstox to be used
|
||||
Class.forName("ca.uhn.fhir.repackage.javax.xml.stream.XMLOutputFactory");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ok
|
||||
}
|
||||
|
||||
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
|
||||
|
||||
if (!ourHaveLoggedStaxImplementation) {
|
||||
logStaxImplementation(outputFactory.getClass());
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that these properties are Woodstox specific and they cause a crash in environments where SJSXP is
|
||||
* being used (e.g. glassfish) so we don't set them there.
|
||||
*/
|
||||
try {
|
||||
Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
|
||||
if (outputFactory instanceof WstxOutputFactory) {
|
||||
outputFactory.setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, new MyEscaper());
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
ourLog.debug("WstxOutputFactory (Woodstox) not found on classpath");
|
||||
}
|
||||
ourOutputFactory = outputFactory;
|
||||
ourOutputFactory = createOutputFactory();
|
||||
}
|
||||
return ourOutputFactory;
|
||||
}
|
||||
|
||||
private static XMLOutputFactory createOutputFactory() throws FactoryConfigurationError {
|
||||
try {
|
||||
// Detect if we're running with the Android lib, and force repackaged Woodstox to be used
|
||||
Class.forName("ca.uhn.fhir.repackage.javax.xml.stream.XMLOutputFactory");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ok
|
||||
}
|
||||
|
||||
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
|
||||
|
||||
if (!ourHaveLoggedStaxImplementation) {
|
||||
logStaxImplementation(outputFactory.getClass());
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that these properties are Woodstox specific and they cause a crash in environments where SJSXP is
|
||||
* being used (e.g. glassfish) so we don't set them there.
|
||||
*/
|
||||
try {
|
||||
Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
|
||||
if (outputFactory instanceof WstxOutputFactory) {
|
||||
outputFactory.setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, new MyEscaper());
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
ourLog.debug("WstxOutputFactory (Woodstox) not found on classpath");
|
||||
}
|
||||
return outputFactory;
|
||||
}
|
||||
|
||||
private static URL getRootUrlForClass(Class<?> cls) {
|
||||
ClassLoader classLoader = cls.getClassLoader();
|
||||
String resource = cls.getName().replace('.', '/') + ".class";
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.List;
|
|||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||
|
||||
/**
|
||||
|
@ -107,7 +108,7 @@ public class ValidationResult {
|
|||
location = null;
|
||||
}
|
||||
String severity = next.getSeverity() != null ? next.getSeverity().getCode() : null;
|
||||
OperationOutcomeUtil.addIssue(myCtx, oo, severity, next.getMessage(), location);
|
||||
OperationOutcomeUtil.addIssue(myCtx, oo, severity, next.getMessage(), location, ExceptionHandlingInterceptor.PROCESSING);
|
||||
}
|
||||
|
||||
return oo;
|
||||
|
|
|
@ -47,6 +47,13 @@
|
|||
<!-- Don't include in standard distribution -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-android</artifactId>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<!-- Don't include in standard distribution -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
|
@ -100,6 +107,7 @@
|
|||
<descriptor>${project.basedir}/src/assembly/hapi-fhir-standard-distribution.xml</descriptor>
|
||||
<descriptor>${project.basedir}/src/assembly/hapi-fhir-jpaserver-example.xml</descriptor>
|
||||
<descriptor>${project.basedir}/src/assembly/hapi-fhir-android-distribution.xml</descriptor>
|
||||
<descriptor>${project.basedir}/src/assembly/hapi-fhir-cli.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
|
||||
<id>android-distribution</id>
|
||||
|
||||
|
@ -15,9 +16,38 @@
|
|||
<directory>${project.basedir}/../hapi-fhir-android/target/</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>hapi-fhir-android-${project.version}*.jar</include>
|
||||
<include>hapi-fhir-android-${project.version}.jar</include>
|
||||
<include>hapi-fhir-android-${project.version}-dstu.jar</include>
|
||||
<include>hapi-fhir-android-${project.version}-dstu2.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>/lib</outputDirectory>
|
||||
<useProjectArtifact>true</useProjectArtifact>
|
||||
<unpack>false</unpack>
|
||||
<scope>provided</scope>
|
||||
<useTransitiveDependencies>true</useTransitiveDependencies>
|
||||
<useTransitiveFiltering>true</useTransitiveFiltering>
|
||||
<includes>
|
||||
<include>ca.uhn.hapi.fhir:hapi-fhir-android</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>ca.uhn.hapi.fhir:hapi-fhir-base</exclude>
|
||||
<exclude>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</exclude>
|
||||
<exclude>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</exclude>
|
||||
<exclude>ca.uhn.hapi.fhir:hapi-fhir-structures-hl7org-dstu2</exclude>
|
||||
<exclude>ca.uhn.hapi.fhir:hapi-fhir-validation-resources-dstu2</exclude>
|
||||
<exclude>org.glassfish:javax.json</exclude>
|
||||
<exclude>org.codehaus.woodstox:woodstox-core-asl</exclude>
|
||||
<exclude>javax.xml.stream:stax-api</exclude>
|
||||
<exclude>org.codehaus.woodstox:stax2-api</exclude>
|
||||
<exclude>org.glassfish:javax.json</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
|
||||
</assembly>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/test/java">
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src/test/resources"/>
|
||||
<classpathentry kind="src" path="src/main/java">
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src/main/resources"/>
|
||||
<classpathentry kind="src" path="target/generated-sources/tinder"/>
|
||||
<classpathentry kind="src" path="target/generated-resources/tinder">
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/classes" path="target/generated-sources/tinder"/>
|
||||
<classpathentry kind="src" output="target/classes" path="target/generated-resources/tinder">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
|
|
@ -16,26 +16,6 @@
|
|||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder (1).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (2).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
|
|
|
@ -174,8 +174,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
|
||||
|
||||
|
||||
if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.REFERENCE) {
|
||||
continue;
|
||||
}
|
||||
|
@ -193,7 +192,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
String[] nextPathsSplit = nextPathsUnsplit.split("\\|");
|
||||
for (String nextPath : nextPathsSplit) {
|
||||
nextPath = nextPath.trim();
|
||||
|
||||
|
||||
List<Class<? extends IBaseResource>> allowedTypesInField = null;
|
||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject == null) {
|
||||
|
@ -219,7 +218,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
try {
|
||||
resourceDefinition = getContext().getResourceDefinition(typeString);
|
||||
} catch (DataFormatException e) {
|
||||
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Resource type is unknown or not supported on this server - " + nextValue.getReference().getValue());
|
||||
throw new InvalidRequestException(
|
||||
"Invalid resource reference found at path[" + nextPathsUnsplit + "] - Resource type is unknown or not supported on this server - " + nextValue.getReference().getValue());
|
||||
}
|
||||
|
||||
Class<? extends IBaseResource> type = resourceDefinition.getImplementingClass();
|
||||
|
@ -253,15 +253,16 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
String resName = targetResourceDef.getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
|
||||
|
||||
if (!typeString.equals(target.getResourceType())) {
|
||||
throw new UnprocessableEntityException("Resource contains reference to " + nextValue.getReference().getValue() + " but resource with ID " + nextValue.getReference().getIdPart() + " is actually of type " + target.getResourceType());
|
||||
throw new UnprocessableEntityException("Resource contains reference to " + nextValue.getReference().getValue() + " but resource with ID " + nextValue.getReference().getIdPart()
|
||||
+ " is actually of type " + target.getResourceType());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Is the target type an allowable type of resource for the path where it is referenced?
|
||||
*/
|
||||
|
||||
|
||||
if (allowedTypesInField == null) {
|
||||
BaseRuntimeChildDefinition childDef = getContext().newTerser().getDefinition(theResource.getClass(), nextPath);
|
||||
if (childDef instanceof RuntimeChildResourceDefinition) {
|
||||
|
@ -272,19 +273,19 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
allowedTypesInField.add(IBaseResource.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean acceptableLink = false;
|
||||
for(Class<? extends IBaseResource> next : allowedTypesInField) {
|
||||
for (Class<? extends IBaseResource> next : allowedTypesInField) {
|
||||
if (next.isAssignableFrom(targetResourceDef.getImplementingClass())) {
|
||||
acceptableLink = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!acceptableLink) {
|
||||
throw new UnprocessableEntityException("Invalid reference found at path '" + nextPath + "'. Resource type '" + targetResourceDef.getName() + "' is not valid for this path");
|
||||
}
|
||||
|
||||
|
||||
nextEntity = new ResourceLink(nextPath, theEntity, target);
|
||||
} else {
|
||||
if (!multiType) {
|
||||
|
@ -683,11 +684,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method is called when an update to an existing resource detects that the resource supplied for update is
|
||||
* missing a tag/profile/security label that the currently persisted resource holds.
|
||||
* This method is called when an update to an existing resource detects that the resource supplied for update is missing a tag/profile/security label that the currently persisted resource holds.
|
||||
* <p>
|
||||
* The default implementation removes any profile declarations, but leaves tags and security labels in place.
|
||||
* Subclasses may choose to override and change this behaviour.
|
||||
* The default implementation removes any profile declarations, but leaves tags and security labels in place. Subclasses may choose to override and change this behaviour.
|
||||
* </p>
|
||||
*
|
||||
* @param theEntity
|
||||
|
@ -695,8 +694,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
* @param theTag
|
||||
* The tag
|
||||
* @return Retturns <code>true</code> if the tag should be removed
|
||||
* @see <a href="http://hl7.org/fhir/2015Sep/resource.html#1.11.3.7">Updates to Tags, Profiles, and Security
|
||||
* Labels</a> for a description of the logic that the default behaviour folows.
|
||||
* @see <a href="http://hl7.org/fhir/2015Sep/resource.html#1.11.3.7">Updates to Tags, Profiles, and Security Labels</a> for a description of the logic that the default behaviour folows.
|
||||
*/
|
||||
protected boolean shouldDroppedTagBeRemovedOnUpdate(ResourceTable theEntity, ResourceTag theTag) {
|
||||
if (theTag.getTag().getTagType() == TagTypeEnum.PROFILE) {
|
||||
|
@ -709,6 +707,10 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
RuntimeResourceDefinition resourceDef = getContext().getResourceDefinition(theResourceType);
|
||||
|
||||
SearchParameterMap paramMap = translateMatchUrl(theMatchUrl, resourceDef);
|
||||
|
||||
if (paramMap.isEmpty()) {
|
||||
throw new InvalidRequestException("Invalid match URL[" + theMatchUrl + "] - URL has no search parameters");
|
||||
}
|
||||
|
||||
IFhirResourceDao<R> dao = getDao(theResourceType);
|
||||
Set<Long> ids = dao.searchForIdsWithAndOr(paramMap);
|
||||
|
@ -719,23 +721,28 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
public static SearchParameterMap translateMatchUrl(String theMatchUrl, RuntimeResourceDefinition resourceDef) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
List<NameValuePair> parameters;
|
||||
try {
|
||||
String matchUrl = theMatchUrl;
|
||||
if (matchUrl.indexOf('?') == -1) {
|
||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Error was: URL does not contain any parameters ('?' not detected)");
|
||||
}
|
||||
matchUrl = matchUrl.replace("|", "%7C");
|
||||
matchUrl = matchUrl.replace("=>=", "=%3E%3D");
|
||||
matchUrl = matchUrl.replace("=<=", "=%3C%3D");
|
||||
matchUrl = matchUrl.replace("=>", "=%3E");
|
||||
matchUrl = matchUrl.replace("=<", "=%3C");
|
||||
parameters = URLEncodedUtils.parse(new URI(matchUrl), "UTF-8");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Error was: " + e.toString());
|
||||
String matchUrl = theMatchUrl;
|
||||
int questionMarkIndex = matchUrl.indexOf('?');
|
||||
if (questionMarkIndex != -1) {
|
||||
matchUrl = matchUrl.substring(questionMarkIndex + 1);
|
||||
}
|
||||
matchUrl = matchUrl.replace("|", "%7C");
|
||||
matchUrl = matchUrl.replace("=>=", "=%3E%3D");
|
||||
matchUrl = matchUrl.replace("=<=", "=%3C%3D");
|
||||
matchUrl = matchUrl.replace("=>", "=%3E");
|
||||
matchUrl = matchUrl.replace("=<", "=%3C");
|
||||
if (matchUrl.contains(" ")) {
|
||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - URL is invalid (must not contain spaces)");
|
||||
}
|
||||
|
||||
parameters = URLEncodedUtils.parse((matchUrl), Constants.CHARSET_UTF8, '&');
|
||||
|
||||
ArrayListMultimap<String, QualifiedParamList> nameToParamLists = ArrayListMultimap.create();
|
||||
for (NameValuePair next : parameters) {
|
||||
if (isBlank(next.getValue())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String paramName = next.getName();
|
||||
String qualifier = null;
|
||||
for (int i = 0; i < paramMap.size(); i++) {
|
||||
|
@ -779,11 +786,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (nextParamName.startsWith("_")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
RuntimeSearchParam paramDef = resourceDef.getSearchParam(nextParamName);
|
||||
if (paramDef == null) {
|
||||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Resource type " + resourceDef.getName() + " does not have a parameter with name: " + nextParamName);
|
||||
|
@ -1030,8 +1037,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
} else if (theForHistoryOperation) {
|
||||
/*
|
||||
* If the create and update times match, this was when the resource was created
|
||||
* so we should mark it as a POST. Otherwise, it's a PUT.
|
||||
* If the create and update times match, this was when the resource was created so we should mark it as a POST. Otherwise, it's a PUT.
|
||||
*/
|
||||
Date published = theEntity.getPublished().getValue();
|
||||
Date updated = theEntity.getUpdated().getValue();
|
||||
|
@ -1041,7 +1047,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(res, BundleEntryTransactionMethodEnum.PUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
res.setId(theEntity.getIdDt());
|
||||
|
||||
ResourceMetadataKeyEnum.VERSION.put(res, Long.toString(theEntity.getVersion()));
|
||||
|
@ -1125,8 +1131,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ResourceTable updateEntity(final IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion, Date theUpdateTime) {
|
||||
|
||||
protected ResourceTable updateEntity(final IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
boolean theUpdateVersion, Date theUpdateTime) {
|
||||
|
||||
/*
|
||||
* This should be the very first thing..
|
||||
*/
|
||||
|
@ -1134,14 +1141,15 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
validateResourceForStorage((T) theResource, theEntity);
|
||||
String resourceType = myContext.getResourceDefinition(theResource).getName();
|
||||
if (isNotBlank(theEntity.getResourceType()) && !theEntity.getResourceType().equals(resourceType)) {
|
||||
throw new UnprocessableEntityException("Existing resource ID[" + theEntity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + theEntity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
|
||||
throw new UnprocessableEntityException(
|
||||
"Existing resource ID[" + theEntity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + theEntity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
|
||||
}
|
||||
}
|
||||
|
||||
if (theEntity.getPublished() == null) {
|
||||
theEntity.setPublished(theUpdateTime);
|
||||
}
|
||||
|
||||
|
||||
if (theUpdateHistory) {
|
||||
final ResourceHistoryTable historyEntry = theEntity.toHistory();
|
||||
myEntityManager.persist(historyEntry);
|
||||
|
@ -1238,7 +1246,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
theEntity.setResourceLinks(links);
|
||||
theEntity.setHasLinks(links.isEmpty() == false);
|
||||
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
populateResourceIntoEntity(theResource, theEntity);
|
||||
|
@ -1261,7 +1269,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
|
||||
} else {
|
||||
theEntity = myEntityManager.merge(theEntity);
|
||||
|
||||
|
||||
postUpdate(theEntity, (T) theResource);
|
||||
}
|
||||
|
||||
|
@ -1354,37 +1362,37 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override to provide behaviour. Called when a resource has been inserved into the database for the
|
||||
* first time.
|
||||
* Subclasses may override to provide behaviour. Called when a resource has been inserved into the database for the first time.
|
||||
*
|
||||
* @param theEntity
|
||||
* The resource
|
||||
* @param theResource The resource being persisted
|
||||
* @param theResource
|
||||
* The resource being persisted
|
||||
*/
|
||||
protected void postUpdate(ResourceTable theEntity, T theResource) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override to provide behaviour. Called when a resource has been inserved into the database for the
|
||||
* first time.
|
||||
* Subclasses may override to provide behaviour. Called when a resource has been inserved into the database for the first time.
|
||||
*
|
||||
* @param theEntity
|
||||
* The resource
|
||||
* @param theResource The resource being persisted
|
||||
* @param theResource
|
||||
* The resource being persisted
|
||||
*/
|
||||
protected void postPersist(ResourceTable theEntity, T theResource) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked immediately before storing a new resource, or an update to an existing resource to allow
|
||||
* the DAO to ensure that it is valid for persistence. By default, checks for the "subsetted" tag and rejects
|
||||
* resources which have it. Subclasses should call the superclass implementation to preserve this check.
|
||||
* This method is invoked immediately before storing a new resource, or an update to an existing resource to allow the DAO to ensure that it is valid for persistence. By default, checks for the
|
||||
* "subsetted" tag and rejects resources which have it. Subclasses should call the superclass implementation to preserve this check.
|
||||
*
|
||||
* @param theResource
|
||||
* The resource that is about to be persisted
|
||||
* @param theEntityToSave TODO
|
||||
* @param theEntityToSave
|
||||
* TODO
|
||||
*/
|
||||
protected void validateResourceForStorage(T theResource, ResourceTable theEntityToSave) {
|
||||
IResource res = (IResource) theResource;
|
||||
|
|
|
@ -74,6 +74,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
|||
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.BaseTag;
|
||||
|
@ -128,6 +129,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
|
@ -148,6 +150,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
@Autowired
|
||||
private PlatformTransactionManager myPlatformTransactionManager;
|
||||
|
||||
@Autowired
|
||||
private DaoConfig myDaoConfig;
|
||||
|
||||
private String myResourceName;
|
||||
private Class<T> myResourceType;
|
||||
private String mySecondaryPrimaryKeyParamName;
|
||||
|
@ -1308,7 +1313,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
throw new InvalidRequestException("Trying to delete " + theId + " but this is not the current version");
|
||||
}
|
||||
|
||||
validateOkToDeleteOrThrowPreconditionFailedException(entity);
|
||||
validateOkToDeleteOrThrowResourceVersionConflictException(entity);
|
||||
|
||||
// Notify interceptors
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(theId, theId.getResourceType());
|
||||
|
@ -1331,26 +1336,31 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
if (resource.isEmpty()) {
|
||||
throw new ResourceNotFoundException(getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "unableToDeleteNotFound", theUrl));
|
||||
} else if (resource.size() > 1) {
|
||||
throw new ResourceNotFoundException(getContext().getLocalizer().getMessage(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "DELETE", theUrl, resource.size()));
|
||||
if (myDaoConfig.isAllowMultipleDelete() == false) {
|
||||
throw new PreconditionFailedException(getContext().getLocalizer().getMessage(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "DELETE", theUrl, resource.size()));
|
||||
}
|
||||
}
|
||||
|
||||
Long pid = resource.iterator().next();
|
||||
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
|
||||
|
||||
validateOkToDeleteOrThrowPreconditionFailedException(entity);
|
||||
|
||||
// Notify interceptors
|
||||
IdDt idToDelete = entity.getIdDt();
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(idToDelete, idToDelete.getResourceType());
|
||||
notifyInterceptors(RestOperationTypeEnum.DELETE, requestDetails);
|
||||
|
||||
// Perform delete
|
||||
Date updateTime = new Date();
|
||||
ResourceTable savedEntity = updateEntity(null, entity, true, updateTime, updateTime);
|
||||
notifyWriteCompleted();
|
||||
|
||||
ourLog.info("Processed delete on {} in {}ms", theUrl, w.getMillisAndRestart());
|
||||
return toMethodOutcome(savedEntity, null);
|
||||
for (Long pid : resource) {
|
||||
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
|
||||
|
||||
validateOkToDeleteOrThrowResourceVersionConflictException(entity);
|
||||
|
||||
// Notify interceptors
|
||||
IdDt idToDelete = entity.getIdDt();
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(idToDelete, idToDelete.getResourceType());
|
||||
notifyInterceptors(RestOperationTypeEnum.DELETE, requestDetails);
|
||||
|
||||
// Perform delete
|
||||
Date updateTime = new Date();
|
||||
updateEntity(null, entity, true, updateTime, updateTime);
|
||||
notifyWriteCompleted();
|
||||
|
||||
}
|
||||
|
||||
ourLog.info("Processed delete on {} (matched {} resource(s)) in {}ms", new Object[] {theUrl, resource.size(), w.getMillisAndRestart()});
|
||||
|
||||
return new DaoMethodOutcome();
|
||||
}
|
||||
|
||||
private DaoMethodOutcome doCreate(T theResource, String theIfNoneExist, boolean thePerformIndexing, Date theUpdateTime) {
|
||||
|
@ -1615,7 +1625,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
/**
|
||||
* THIS SHOULD RETURN HASHSET and not jsut Set because we add to it later (so it can't be Collections.emptySet())
|
||||
*/
|
||||
private HashSet<Long> loadReverseIncludes(Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode) {
|
||||
private HashSet<Long> loadReverseIncludes(Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode, EverythingModeEnum theEverythingModeEnum) {
|
||||
if (theMatches.size() == 0) {
|
||||
return new HashSet<Long>();
|
||||
}
|
||||
|
@ -1632,6 +1642,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
boolean addedSomeThisRound;
|
||||
do {
|
||||
HashSet<Long> pidsToInclude = new HashSet<Long>();
|
||||
Set<Long> nextRoundOmit = new HashSet<Long>();
|
||||
|
||||
for (Iterator<Include> iter = includes.iterator(); iter.hasNext();) {
|
||||
Include nextInclude = iter.next();
|
||||
|
@ -1648,6 +1659,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
List<ResourceLink> results = q.getResultList();
|
||||
for (ResourceLink resourceLink : results) {
|
||||
if (theReverseMode) {
|
||||
if (theEverythingModeEnum == EverythingModeEnum.ENCOUNTER) {
|
||||
if (resourceLink.getSourcePath().equals("Encounter.subject") || resourceLink.getSourcePath().equals("Encounter.patient")) {
|
||||
nextRoundOmit.add(resourceLink.getSourceResourcePid());
|
||||
}
|
||||
}
|
||||
pidsToInclude.add(resourceLink.getSourceResourcePid());
|
||||
} else {
|
||||
pidsToInclude.add(resourceLink.getTargetResourcePid());
|
||||
|
@ -1702,6 +1718,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
theMatches.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
pidsToInclude.removeAll(nextRoundOmit);
|
||||
|
||||
addedSomeThisRound = allAdded.addAll(pidsToInclude);
|
||||
nextRoundMatches = pidsToInclude;
|
||||
} while (includes.size() > 0 && nextRoundMatches.size() > 0 && addedSomeThisRound);
|
||||
|
@ -2024,10 +2043,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
// Load _include and _revinclude before filter and sort in everything mode
|
||||
if (theParams.isEverythingMode() == true) {
|
||||
if (theParams.getEverythingMode() != null) {
|
||||
if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
|
||||
loadPids.addAll(loadReverseIncludes(loadPids, theParams.getRevIncludes(), true));
|
||||
loadPids.addAll(loadReverseIncludes(loadPids, theParams.getIncludes(), false));
|
||||
loadPids.addAll(loadReverseIncludes(loadPids, theParams.getRevIncludes(), true, theParams.getEverythingMode()));
|
||||
loadPids.addAll(loadReverseIncludes(loadPids, theParams.getIncludes(), false, theParams.getEverythingMode()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2066,9 +2085,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
|
||||
// Load _revinclude resources
|
||||
final Set<Long> revIncludedPids;
|
||||
if (theParams.isEverythingMode() == false) {
|
||||
if (theParams.getEverythingMode() == null) {
|
||||
if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
|
||||
revIncludedPids = loadReverseIncludes(pids, theParams.getRevIncludes(), true);
|
||||
revIncludedPids = loadReverseIncludes(pids, theParams.getRevIncludes(), true, null);
|
||||
} else {
|
||||
revIncludedPids = new HashSet<Long>();
|
||||
}
|
||||
|
@ -2095,9 +2114,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
List<Long> pidsSubList = pids.subList(theFromIndex, theToIndex);
|
||||
|
||||
// Load includes
|
||||
if (!theParams.isEverythingMode()) {
|
||||
if (theParams.getEverythingMode()==null) {
|
||||
pidsSubList = new ArrayList<Long>(pidsSubList);
|
||||
revIncludedPids.addAll(loadReverseIncludes(pidsSubList, theParams.getIncludes(), false));
|
||||
revIncludedPids.addAll(loadReverseIncludes(pidsSubList, theParams.getIncludes(), false, null));
|
||||
}
|
||||
|
||||
// Execute the query and make sure we return distinct results
|
||||
|
@ -2502,7 +2521,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
}
|
||||
|
||||
protected void validateOkToDeleteOrThrowPreconditionFailedException(ResourceTable theEntity) {
|
||||
protected void validateOkToDeleteOrThrowResourceVersionConflictException(ResourceTable theEntity) {
|
||||
TypedQuery<ResourceLink> query = myEntityManager.createQuery("SELECT l FROM ResourceLink l WHERE l.myTargetResourcePid = :target_pid", ResourceLink.class);
|
||||
query.setParameter("target_pid", theEntity.getId());
|
||||
query.setMaxResults(1);
|
||||
|
@ -2516,7 +2535,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
String sourceId = link.getSourceResource().getIdDt().toUnqualifiedVersionless().getValue();
|
||||
String sourcePath = link.getSourcePath();
|
||||
|
||||
throw new PreconditionFailedException(
|
||||
throw new ResourceVersionConflictException(
|
||||
"Unable to delete " + targetId + " because at least one resource has a reference to this resource. First reference found was resource " + sourceId + " in path " + sourcePath);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
|
||||
public class DaoConfig {
|
||||
|
||||
private boolean myAllowMultipleDelete;
|
||||
private int myHardSearchLimit = 1000;
|
||||
private int myHardTagListLimit = 1000;
|
||||
private int myIncludeLimit = 2000;
|
||||
|
@ -74,6 +75,14 @@ public class DaoConfig {
|
|||
return mySubscriptionPollDelay;
|
||||
}
|
||||
|
||||
public Long getSubscriptionPurgeInactiveAfterMillis() {
|
||||
return mySubscriptionPurgeInactiveAfterMillis;
|
||||
}
|
||||
|
||||
public boolean isAllowMultipleDelete() {
|
||||
return myAllowMultipleDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #setSubscriptionEnabled(boolean)}
|
||||
*/
|
||||
|
@ -81,6 +90,10 @@ public class DaoConfig {
|
|||
return mySubscriptionEnabled;
|
||||
}
|
||||
|
||||
public void setAllowMultipleDelete(boolean theAllowMultipleDelete) {
|
||||
myAllowMultipleDelete = theAllowMultipleDelete;
|
||||
}
|
||||
|
||||
public void setHardSearchLimit(int theHardSearchLimit) {
|
||||
myHardSearchLimit = theHardSearchLimit;
|
||||
}
|
||||
|
@ -144,10 +157,6 @@ public class DaoConfig {
|
|||
mySubscriptionPollDelay = theSubscriptionPollDelay;
|
||||
}
|
||||
|
||||
public void setSubscriptionPurgeInactiveAfterSeconds(int theSeconds) {
|
||||
setSubscriptionPurgeInactiveAfterMillis(theSeconds * DateUtils.MILLIS_PER_SECOND);
|
||||
}
|
||||
|
||||
public void setSubscriptionPurgeInactiveAfterMillis(Long theMillis) {
|
||||
if (theMillis != null) {
|
||||
Validate.exclusiveBetween(0, Long.MAX_VALUE, theMillis);
|
||||
|
@ -155,8 +164,8 @@ public class DaoConfig {
|
|||
mySubscriptionPurgeInactiveAfterMillis = theMillis;
|
||||
}
|
||||
|
||||
public Long getSubscriptionPurgeInactiveAfterMillis() {
|
||||
return mySubscriptionPurgeInactiveAfterMillis;
|
||||
public void setSubscriptionPurgeInactiveAfterSeconds(int theSeconds) {
|
||||
setSubscriptionPurgeInactiveAfterMillis(theSeconds * DateUtils.MILLIS_PER_SECOND);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
|||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
import ca.uhn.fhir.validation.DefaultProfileValidationSupport;
|
||||
|
@ -105,11 +106,11 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
|
|||
final ResourceTable entity = readEntityLatestVersion(theId);
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
try {
|
||||
validateOkToDeleteOrThrowPreconditionFailedException(entity);
|
||||
validateOkToDeleteOrThrowResourceVersionConflictException(entity);
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.INFORMATION).setDiagnostics("Ok to delete");
|
||||
} catch (PreconditionFailedException e) {
|
||||
} catch (ResourceVersionConflictException e) {
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.ERROR).setDiagnostics(e.getMessage());
|
||||
throw new PreconditionFailedException(e.getMessage(), oo);
|
||||
throw new ResourceVersionConflictException(e.getMessage(), oo);
|
||||
}
|
||||
return new MethodOutcome(new IdDt(theId.getValue()), oo);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public class FhirResourceDaoEncounterDstu2 extends FhirResourceDaoDstu2<Encounter>implements IFhirResourceDaoEncounter<Encounter> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(EverythingModeEnum.ENCOUNTER);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
if (theId != null) {
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
}
|
||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = search(paramMap);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return encounterInstanceEverything(theServletRequest, null, theCount, theLastUpdated, theSort);
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -36,7 +37,7 @@ import ca.uhn.fhir.rest.server.IBundleProvider;
|
|||
public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>implements IFhirResourceDaoPatient<Patient> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider everything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
|
@ -44,12 +45,19 @@ public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>im
|
|||
|
||||
paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(true);
|
||||
paramMap.setEverythingMode(EverythingModeEnum.PATIENT);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
if (theId != null) {
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
}
|
||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = search(paramMap);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
return patientInstanceEverything(theServletRequest, null, theCount, theLastUpdated, theSort);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ import javax.annotation.PostConstruct;
|
|||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
|
@ -41,7 +43,10 @@ import ca.uhn.fhir.validation.ValidationResult;
|
|||
|
||||
public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDstu2<QuestionnaireResponse> {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myFhirContextDstu2Hl7Org")
|
||||
private FhirContext myRefImplCtx;
|
||||
|
||||
private Boolean myValidateResponses;
|
||||
|
||||
/**
|
||||
|
@ -52,7 +57,6 @@ public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDs
|
|||
try {
|
||||
Class.forName("org.hl7.fhir.instance.model.QuestionnaireResponse");
|
||||
myValidateResponses = true;
|
||||
myRefImplCtx = FhirContext.forDstu2Hl7Org();
|
||||
} catch (ClassNotFoundException e) {
|
||||
myValidateResponses = Boolean.FALSE;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
|
@ -129,7 +130,8 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
ourLog.trace("Skipping search for subscription");
|
||||
return;
|
||||
}
|
||||
ourLog.info("Subscription search from {} to {}", start, end);
|
||||
|
||||
ourLog.debug("Subscription {} search from {} to {}", new Object[] { subscription.getId().getIdPart(), new InstantDt(new Date(start)), new InstantDt(new Date(end)) });
|
||||
|
||||
DateRangeParam range = new DateRangeParam();
|
||||
range.setLowerBound(new DateParam(QuantityCompararatorEnum.GREATERTHAN, start));
|
||||
|
@ -176,7 +178,8 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ResourceTable updateEntity(IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion, Date theUpdateTime) {
|
||||
protected ResourceTable updateEntity(IResource theResource, ResourceTable theEntity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
|
||||
Date theUpdateTime) {
|
||||
ResourceTable retVal = super.updateEntity(theResource, theEntity, theUpdateHistory, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime);
|
||||
|
||||
Subscription resource = (Subscription) theResource;
|
||||
|
@ -278,16 +281,17 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
@Override
|
||||
public void purgeInactiveSubscriptions() {
|
||||
Long purgeInactiveAfterMillis = getConfig().getSubscriptionPurgeInactiveAfterMillis();
|
||||
if (getConfig().isSubscriptionEnabled()==false || purgeInactiveAfterMillis == null) {
|
||||
if (getConfig().isSubscriptionEnabled() == false || purgeInactiveAfterMillis == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Date cutoff = new Date(System.currentTimeMillis() - purgeInactiveAfterMillis);
|
||||
Collection<SubscriptionTable> toPurge = mySubscriptionTableDao.findInactiveBeforeCutoff(cutoff);
|
||||
for (SubscriptionTable subscriptionTable : toPurge) {
|
||||
|
||||
final IdDt subscriptionId = subscriptionTable.getSubscriptionResource().getIdDt();
|
||||
ourLog.info("Deleting inactive subscription {} - Created {}, last client poll {}", new Object[] { subscriptionId.toUnqualified(), subscriptionTable.getCreated(), subscriptionTable.getLastClientPoll() });
|
||||
ourLog.info("Deleting inactive subscription {} - Created {}, last client poll {}",
|
||||
new Object[] { subscriptionId.toUnqualified(), subscriptionTable.getCreated(), subscriptionTable.getLastClientPoll() });
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
|
|
|
@ -28,10 +28,15 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.apache.commons.codec.binary.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||
|
@ -46,32 +51,83 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.validation.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.validation.ValidationSupportChain;
|
||||
|
||||
public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>implements IFhirResourceDaoValueSet<ValueSet> {
|
||||
|
||||
@Override
|
||||
public ValueSet expand(IIdType theId, StringDt theFilter) {
|
||||
ValueSet retVal = new ValueSet();
|
||||
retVal.setDate(DateTimeDt.withCurrentTime());
|
||||
@Autowired
|
||||
private IJpaValidationSupport myJpaValidationSupport;
|
||||
|
||||
private ValidationSupportChain myValidationSupport;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myFhirContextDstu2Hl7Org")
|
||||
private FhirContext myRiCtx;
|
||||
|
||||
private DefaultProfileValidationSupport myDefaultProfileValidationSupport;
|
||||
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
super.postConstruct();
|
||||
myDefaultProfileValidationSupport = new DefaultProfileValidationSupport();
|
||||
myValidationSupport = new ValidationSupportChain(myDefaultProfileValidationSupport, myJpaValidationSupport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet expand(IIdType theId, String theFilter) {
|
||||
BaseHasResource sourceEntity = readEntity(theId);
|
||||
if (sourceEntity == null) {
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
ValueSet source = (ValueSet) toResource(sourceEntity, false);
|
||||
|
||||
return expand(source, theFilter);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet expandByIdentifier(String theUri, String theFilter) {
|
||||
if (isBlank(theUri)) {
|
||||
throw new InvalidRequestException("URI must not be blank or missing");
|
||||
}
|
||||
ValueSet source;
|
||||
|
||||
org.hl7.fhir.instance.model.ValueSet defaultValueSet = myDefaultProfileValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theUri);
|
||||
if (defaultValueSet != null) {
|
||||
source = getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(defaultValueSet));
|
||||
} else {
|
||||
IBundleProvider ids = search(ValueSet.SP_URL, new UriParam(theUri));
|
||||
if (ids.size() == 0) {
|
||||
throw new InvalidRequestException("Unknown ValueSet URI: " + theUri);
|
||||
}
|
||||
source = (ValueSet) ids.getResources(0, 1).get(0);
|
||||
}
|
||||
|
||||
return expand(source, theFilter);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet expand(ValueSet source, String theFilter) {
|
||||
ValueSet retVal = new ValueSet();
|
||||
retVal.setDate(DateTimeDt.withCurrentTime());
|
||||
|
||||
/*
|
||||
* Add composed concepts
|
||||
*/
|
||||
|
||||
for (ComposeInclude nextInclude : source.getCompose().getInclude()) {
|
||||
for (ComposeIncludeConcept next : nextInclude.getConcept()) {
|
||||
if (theFilter == null || theFilter.isEmpty()) {
|
||||
if (isBlank(theFilter)) {
|
||||
addCompose(retVal, nextInclude.getSystem(), next.getCode(), next.getDisplay());
|
||||
} else {
|
||||
String filter = theFilter.getValue().toLowerCase();
|
||||
String filter = theFilter.toLowerCase();
|
||||
if (next.getDisplay().toLowerCase().contains(filter) || next.getCode().toLowerCase().contains(filter)) {
|
||||
addCompose(retVal, nextInclude.getSystem(), next.getCode(), next.getDisplay());
|
||||
}
|
||||
|
@ -88,14 +144,13 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
|
|||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
}
|
||||
|
||||
private void addCompose(StringDt theFilter, ValueSet theValueSetToPopulate, ValueSet theSourceValueSet, CodeSystemConcept theConcept) {
|
||||
if (theFilter == null || theFilter.isEmpty()) {
|
||||
private void addCompose(String theFilter, ValueSet theValueSetToPopulate, ValueSet theSourceValueSet, CodeSystemConcept theConcept) {
|
||||
if (isBlank(theFilter)) {
|
||||
addCompose(theValueSetToPopulate, theSourceValueSet.getCodeSystem().getSystem(), theConcept.getCode(), theConcept.getDisplay());
|
||||
} else {
|
||||
String filter = theFilter.getValue().toLowerCase();
|
||||
String filter = theFilter.toLowerCase();
|
||||
if (theConcept.getDisplay().toLowerCase().contains(filter) || theConcept.getCode().toLowerCase().contains(filter)) {
|
||||
addCompose(theValueSetToPopulate, theSourceValueSet.getCodeSystem().getSystem(), theConcept.getCode(), theConcept.getDisplay());
|
||||
}
|
||||
|
@ -133,7 +188,7 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
|
|||
|
||||
boolean haveIdentifierParam = theValueSetIdentifier != null && theValueSetIdentifier.isEmpty() == false;
|
||||
if (theId != null) {
|
||||
valueSetIds = Collections.singletonList((IIdType) theId);
|
||||
valueSetIds = Collections.singletonList(theId);
|
||||
} else if (haveIdentifierParam) {
|
||||
Set<Long> ids = searchForIds(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue()));
|
||||
valueSetIds = new ArrayList<IIdType>();
|
||||
|
|
|
@ -222,6 +222,17 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle> {
|
|||
if (res != null) {
|
||||
|
||||
nextResourceId = res.getId();
|
||||
|
||||
if (nextResourceId.hasIdPart() == false) {
|
||||
if (isNotBlank(nextEntry.getFullUrl())) {
|
||||
nextResourceId = new IdDt(nextEntry.getFullUrl());
|
||||
}
|
||||
}
|
||||
|
||||
if (nextResourceId.hasIdPart() && nextResourceId.getIdPart().matches("[a-zA-Z]+\\:.*") && !isPlaceholder(nextResourceId)) {
|
||||
throw new InvalidRequestException("Invalid placeholder ID found: " + nextResourceId.getIdPart() + " - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'");
|
||||
}
|
||||
|
||||
if (nextResourceId.hasIdPart() && !nextResourceId.hasResourceType() && !isPlaceholder(nextResourceId)) {
|
||||
nextResourceId = new IdDt(toResourceName(res.getClass()), nextResourceId.getIdPart());
|
||||
res.setId(nextResourceId);
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public interface IFhirResourceDaoEncounter<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdate, SortSpec theSort);
|
||||
|
||||
IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSortSpec);
|
||||
|
||||
}
|
|
@ -32,6 +32,8 @@ import ca.uhn.fhir.rest.server.IBundleProvider;
|
|||
|
||||
public interface IFhirResourceDaoPatient<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider everything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdate, SortSpec theSort);
|
||||
IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdate, SortSpec theSort);
|
||||
|
||||
IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSortSpec);
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,12 @@ import ca.uhn.fhir.model.primitive.UriDt;
|
|||
|
||||
public interface IFhirResourceDaoValueSet<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
ValueSet expand(IIdType theId, StringDt theFilter);
|
||||
ValueSet expand(IIdType theId, String theFilter);
|
||||
|
||||
ValueSet expand(ValueSet theSource, String theFilter);
|
||||
|
||||
ValueSet expandByIdentifier(String theUri, String theFilter);
|
||||
|
||||
ValidateCodeResult validateCode(UriDt theValueSetIdentifier, IIdType theId, CodeDt theCode, UriDt theSystem, StringDt theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept);
|
||||
|
||||
public class ValidateCodeResult {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.validation.IValidationSupport;
|
||||
|
||||
public interface IJpaValidationSupport extends IValidationSupport {
|
||||
|
||||
}
|
|
@ -30,13 +30,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.validation.IValidationSupport;
|
||||
|
||||
public class JpaValidationSupportDstu2 implements IValidationSupport {
|
||||
public class JpaValidationSupportDstu2 implements IJpaValidationSupport {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaValidationSupportDstu2.class);
|
||||
|
||||
private FhirContext myRiCtx = FhirContext.forDstu2Hl7Org();
|
||||
@Autowired
|
||||
@Qualifier("myFhirContextDstu2Hl7Org")
|
||||
private FhirContext myRiCtx;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myStructureDefinitionDaoDstu2")
|
||||
|
|
|
@ -52,6 +52,7 @@ import ca.uhn.fhir.jpa.entity.ResourceTable;
|
|||
import ca.uhn.fhir.model.api.IDatatype;
|
||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
|
||||
import ca.uhn.fhir.model.base.composite.BaseHumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.AddressDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.BoundCodeableConceptDt;
|
||||
|
@ -71,6 +72,7 @@ import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
|||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.RestfulSecurityServiceEnum;
|
||||
import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
|
@ -79,7 +81,7 @@ import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
|||
public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implements ISearchParamExtractor {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamExtractorDstu2.class);
|
||||
|
||||
|
||||
public SearchParamExtractorDstu2(FhirContext theContext) {
|
||||
super(theContext);
|
||||
}
|
||||
|
@ -115,7 +117,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -175,7 +178,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public HashSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -222,12 +226,17 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
nextValue = newValue;
|
||||
|
||||
/*
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<? extends org.unitsofmeasurement.quantity.Quantity<?>> unit = (PhysicsUnit<? extends org.unitsofmeasurement.quantity.Quantity<?>>)
|
||||
* UCUMFormat.getCaseInsensitiveInstance().parse(nextValue.getCode().getValue(), null); if (unit.isCompatible(UCUM.DAY)) {
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<? extends
|
||||
* org.unitsofmeasurement.quantity.Quantity<?>> unit = (PhysicsUnit<? extends
|
||||
* org.unitsofmeasurement.quantity.Quantity<?>>)
|
||||
* UCUMFormat.getCaseInsensitiveInstance().parse(nextValue.getCode().getValue(), null); if
|
||||
* (unit.isCompatible(UCUM.DAY)) {
|
||||
*
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<org.unitsofmeasurement.quantity.Time> timeUnit = (PhysicsUnit<Time>) unit; UnitConverter conv = timeUnit.getConverterTo(UCUM.DAY);
|
||||
* double dayValue = conv.convert(nextValue.getValue().getValue().doubleValue()); DurationDt newValue = new DurationDt(); newValue.setSystem(UCUM_NS);
|
||||
* newValue.setCode(UCUM.DAY.getSymbol()); newValue.setValue(dayValue); nextValue=newValue; }
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<org.unitsofmeasurement.quantity.Time> timeUnit =
|
||||
* (PhysicsUnit<Time>) unit; UnitConverter conv = timeUnit.getConverterTo(UCUM.DAY); double
|
||||
* dayValue = conv.convert(nextValue.getValue().getValue().doubleValue()); DurationDt newValue =
|
||||
* new DurationDt(); newValue.setSystem(UCUM_NS); newValue.setCode(UCUM.DAY.getSymbol());
|
||||
* newValue.setValue(dayValue); nextValue=newValue; }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +278,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -303,8 +313,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
continue;
|
||||
}
|
||||
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(resourceName, nextValue.getValueElement().getValue(),
|
||||
nextValue.getSystemElement().getValueAsString(), nextValue.getCode());
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(resourceName, nextValue.getValueElement().getValue(), nextValue.getSystemElement().getValueAsString(), nextValue.getCode());
|
||||
nextEntity.setResource(theEntity);
|
||||
retVal.add(nextEntity);
|
||||
} else {
|
||||
|
@ -323,7 +332,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -404,7 +414,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -464,11 +475,11 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
systems.add(system);
|
||||
codes.add(value);
|
||||
}
|
||||
|
||||
|
||||
if (isNotBlank(nextValue.getType().getText())) {
|
||||
addStringParam(theEntity, retVal, nextSpDef, nextValue.getType().getText());
|
||||
}
|
||||
|
||||
|
||||
} else if (nextObject instanceof ContactPointDt) {
|
||||
ContactPointDt nextValue = (ContactPointDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
|
@ -481,6 +492,14 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
systems.add(nextValue.getSystemElement().getValueAsString());
|
||||
codes.add(nextValue.getValueElement().getValue());
|
||||
} else if (nextObject instanceof BoundCodeDt) {
|
||||
BoundCodeDt<?> obj = (BoundCodeDt<?>) nextObject;
|
||||
String system = extractSystem(obj);
|
||||
String code = obj.getValue();
|
||||
if (isNotBlank(code)) {
|
||||
systems.add(system);
|
||||
codes.add(code);
|
||||
}
|
||||
} else if (nextObject instanceof IPrimitiveDatatype<?>) {
|
||||
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
|
@ -503,7 +522,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
|
||||
extractTokensFromCodeableConcept(systems, codes, nextCC, theEntity, retVal, nextSpDef);
|
||||
} else if (nextObject instanceof RestSecurity) {
|
||||
// Conformance.security search param points to something kind of useless right now - This should probably be fixed.
|
||||
// Conformance.security search param points to something kind of useless right now - This should probably
|
||||
// be fixed.
|
||||
RestSecurity sec = (RestSecurity) nextObject;
|
||||
for (BoundCodeableConceptDt<RestfulSecurityServiceEnum> nextCC : sec.getService()) {
|
||||
extractTokensFromCodeableConcept(systems, codes, nextCC, theEntity, retVal, nextSpDef);
|
||||
|
@ -588,9 +608,9 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
ourLog.trace("Adding param: {}, {}", resourceName, nextValue.getValue());
|
||||
|
||||
|
||||
ResourceIndexedSearchParamUri nextEntity = new ResourceIndexedSearchParamUri(resourceName, nextValue.getValue());
|
||||
|
||||
|
||||
nextEntity.setResource(theEntity);
|
||||
retVal.add(nextEntity);
|
||||
} else {
|
||||
|
@ -605,17 +625,14 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConceptDt theCodeableConcept, ResourceTable theEntity,
|
||||
Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
|
||||
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConceptDt theCodeableConcept, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
for (CodingDt nextCoding : theCodeableConcept.getCoding()) {
|
||||
extractTokensFromCoding(theSystems, theCodes, theEntity, theListToPopulate, theParameterDef, nextCoding);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate,
|
||||
RuntimeSearchParam theParameterDef, CodingDt nextCoding) {
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef, CodingDt nextCoding) {
|
||||
if (nextCoding != null && !nextCoding.isEmpty()) {
|
||||
|
||||
String nextSystem = nextCoding.getSystemElement().getValueAsString();
|
||||
|
@ -632,4 +649,12 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
}
|
||||
|
||||
private static <T extends Enum<?>> String extractSystem(BoundCodeDt<T> theBoundCode) {
|
||||
if (theBoundCode.getValueAsEnum() != null) {
|
||||
IValueSetEnumBinder<T> binder = theBoundCode.getBinder();
|
||||
return binder.toSystemString(theBoundCode.getValueAsEnum());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer myCount;
|
||||
private boolean myEverythingMode = false;
|
||||
private EverythingModeEnum myEverythingMode = null;
|
||||
private Set<Include> myIncludes;
|
||||
private DateRangeParam myLastUpdated;
|
||||
private Set<Include> myRevIncludes;
|
||||
|
@ -124,7 +124,7 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
return mySort;
|
||||
}
|
||||
|
||||
public boolean isEverythingMode() {
|
||||
public EverythingModeEnum getEverythingMode() {
|
||||
return myEverythingMode;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
myCount = theCount;
|
||||
}
|
||||
|
||||
public void setEverythingMode(boolean theConsolidateMatches) {
|
||||
public void setEverythingMode(EverythingModeEnum theConsolidateMatches) {
|
||||
myEverythingMode = theConsolidateMatches;
|
||||
}
|
||||
|
||||
|
@ -164,4 +164,8 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
public enum EverythingModeEnum {
|
||||
PATIENT, ENCOUNTER
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,45 +20,79 @@ package ca.uhn.fhir.jpa.provider;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoEncounter;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class BaseJpaResourceProviderEncounterDstu2 extends JpaResourceProviderDstu2<Encounter> {
|
||||
|
||||
/**
|
||||
* Encounter/123/$everything
|
||||
*/
|
||||
//@formatter:off
|
||||
@Operation(name = "everything", idempotent = true)
|
||||
public ca.uhn.fhir.rest.server.IBundleProvider EncounterInstanceEverything(
|
||||
|
||||
@Operation(name="everything", idempotent=true)
|
||||
public ca.uhn.fhir.rest.server.IBundleProvider everything(
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
@IdParam ca.uhn.fhir.model.primitive.IdDt theId,
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
|
||||
@IdParam
|
||||
ca.uhn.fhir.model.primitive.IdDt theId,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name="_count") ca.uhn.fhir.model.primitive.UnsignedIntDt theCount
|
||||
){
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec
|
||||
) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(true);
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap);
|
||||
return retVal;
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}}
|
||||
|
||||
/**
|
||||
* /Encounter/$everything
|
||||
*/
|
||||
//@formatter:off
|
||||
@Operation(name = "everything", idempotent = true)
|
||||
public ca.uhn.fhir.rest.server.IBundleProvider EncounterTypeEverything(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec
|
||||
) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,13 @@ import ca.uhn.fhir.rest.server.Constants;
|
|||
|
||||
public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu2<Patient> {
|
||||
|
||||
|
||||
/**
|
||||
* Patient/123/$everything
|
||||
*/
|
||||
//@formatter:off
|
||||
@Operation(name = "everything", idempotent = true)
|
||||
public ca.uhn.fhir.rest.server.IBundleProvider everything(
|
||||
public ca.uhn.fhir.rest.server.IBundleProvider patientInstanceEverything(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
|
||||
|
@ -49,17 +54,46 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
// @OperationParam(name = Constants.PARAM_SORT, min=0, max=1)
|
||||
@Sort
|
||||
SortSpec theSortSpec
|
||||
) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>)getDao()).everything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
return ((IFhirResourceDaoPatient<Patient>)getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}}
|
||||
|
||||
/**
|
||||
* /Patient/$everything
|
||||
*/
|
||||
//@formatter:off
|
||||
@Operation(name = "everything", idempotent = true)
|
||||
public ca.uhn.fhir.rest.server.IBundleProvider patientTypeEverything(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@Sort
|
||||
SortSpec theSortSpec
|
||||
) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>)getDao()).patientTypeEverything(theServletRequest, theCount, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -45,19 +45,63 @@ public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDst
|
|||
@Operation(name = "$expand", idempotent = true)
|
||||
public ValueSet everything(
|
||||
HttpServletRequest theServletRequest,
|
||||
@IdParam IdDt theId,
|
||||
@OperationParam(name = "filter") StringDt theFilter) {
|
||||
|
||||
@IdParam IdDt theId,
|
||||
|
||||
@OperationParam(name = "filter", min=0, max=1) StringDt theFilter) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
IFhirResourceDaoValueSet<ValueSet> dao = (IFhirResourceDaoValueSet<ValueSet>) getDao();
|
||||
return dao.expand(theId, theFilter);
|
||||
return dao.expand(theId, toFilterString(theFilter));
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name = "$expand", idempotent = true)
|
||||
public ValueSet everything(
|
||||
HttpServletRequest theServletRequest,
|
||||
|
||||
@OperationParam(name="identifier", min=1, max=1) UriDt theIdentifier,
|
||||
|
||||
@OperationParam(name = "filter", min=0, max=1) StringDt theFilter) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
IFhirResourceDaoValueSet<ValueSet> dao = (IFhirResourceDaoValueSet<ValueSet>) getDao();
|
||||
return dao.expandByIdentifier(theIdentifier.getValue(), toFilterString(theFilter));
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name = "$expand", idempotent = true)
|
||||
public ValueSet everything(
|
||||
HttpServletRequest theServletRequest,
|
||||
|
||||
@OperationParam(name="valueSet", min=1, max=1) ValueSet theValueSet,
|
||||
|
||||
@OperationParam(name = "filter", min=0, max=1) StringDt theFilter) {
|
||||
//@formatter:on
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
IFhirResourceDaoValueSet<ValueSet> dao = (IFhirResourceDaoValueSet<ValueSet>) getDao();
|
||||
return dao.expand(theValueSet, toFilterString(theFilter));
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private String toFilterString(StringDt theFilter) {
|
||||
return theFilter != null ? theFilter.getValue() : null;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name = "$validate-code", idempotent = true, returnParameters= {
|
||||
@OperationParam(name="result", type=BooleanDt.class, min=1),
|
||||
|
|
|
@ -28,12 +28,14 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance.Rest;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance.RestResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance.RestResourceSearchParam;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ConditionalDeleteStatusEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SearchParamTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||
|
@ -48,11 +50,13 @@ public class JpaConformanceProviderDstu2 extends ServerConformanceProvider {
|
|||
private IFhirSystemDao<Bundle> mySystemDao;
|
||||
private volatile Conformance myCachedValue;
|
||||
private RestfulServer myRestfulServer;
|
||||
private DaoConfig myDaoConfig;
|
||||
|
||||
public JpaConformanceProviderDstu2(RestfulServer theRestfulServer, IFhirSystemDao<Bundle> theSystemDao) {
|
||||
public JpaConformanceProviderDstu2(RestfulServer theRestfulServer, IFhirSystemDao<Bundle> theSystemDao, DaoConfig theDaoConfig) {
|
||||
super(theRestfulServer);
|
||||
myRestfulServer = theRestfulServer;
|
||||
mySystemDao = theSystemDao;
|
||||
myDaoConfig = theDaoConfig;
|
||||
super.setCache(false);
|
||||
}
|
||||
|
||||
|
@ -63,17 +67,23 @@ public class JpaConformanceProviderDstu2 extends ServerConformanceProvider {
|
|||
Map<String, Long> counts = mySystemDao.getResourceCounts();
|
||||
|
||||
FhirContext ctx = myRestfulServer.getFhirContext();
|
||||
|
||||
|
||||
retVal = super.getServerConformance(theRequest);
|
||||
for (Rest nextRest : retVal.getRest()) {
|
||||
|
||||
for (RestResource nextResource : nextRest.getResource()) {
|
||||
|
||||
ConditionalDeleteStatusEnum conditionalDelete = nextResource.getConditionalDeleteElement().getValueAsEnum();
|
||||
if (conditionalDelete == ConditionalDeleteStatusEnum.MULTIPLE_DELETES_SUPPORTED && myDaoConfig.isAllowMultipleDelete() == false) {
|
||||
nextResource.setConditionalDelete(ConditionalDeleteStatusEnum.SINGLE_DELETES_SUPPORTED);
|
||||
}
|
||||
|
||||
// Add resource counts
|
||||
Long count = counts.get(nextResource.getTypeElement().getValueAsString());
|
||||
if (count != null) {
|
||||
nextResource.addUndeclaredExtension(false, ExtensionConstants.CONF_RESOURCE_COUNT, new DecimalDt(count));
|
||||
}
|
||||
|
||||
|
||||
// Add chained params
|
||||
for (RestResourceSearchParam nextParam : nextResource.getSearchParam()) {
|
||||
if (nextParam.getTypeElement().getValueAsEnum() == SearchParamTypeEnum.REFERENCE) {
|
||||
|
@ -86,7 +96,7 @@ public class JpaConformanceProviderDstu2 extends ServerConformanceProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,8 +69,8 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
|||
}
|
||||
}
|
||||
|
||||
@Delete
|
||||
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdDt theResource, @ConditionalUrlParam String theConditional) {
|
||||
@Delete()
|
||||
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdDt theResource, @ConditionalUrlParam(supportsMultiple=true) String theConditional) {
|
||||
startRequest(theRequest);
|
||||
try {
|
||||
if (theConditional != null) {
|
||||
|
|
|
@ -103,6 +103,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
@PersistenceContext()
|
||||
protected EntityManager myEntityManager;
|
||||
@Autowired
|
||||
@Qualifier("myFhirContextDstu2")
|
||||
protected FhirContext myFhirCtx;
|
||||
@Autowired
|
||||
@Qualifier("myImmunizationDaoDstu2")
|
||||
|
@ -151,7 +152,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
protected PlatformTransactionManager myTxManager;
|
||||
@Autowired
|
||||
@Qualifier("myValueSetDaoDstu2")
|
||||
protected IFhirResourceDao<ValueSet> myValueSetDao;
|
||||
protected IFhirResourceDaoValueSet<ValueSet> myValueSetDao;
|
||||
|
||||
@Before
|
||||
public void beforeCreateInterceptor() {
|
||||
|
|
|
@ -1,17 +1,32 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
|
||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public class BaseJpaTest {
|
||||
|
||||
public static String loadClasspath(String resource) throws IOException {
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream(resource);
|
||||
if (bundleRes == null) {
|
||||
throw new NullPointerException("Can not load " + resource);
|
||||
}
|
||||
String bundleStr = IOUtils.toString(bundleRes);
|
||||
return bundleStr;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassShutdownDerby() throws SQLException {
|
||||
// try {
|
||||
|
@ -35,6 +50,16 @@ public class BaseJpaTest {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
protected List<IIdType> toUnqualifiedVersionlessIds(Bundle theFound) {
|
||||
List<IIdType> retVal = new ArrayList<IIdType>();
|
||||
for (Entry next : theFound.getEntry()) {
|
||||
// if (next.getResource()!= null) {
|
||||
retVal.add(next.getResource().getId().toUnqualifiedVersionless());
|
||||
// }
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
protected List<IIdType> toUnqualifiedVersionlessIds(List<IBaseResource> theFound) {
|
||||
List<IIdType> retVal = new ArrayList<IIdType>();
|
||||
for (IBaseResource next : theFound) {
|
||||
|
|
|
@ -56,9 +56,12 @@ import ca.uhn.fhir.model.dstu2.resource.Observation;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Substance;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ContactPointSystemEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
|
@ -100,6 +103,19 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
|||
assertEquals(0, results.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCodeSearch() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setCriteria("Observation?");
|
||||
IIdType id = mySubscriptionDao.create(subs).getId().toUnqualifiedVersionless();
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.add(Subscription.SP_TYPE, new TokenParam(null, SubscriptionChannelTypeEnum.WEBSOCKET.getCode()));
|
||||
map.add(Subscription.SP_STATUS, new TokenParam(null, SubscriptionStatusEnum.ACTIVE.getCode()));
|
||||
assertThat(toUnqualifiedVersionlessIds(mySubscriptionDao.search(map)), contains(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexNoDuplicatesString() {
|
||||
|
|
|
@ -97,6 +97,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
|
||||
|
@ -683,7 +684,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
try {
|
||||
myOrganizationDao.delete(orgId);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
} catch (ResourceVersionConflictException e) {
|
||||
assertThat(e.getMessage(), containsString("Unable to delete Organization/" + orgId.getIdPart()
|
||||
+ " because at least one resource has a reference to this resource. First reference found was resource Patient/" + patId.getIdPart() + " in path Patient.managingOrganization"));
|
||||
}
|
||||
|
@ -839,6 +840,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testHistoryByForcedId() {
|
||||
IIdType idv1;
|
||||
|
@ -2088,21 +2091,21 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_RES_ID));
|
||||
pm.setSort(new SortSpec(BaseResource.SP_RES_ID));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm));
|
||||
assertEquals(5, actual.size());
|
||||
assertThat(actual, contains(idMethodName, id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_RES_ID).setOrder(SortOrderEnum.ASC));
|
||||
pm.setSort(new SortSpec(BaseResource.SP_RES_ID).setOrder(SortOrderEnum.ASC));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm));
|
||||
assertEquals(5, actual.size());
|
||||
assertThat(actual, contains(idMethodName, id1, id2, id3, id4));
|
||||
|
||||
pm = new SearchParameterMap();
|
||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||
pm.setSort(new SortSpec(Patient.SP_RES_ID).setOrder(SortOrderEnum.DESC));
|
||||
pm.setSort(new SortSpec(BaseResource.SP_RES_ID).setOrder(SortOrderEnum.DESC));
|
||||
actual = toUnqualifiedVersionlessIds(myPatientDao.search(pm));
|
||||
assertEquals(5, actual.size());
|
||||
assertThat(actual, contains(id4, id3, id2, id1, idMethodName));
|
||||
|
|
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
|
||||
public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2ValidateTest.class);
|
||||
|
@ -141,9 +142,9 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
|
|||
|
||||
OperationOutcome outcome=null;
|
||||
try {
|
||||
myOrganizationDao.validate(null, orgId, null, null, ValidationModeEnum.DELETE, null);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
myOrganizationDao.validate(null, orgId, null, null, ValidationModeEnum.DELETE, null);
|
||||
fail();
|
||||
} catch (ResourceVersionConflictException e) {
|
||||
outcome= (OperationOutcome) e.getOperationOutcome();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,68 +1,42 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult;
|
||||
import ca.uhn.fhir.jpa.provider.ResourceProviderDstu2Test;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({ "/hapi-fhir-server-resourceproviders-dstu2.xml", "/fhir-jpabase-spring-test-config.xml" })
|
||||
public class FhirResourceDaoValueSetDstu2Test {
|
||||
public class FhirResourceDaoValueSetDstu2Test extends BaseJpaDstu2Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoValueSetDstu2Test.class);
|
||||
|
||||
private static IIdType vsid;
|
||||
private IIdType myExtensionalVsId;
|
||||
|
||||
@Autowired
|
||||
private FhirContext myCtx;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mySystemDaoDstu2")
|
||||
private IFhirSystemDao<Bundle> mySystemDao;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myValueSetDaoDstu2")
|
||||
private IFhirResourceDaoValueSet<ValueSet> myValueSetDao;
|
||||
|
||||
@Before
|
||||
@Transactional
|
||||
public void before01() {
|
||||
if (vsid == null) {
|
||||
FhirSystemDaoDstu2Test.doDeleteEverything(mySystemDao);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@Transactional
|
||||
public void before02() {
|
||||
if (vsid == null) {
|
||||
ValueSet upload = myCtx.newXmlParser().parseResource(ValueSet.class, new InputStreamReader(ResourceProviderDstu2Test.class.getResourceAsStream("/extensional-case-2.xml")));
|
||||
upload.setId("");
|
||||
vsid = myValueSetDao.create(upload).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
public void before02() throws IOException {
|
||||
ValueSet upload = loadResourceFromClasspath(ValueSet.class, "/extensional-case-2.xml");
|
||||
upload.setId("");
|
||||
myExtensionalVsId = myValueSetDao.create(upload).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -137,7 +111,7 @@ public class FhirResourceDaoValueSetDstu2Test {
|
|||
@Test
|
||||
public void testValidateCodeOperationByResourceIdAndCodeableConcept() {
|
||||
UriDt valueSetIdentifier = null;
|
||||
IIdType id = vsid;
|
||||
IIdType id = myExtensionalVsId;
|
||||
CodeDt code = null;
|
||||
UriDt system = null;
|
||||
StringDt display = null;
|
||||
|
@ -151,7 +125,7 @@ public class FhirResourceDaoValueSetDstu2Test {
|
|||
@Test
|
||||
public void testValidateCodeOperationByResourceIdAndCodeAndSystem() {
|
||||
UriDt valueSetIdentifier = null;
|
||||
IIdType id = vsid;
|
||||
IIdType id = myExtensionalVsId;
|
||||
CodeDt code = new CodeDt("11378-7");
|
||||
UriDt system = new UriDt("http://loinc.org");
|
||||
StringDt display = null;
|
||||
|
@ -163,11 +137,11 @@ public class FhirResourceDaoValueSetDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testValueSetExpandOperation() throws IOException {
|
||||
public void testExpandById() throws IOException {
|
||||
String resp;
|
||||
|
||||
ValueSet expanded = myValueSetDao.expand(vsid, null);
|
||||
resp = myCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ValueSet expanded = myValueSetDao.expand(myExtensionalVsId, null);
|
||||
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
// @formatter:off
|
||||
assertThat(resp,
|
||||
|
@ -191,8 +165,8 @@ public class FhirResourceDaoValueSetDstu2Test {
|
|||
* Filter with display name
|
||||
*/
|
||||
|
||||
expanded = myValueSetDao.expand(vsid, new StringDt("systolic"));
|
||||
resp = myCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
expanded = myValueSetDao.expand(myExtensionalVsId, ("systolic"));
|
||||
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
|
@ -204,8 +178,8 @@ public class FhirResourceDaoValueSetDstu2Test {
|
|||
* Filter with code
|
||||
*/
|
||||
|
||||
expanded = myValueSetDao.expand(vsid, new StringDt("11378"));
|
||||
resp = myCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
expanded = myValueSetDao.expand(myExtensionalVsId, ("11378"));
|
||||
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
|
@ -213,5 +187,34 @@ public class FhirResourceDaoValueSetDstu2Test {
|
|||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandByIdentifier() {
|
||||
ValueSet expanded = myValueSetDao.expandByIdentifier("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", "11378");
|
||||
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
|
||||
assertThat(resp, not(containsString("<code value=\"8450-9\"/>")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandByValueSet() throws IOException {
|
||||
ValueSet toExpand = loadResourceFromClasspath(ValueSet.class, "/extensional-case-2.xml");
|
||||
ValueSet expanded = myValueSetDao.expand(toExpand, "11378");
|
||||
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
|
||||
assertThat(resp, not(containsString("<code value=\"8450-9\"/>")));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
|
@ -28,7 +27,6 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -346,8 +344,8 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
|||
|
||||
@Test
|
||||
public void testTransactionWithCidIds2() throws Exception {
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/dstu1_bundle.xml");
|
||||
String bundleStr = IOUtils.toString(bundleRes);
|
||||
String resource = "/dstu1_bundle.xml";
|
||||
String bundleStr = loadClasspath(resource);
|
||||
Bundle bundle = ourFhirContext.newXmlParser().parseBundle(bundleStr);
|
||||
|
||||
List<IResource> res = new ArrayList<IResource>();
|
||||
|
@ -363,6 +361,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
|||
assertThat(encodeResourceToString, not(containsString("smsp")));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the correct way to do this, not {@link #testTransactionWithCidIds()}
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.transaction.TransactionStatus;
|
|||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||
|
@ -44,7 +45,11 @@ import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
|||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryRequest;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryResponse;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Communication;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
||||
import ca.uhn.fhir.model.dstu2.resource.MedicationOrder;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
|
@ -53,8 +58,11 @@ import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
|
|||
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -354,6 +362,42 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionCreateWithInvalidMatchUrl() {
|
||||
String methodName = "testTransactionCreateWithInvalidMatchUrl";
|
||||
Bundle request = new Bundle();
|
||||
|
||||
Patient p;
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
EntryRequest entry = request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
entry.setIfNoneExist("Patient?identifier identifier" + methodName);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Failed to parse match URL[Patient?identifier identifiertestTransactionCreateWithInvalidMatchUrl] - URL is invalid (must not contain spaces)", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
entry.setIfNoneExist("Patient?identifier=");
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Invalid match URL[Patient?identifier=] - URL has no search parameters", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
entry.setIfNoneExist("Patient?foo=bar");
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testTransactionCreateWithDuplicateMatchUrl02() {
|
||||
String methodName = "testTransactionCreateWithDuplicateMatchUrl02";
|
||||
Bundle request = new Bundle();
|
||||
|
@ -634,7 +678,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
try {
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
} catch (PreconditionFailedException e) {
|
||||
assertThat(e.getMessage(), containsString("resource with match URL \"Patient?"));
|
||||
}
|
||||
}
|
||||
|
@ -731,6 +775,68 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
assertEquals("201 Created", resp.getEntry().get(1).getResponse().getStatus());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Communication com = new Communication();
|
||||
com.getSender().setReference("Patient/james");
|
||||
com.addRecipient().setReference("Group/everyone");
|
||||
com.addMedium().setText("Skype");
|
||||
com.addPayload().setContent(new StringDt("Welcome to Connectathon 10! Any HAPI users feel free to grab me if you want to chat or need help!"));
|
||||
System.out.println(FhirContext.forDstu2().newJsonParser().setPrettyPrint(true).encodeResourceToString(com));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionWithReferenceToCreateIfNoneExist() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.setType(BundleTypeEnum.TRANSACTION);
|
||||
|
||||
Medication med = new Medication();
|
||||
IdDt medId = IdDt.newRandomUuid();
|
||||
med.setId(medId);
|
||||
med.getCode().addCoding().setSystem("billscodes").setCode("theCode");
|
||||
bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("Medication?code=billscodes|theCode");
|
||||
|
||||
MedicationOrder mo = new MedicationOrder();
|
||||
mo.setMedication(new ResourceReferenceDt(medId));
|
||||
bundle.addEntry().setResource(mo).setFullUrl(mo.getId().getValue()).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
ourLog.info("Request:\n"+myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
|
||||
|
||||
Bundle outcome = mySystemDao.transaction(bundle);
|
||||
ourLog.info("Response:\n"+myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||
|
||||
IdDt medId1 = new IdDt(outcome.getEntry().get(0).getResponse().getLocation());
|
||||
IdDt medOrderId1 = new IdDt( outcome.getEntry().get(1).getResponse().getLocation());
|
||||
|
||||
/*
|
||||
* Again!
|
||||
*/
|
||||
|
||||
bundle = new Bundle();
|
||||
bundle.setType(BundleTypeEnum.TRANSACTION);
|
||||
|
||||
med = new Medication();
|
||||
medId = IdDt.newRandomUuid();
|
||||
med.getCode().addCoding().setSystem("billscodes").setCode("theCode");
|
||||
bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("Medication?code=billscodes|theCode");
|
||||
|
||||
mo = new MedicationOrder();
|
||||
mo.setMedication(new ResourceReferenceDt(medId));
|
||||
bundle.addEntry().setResource(mo).setFullUrl(mo.getId().getValue()).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
outcome = mySystemDao.transaction(bundle);
|
||||
|
||||
IdDt medId2 = new IdDt(outcome.getEntry().get(0).getResponse().getLocation());
|
||||
IdDt medOrderId2 = new IdDt(outcome.getEntry().get(1).getResponse().getLocation());
|
||||
|
||||
assertTrue(medId1.isIdPartValidLong());
|
||||
assertTrue(medId2.isIdPartValidLong());
|
||||
assertTrue(medOrderId1.isIdPartValidLong());
|
||||
assertTrue(medOrderId2.isIdPartValidLong());
|
||||
|
||||
assertEquals(medId1, medId2);
|
||||
assertNotEquals(medOrderId1, medOrderId2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionReadAndSearch() {
|
||||
String methodName = "testTransactionReadAndSearch";
|
||||
|
|
|
@ -101,7 +101,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
|
|||
|
||||
restServer.setPlainProviders(mySystemProvider);
|
||||
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, mySystemDao);
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, mySystemDao, myDaoConfig);
|
||||
confProvider.setImplementationDescription("THIS IS THE DESC");
|
||||
restServer.setServerConformanceProvider(confProvider);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import static org.hamcrest.Matchers.contains;
|
|||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
@ -25,9 +26,7 @@ import java.net.Socket;
|
|||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -69,12 +68,15 @@ import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AnswerFormatEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.EncounterClassEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.EncounterStateEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SearchEntryModeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -89,6 +91,8 @@ import ca.uhn.fhir.rest.client.IGenericClient;
|
|||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||
|
@ -97,6 +101,13 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
@Override
|
||||
public void before() throws Exception {
|
||||
super.before();
|
||||
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
}
|
||||
|
||||
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
|
||||
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
|
||||
CloseableHttpResponse resp = ourHttpClient.execute(get);
|
||||
|
@ -104,58 +115,6 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
// private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||
// Bundle resources;
|
||||
// do {
|
||||
// IQuery<Bundle> forResource = ourClient.search().forResource(theResourceType);
|
||||
// if (theParamName != null) {
|
||||
// forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
|
||||
// }
|
||||
// resources = forResource.execute();
|
||||
// for (IResource next : resources.toListOfResources()) {
|
||||
// ourLog.info("Deleting resource: {}", next.getId());
|
||||
// ourClient.delete().resource(next).execute();
|
||||
// }
|
||||
// } while (resources.size() > 0);
|
||||
// }
|
||||
//
|
||||
// private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue)
|
||||
// {
|
||||
// Bundle resources = ourClient.search().forResource(theResourceType).where(new
|
||||
// TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||
// for (IResource next : resources.toListOfResources()) {
|
||||
// ourLog.info("Deleting resource: {}", next.getId());
|
||||
// ourClient.delete().resource(next).execute();
|
||||
// }
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testSearchByIdOr() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.RES_ID.matches().values(id1.getIdPart(), id2.getIdPart()))
|
||||
.and(Patient.RES_ID.matches().value(id1.getIdPart()))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBundleCreate() throws Exception {
|
||||
IGenericClient client = ourClient;
|
||||
|
@ -184,6 +143,78 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||
// Bundle resources;
|
||||
// do {
|
||||
// IQuery<Bundle> forResource = ourClient.search().forResource(theResourceType);
|
||||
// if (theParamName != null) {
|
||||
// forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
|
||||
// }
|
||||
// resources = forResource.execute();
|
||||
// for (IResource next : resources.toListOfResources()) {
|
||||
// ourLog.info("Deleting resource: {}", next.getId());
|
||||
// ourClient.delete().resource(next).execute();
|
||||
// }
|
||||
// } while (resources.size() > 0);
|
||||
// }
|
||||
//
|
||||
// private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue)
|
||||
// {
|
||||
// Bundle resources = ourClient.search().forResource(theResourceType).where(new
|
||||
// TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||
// for (IResource next : resources.toListOfResources()) {
|
||||
// ourLog.info("Deleting resource: {}", next.getId());
|
||||
// ourClient.delete().resource(next).execute();
|
||||
// }
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testCodeSearch() {
|
||||
Subscription subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setCriteria("Observation?");
|
||||
IIdType id = ourClient.create().resource(subs).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
//@formatter:off
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient
|
||||
.search()
|
||||
.forResource(Subscription.class)
|
||||
.where(Subscription.TYPE.exactly().code(SubscriptionChannelTypeEnum.WEBSOCKET.getCode()))
|
||||
.and(Subscription.STATUS.exactly().code(SubscriptionStatusEnum.ACTIVE.getCode()))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:off
|
||||
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), contains(id));
|
||||
|
||||
//@formatter:off
|
||||
resp = ourClient
|
||||
.search()
|
||||
.forResource(Subscription.class)
|
||||
.where(Subscription.TYPE.exactly().systemAndCode(SubscriptionChannelTypeEnum.WEBSOCKET.getSystem(), SubscriptionChannelTypeEnum.WEBSOCKET.getCode()))
|
||||
.and(Subscription.STATUS.exactly().systemAndCode(SubscriptionStatusEnum.ACTIVE.getSystem(), SubscriptionStatusEnum.ACTIVE.getCode()))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:off
|
||||
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), contains(id));
|
||||
|
||||
//@formatter:off
|
||||
resp = ourClient
|
||||
.search()
|
||||
.forResource(Subscription.class)
|
||||
.where(Subscription.TYPE.exactly().systemAndCode(SubscriptionChannelTypeEnum.WEBSOCKET.getSystem(), SubscriptionChannelTypeEnum.WEBSOCKET.getCode()))
|
||||
.and(Subscription.STATUS.exactly().systemAndCode("foo", SubscriptionStatusEnum.ACTIVE.getCode()))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
//@formatter:off
|
||||
|
||||
assertThat(toUnqualifiedVersionlessIds(resp), empty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCountParam() throws Exception {
|
||||
// NB this does not get used- The paging provider has its own limits built in
|
||||
|
@ -207,19 +238,6 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithForcedId() throws IOException {
|
||||
String methodName = "testCreateWithForcedId";
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.setId(methodName);
|
||||
|
||||
IIdType optId = ourClient.update().resource(p).execute().getId();
|
||||
assertEquals(methodName, optId.getIdPart());
|
||||
assertEquals("1", optId.getVersionIdPart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
||||
ValueSet options = new ValueSet();
|
||||
|
@ -328,6 +346,19 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithForcedId() throws IOException {
|
||||
String methodName = "testCreateWithForcedId";
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.setId(methodName);
|
||||
|
||||
IIdType optId = ourClient.update().resource(p).execute().getId();
|
||||
assertEquals(methodName, optId.getIdPart());
|
||||
assertEquals("1", optId.getVersionIdPart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeepChaining() {
|
||||
Location l1 = new Location();
|
||||
|
@ -363,6 +394,63 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteConditionalMultiple() {
|
||||
String methodName = "testDeleteConditionalMultiple";
|
||||
|
||||
myDaoConfig.setAllowMultipleDelete(false);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("FAM1");
|
||||
IIdType id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("FAM2");
|
||||
IIdType id2 = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
try {
|
||||
//@formatter:off
|
||||
ourClient
|
||||
.delete()
|
||||
.resourceConditionalByType(Patient.class)
|
||||
.where(Patient.IDENTIFIER.exactly().code(methodName))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
assertEquals("HTTP 412 Precondition Failed: Failed to DELETE resource with match URL \"Patient?identifier=testDeleteConditionalMultiple\" because this search matched 2 resources", e.getMessage());
|
||||
}
|
||||
|
||||
// Not deleted yet..
|
||||
ourClient.read().resource("Patient").withId(id1).execute();
|
||||
ourClient.read().resource("Patient").withId(id2).execute();
|
||||
|
||||
myDaoConfig.setAllowMultipleDelete(true);
|
||||
|
||||
//@formatter:off
|
||||
ourClient
|
||||
.delete()
|
||||
.resourceConditionalByType(Patient.class)
|
||||
.where(Patient.IDENTIFIER.exactly().code(methodName))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
try {
|
||||
ourClient.read().resource("Patient").withId(id1).execute();
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// good
|
||||
}
|
||||
try {
|
||||
ourClient.read().resource("Patient").withId(id2).execute();
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteInvalidReference() throws IOException {
|
||||
HttpDelete delete = new HttpDelete(ourServerBase + "/Patient");
|
||||
|
@ -376,7 +464,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDeleteResourceConditional1() throws IOException {
|
||||
String methodName = "testDeleteResourceConditional1";
|
||||
|
@ -416,7 +504,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Based on email from Rene Spronk
|
||||
*/
|
||||
|
@ -543,11 +631,133 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEverythingEncounterInstance() throws Exception {
|
||||
String methodName = "testEverythingEncounterInstance";
|
||||
|
||||
Organization org1parent = new Organization();
|
||||
org1parent.setId("org1parent");
|
||||
org1parent.setName(methodName + "1parent");
|
||||
IIdType orgId1parent = ourClient.update().resource(org1parent).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org1 = new Organization();
|
||||
org1.setName(methodName + "1");
|
||||
org1.getPartOf().setReference(orgId1parent);
|
||||
IIdType orgId1 = ourClient.create().resource(org1).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.getManagingOrganization().setReference(orgId1);
|
||||
IIdType patientId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org2 = new Organization();
|
||||
org2.setName(methodName + "1");
|
||||
IIdType orgId2 = ourClient.create().resource(org2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Device dev = new Device();
|
||||
dev.setModel(methodName);
|
||||
dev.getOwner().setReference(orgId2);
|
||||
IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locParent = new Location();
|
||||
locParent.setName(methodName+"Parent");
|
||||
IIdType locPId = ourClient.create().resource(locParent).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locChild = new Location();
|
||||
locChild.setName(methodName);
|
||||
locChild.getPartOf().setReference(locPId);
|
||||
IIdType locCId = ourClient.create().resource(locChild).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter encU = new Encounter();
|
||||
encU.getPatient().setReference(patientId);
|
||||
encU.addLocation().getLocation().setReference(locCId);
|
||||
IIdType encUId = ourClient.create().resource(encU).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.getPatient().setReference(patientId);
|
||||
enc.addLocation().getLocation().setReference(locCId);
|
||||
IIdType encId = ourClient.create().resource(enc).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.getSubject().setReference(patientId);
|
||||
obs.getDevice().setReference(devId);
|
||||
obs.getEncounter().setReference(encId);
|
||||
IIdType obsId = ourClient.create().resource(obs).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(encId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(b);
|
||||
assertThat(ids, containsInAnyOrder(patientId, encId, orgId1, orgId2, orgId1parent, locPId, locCId, obsId, devId));
|
||||
assertThat(ids, not(containsInRelativeOrder(encUId)));
|
||||
|
||||
ourLog.info(ids.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEverythingEncounterType() throws Exception {
|
||||
String methodName = "testEverythingEncounterInstance";
|
||||
|
||||
Organization org1parent = new Organization();
|
||||
org1parent.setId("org1parent");
|
||||
org1parent.setName(methodName + "1parent");
|
||||
IIdType orgId1parent = ourClient.update().resource(org1parent).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org1 = new Organization();
|
||||
org1.setName(methodName + "1");
|
||||
org1.getPartOf().setReference(orgId1parent);
|
||||
IIdType orgId1 = ourClient.create().resource(org1).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.getManagingOrganization().setReference(orgId1);
|
||||
IIdType patientId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org2 = new Organization();
|
||||
org2.setName(methodName + "1");
|
||||
IIdType orgId2 = ourClient.create().resource(org2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Device dev = new Device();
|
||||
dev.setModel(methodName);
|
||||
dev.getOwner().setReference(orgId2);
|
||||
IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locParent = new Location();
|
||||
locParent.setName(methodName+"Parent");
|
||||
IIdType locPId = ourClient.create().resource(locParent).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Location locChild = new Location();
|
||||
locChild.setName(methodName);
|
||||
locChild.getPartOf().setReference(locPId);
|
||||
IIdType locCId = ourClient.create().resource(locChild).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter encU = new Encounter();
|
||||
encU.addIdentifier().setValue(methodName);
|
||||
IIdType encUId = ourClient.create().resource(encU).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.getPatient().setReference(patientId);
|
||||
enc.addLocation().getLocation().setReference(locCId);
|
||||
IIdType encId = ourClient.create().resource(enc).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.getSubject().setReference(patientId);
|
||||
obs.getDevice().setReference(devId);
|
||||
obs.getEncounter().setReference(encId);
|
||||
IIdType obsId = ourClient.create().resource(obs).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onType(Encounter.class).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(b);
|
||||
assertThat(ids, containsInAnyOrder(patientId, encUId, encId, orgId1, orgId2, orgId1parent, locPId, locCId, obsId, devId));
|
||||
|
||||
ourLog.info(ids.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* See #147
|
||||
*/
|
||||
@Test
|
||||
public void testEverythingDoesntRepeatPatient() throws Exception {
|
||||
public void testEverythingPatientDoesntRepeatPatient() throws Exception {
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b;
|
||||
b = myFhirCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, new InputStreamReader(ResourceProviderDstu2Test.class.getResourceAsStream("/bug147-bundle.json")));
|
||||
|
||||
|
@ -601,14 +811,159 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
assertThat(ids.size(), greaterThan(10));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for #226
|
||||
*/
|
||||
@Test
|
||||
public void testEverythingPatientIncludesBackReferences() throws Exception {
|
||||
String methodName = "testEverythingIncludesBackReferences";
|
||||
|
||||
Medication med = new Medication();
|
||||
med.getCode().setText(methodName);
|
||||
IIdType medId = myMedicationDao.create(med).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient pat = new Patient();
|
||||
pat.addAddress().addLine(methodName);
|
||||
IIdType patId = myPatientDao.create(pat).getId().toUnqualifiedVersionless();
|
||||
|
||||
MedicationOrder mo = new MedicationOrder();
|
||||
mo.getPatient().setReference(patId);
|
||||
mo.setMedication(new ResourceReferenceDt(medId));
|
||||
IIdType moId = myMedicationOrderDao.create(mo).getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(patId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(b);
|
||||
ourLog.info(ids.toString());
|
||||
assertThat(ids, containsInAnyOrder(patId, medId, moId));
|
||||
}
|
||||
|
||||
/**
|
||||
* See #148
|
||||
*/
|
||||
@Test
|
||||
public void testEverythingPatientIncludesCondition() throws Exception {
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||
Patient p = new Patient();
|
||||
p.setId("1");
|
||||
b.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Condition c = new Condition();
|
||||
c.getPatient().setReference("Patient/1");
|
||||
b.addEntry().setResource(c).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient.transaction().withBundle(b).execute();
|
||||
|
||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
IdDt patientId = new IdDt(resp.getEntry().get(0).getResponse().getLocation());
|
||||
assertEquals("Patient", patientId.getResourceType());
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
|
||||
List<IdDt> ids = new ArrayList<IdDt>();
|
||||
for (Entry next : b.getEntry()) {
|
||||
IdDt toAdd = next.getResource().getId().toUnqualifiedVersionless();
|
||||
ids.add(toAdd);
|
||||
}
|
||||
|
||||
assertThat(ids.toString(), containsString("Patient/"));
|
||||
assertThat(ids.toString(), containsString("Condition/"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testEverythingPatientOperation() throws Exception {
|
||||
String methodName = "testEverythingOperation";
|
||||
|
||||
Organization org1parent = new Organization();
|
||||
org1parent.setId("org1parent");
|
||||
org1parent.setName(methodName + "1parent");
|
||||
IIdType orgId1parent = ourClient.update().resource(org1parent).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org1 = new Organization();
|
||||
org1.setName(methodName + "1");
|
||||
org1.getPartOf().setReference(orgId1parent);
|
||||
IIdType orgId1 = ourClient.create().resource(org1).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.getManagingOrganization().setReference(orgId1);
|
||||
IIdType patientId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org2 = new Organization();
|
||||
org2.setName(methodName + "1");
|
||||
IIdType orgId2 = ourClient.create().resource(org2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Device dev = new Device();
|
||||
dev.setModel(methodName);
|
||||
dev.getOwner().setReference(orgId2);
|
||||
IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.getSubject().setReference(patientId);
|
||||
obs.getDevice().setReference(devId);
|
||||
IIdType obsId = ourClient.create().resource(obs).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.getPatient().setReference(patientId);
|
||||
IIdType encId = ourClient.create().resource(enc).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(b);
|
||||
assertThat(ids, containsInAnyOrder(patientId, devId, obsId, encId, orgId1, orgId2, orgId1parent));
|
||||
|
||||
ourLog.info(ids.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEverythingPatientType() throws Exception {
|
||||
String methodName = "testEverythingPatientType";
|
||||
|
||||
Organization o1 = new Organization();
|
||||
o1.setName(methodName+"1");
|
||||
IIdType o1Id = ourClient.create().resource(o1).execute().getId().toUnqualifiedVersionless();
|
||||
Organization o2 = new Organization();
|
||||
o2.setName(methodName+"2");
|
||||
IIdType o2Id = ourClient.create().resource(o2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p1 = new Patient();
|
||||
p1.addName().addFamily(methodName+"1");
|
||||
p1.getManagingOrganization().setReference(o1Id);
|
||||
IIdType p1Id = ourClient.create().resource(p1).execute().getId().toUnqualifiedVersionless();
|
||||
Patient p2 = new Patient();
|
||||
p2.addName().addFamily(methodName+"2");
|
||||
p2.getManagingOrganization().setReference(o2Id);
|
||||
IIdType p2Id = ourClient.create().resource(p2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Condition c1 = new Condition();
|
||||
c1.getPatient().setReference(p1Id);
|
||||
IIdType c1Id = ourClient.create().resource(c1).execute().getId().toUnqualifiedVersionless();
|
||||
Condition c2 = new Condition();
|
||||
c2.getPatient().setReference(p2Id);
|
||||
IIdType c2Id = ourClient.create().resource(c2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Condition c3 = new Condition();
|
||||
c3.addIdentifier().setValue(methodName+"3");
|
||||
IIdType c3Id = ourClient.create().resource(c3).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onType(Patient.class).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
List<IIdType> ids = toUnqualifiedVersionlessIds(b);
|
||||
|
||||
assertThat(ids, containsInAnyOrder(o1Id, o2Id, p1Id, p2Id, c1Id, c2Id));
|
||||
assertThat(ids, not(containsInRelativeOrder(c3Id)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEverythingWithLastUpdatedAndSort() throws Exception {
|
||||
public void testEverythingPatientWithLastUpdatedAndSort() throws Exception {
|
||||
String methodName = "testEverythingWithLastUpdatedAndSort";
|
||||
|
||||
long time0 = System.currentTimeMillis();
|
||||
Thread.sleep(10);
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setName(methodName);
|
||||
IIdType oId = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
|
||||
|
@ -691,122 +1046,6 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #148
|
||||
*/
|
||||
@Test
|
||||
public void testEverythingIncludesCondition() throws Exception {
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||
Patient p = new Patient();
|
||||
p.setId("1");
|
||||
b.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Condition c = new Condition();
|
||||
c.getPatient().setReference("Patient/1");
|
||||
b.addEntry().setResource(c).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle resp = ourClient.transaction().withBundle(b).execute();
|
||||
|
||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
IdDt patientId = new IdDt(resp.getEntry().get(0).getResponse().getLocation());
|
||||
assertEquals("Patient", patientId.getResourceType());
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
|
||||
List<IdDt> ids = new ArrayList<IdDt>();
|
||||
for (Entry next : b.getEntry()) {
|
||||
IdDt toAdd = next.getResource().getId().toUnqualifiedVersionless();
|
||||
ids.add(toAdd);
|
||||
}
|
||||
|
||||
assertThat(ids.toString(), containsString("Patient/"));
|
||||
assertThat(ids.toString(), containsString("Condition/"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for #226
|
||||
*/
|
||||
@Test
|
||||
public void testEverythingIncludesBackReferences() throws Exception {
|
||||
String methodName = "testEverythingIncludesBackReferences";
|
||||
|
||||
Medication med = new Medication();
|
||||
med.getCode().setText(methodName);
|
||||
IIdType medId = myMedicationDao.create(med).getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient pat = new Patient();
|
||||
pat.addAddress().addLine(methodName);
|
||||
IIdType patId = myPatientDao.create(pat).getId().toUnqualifiedVersionless();
|
||||
|
||||
MedicationOrder mo = new MedicationOrder();
|
||||
mo.getPatient().setReference(patId);
|
||||
mo.setMedication(new ResourceReferenceDt(medId));
|
||||
IIdType moId = myMedicationOrderDao.create(mo).getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(patId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
Set<IdDt> ids = toIdList(b);
|
||||
ourLog.info(ids.toString());
|
||||
assertThat(ids, containsInAnyOrder(patId, medId, moId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEverythingOperation() throws Exception {
|
||||
String methodName = "testEverythingOperation";
|
||||
|
||||
Organization org1parent = new Organization();
|
||||
org1parent.setId("org1parent");
|
||||
org1parent.setName(methodName + "1parent");
|
||||
IIdType orgId1parent = ourClient.update().resource(org1parent).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org1 = new Organization();
|
||||
org1.setName(methodName + "1");
|
||||
org1.getPartOf().setReference(orgId1parent);
|
||||
IIdType orgId1 = ourClient.create().resource(org1).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.getManagingOrganization().setReference(orgId1);
|
||||
IIdType patientId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Organization org2 = new Organization();
|
||||
org2.setName(methodName + "1");
|
||||
IIdType orgId2 = ourClient.create().resource(org2).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Device dev = new Device();
|
||||
dev.setModel(methodName);
|
||||
dev.getOwner().setReference(orgId2);
|
||||
IIdType devId = ourClient.create().resource(dev).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Observation obs = new Observation();
|
||||
obs.getSubject().setReference(patientId);
|
||||
obs.getDevice().setReference(devId);
|
||||
IIdType obsId = ourClient.create().resource(obs).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Encounter enc = new Encounter();
|
||||
enc.getPatient().setReference(patientId);
|
||||
IIdType encId = ourClient.create().resource(enc).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||
|
||||
Set<IdDt> ids = toIdList(b);
|
||||
assertThat(ids, containsInAnyOrder(patientId, devId, obsId, encId, orgId1, orgId2, orgId1parent));
|
||||
|
||||
ourLog.info(ids.toString());
|
||||
}
|
||||
|
||||
private Set<IdDt> toIdList(ca.uhn.fhir.model.dstu2.resource.Bundle b) {
|
||||
Set<IdDt> ids = new HashSet<IdDt>();
|
||||
for (Entry next : b.getEntry()) {
|
||||
ids.add(next.getResource().getId().toUnqualifiedVersionless());
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceCountsOperation() throws Exception {
|
||||
|
@ -886,6 +1125,29 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperations() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
IIdType id = ourClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
MetaDt meta = ourClient.meta().get(MetaDt.class).fromResource(id).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
|
||||
MetaDt inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().add().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(1, meta.getTag().size());
|
||||
|
||||
inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().delete().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperationWithNoMetaParameter() throws Exception {
|
||||
Patient p = new Patient();
|
||||
|
@ -930,29 +1192,6 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperations() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
IIdType id = ourClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
MetaDt meta = ourClient.meta().get(MetaDt.class).fromResource(id).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
|
||||
MetaDt inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().add().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(1, meta.getTag().size());
|
||||
|
||||
inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().delete().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for issue #60
|
||||
*/
|
||||
|
@ -1093,6 +1332,33 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByIdOr() {
|
||||
IIdType id1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id1 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
IIdType id2;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
id2 = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.RES_ID.matches().values(id1.getIdPart(), id2.getIdPart()))
|
||||
.and(Patient.RES_ID.matches().value(id1.getIdPart()))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertThat(toIdListUnqualifiedVersionless(found), containsInAnyOrder(id1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByResourceChain() {
|
||||
|
||||
|
@ -1297,7 +1563,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
o.getCode().setText("testSearchWithInvalidSort");
|
||||
myObservationDao.create(o);
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
ourClient
|
||||
.search()
|
||||
.forResource(Observation.class)
|
||||
.sort().ascending(Observation.CODE_VALUE_QUANTITY) // composite sort not supported yet
|
||||
|
@ -1552,6 +1818,21 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransaction() throws Exception {
|
||||
String contents = loadClasspath("/update.xml");
|
||||
HttpPost post = new HttpPost(ourServerBase);
|
||||
post.setEntity(new StringEntity(contents, ContentType.create("application/xml+fhir", "UTF-8")));
|
||||
CloseableHttpResponse resp = ourHttpClient.execute(post);
|
||||
try {
|
||||
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||
String output= IOUtils.toString(resp.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
} finally {
|
||||
resp.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryToCreateResourceWithReferenceThatDoesntExist() {
|
||||
Patient p1 = new Patient();
|
||||
|
@ -1568,6 +1849,27 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateInvalidReference() throws IOException, Exception {
|
||||
String methodName = "testUpdateInvalidReference";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
|
||||
HttpPut post = new HttpPut(ourServerBase + "/Patient");
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
try {
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(responseString);
|
||||
assertThat(responseString, containsString("<pre>Can not update a resource with no ID</pre>"));
|
||||
assertThat(responseString, containsString("<OperationOutcome"));
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRejectsInvalidTypes() throws InterruptedException {
|
||||
|
@ -1629,28 +1931,6 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateInvalidReference() throws IOException, Exception {
|
||||
String methodName = "testUpdateInvalidReference";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
String resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
|
||||
HttpPut post = new HttpPut(ourServerBase + "/Patient");
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
try {
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(responseString);
|
||||
assertThat(responseString, containsString("<pre>Can not update a resource with no ID</pre>"));
|
||||
assertThat(responseString, containsString("<OperationOutcome"));
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateResourceWithPrefer() throws IOException, Exception {
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
|
||||
public class ResourceProviderDstu2ValueSetTest extends BaseResourceProviderDstu2Test {
|
||||
|
||||
private IIdType myExtensionalVsId;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2ValueSetTest.class);
|
||||
|
||||
@Before
|
||||
@Transactional
|
||||
public void before02() throws IOException {
|
||||
ValueSet upload = loadResourceFromClasspath(ValueSet.class, "/extensional-case-2.xml");
|
||||
upload.setId("");
|
||||
myExtensionalVsId = myValueSetDao.create(upload).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandById() throws IOException {
|
||||
//@formatter:off
|
||||
Parameters respParam = ourClient
|
||||
.operation()
|
||||
.onInstance(myExtensionalVsId)
|
||||
.named("expand")
|
||||
.withNoParameters(Parameters.class)
|
||||
.execute();
|
||||
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
|
||||
//@formatter:on
|
||||
|
||||
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
// @formatter:off
|
||||
assertThat(resp,
|
||||
stringContainsInOrder("<ValueSet xmlns=\"http://hl7.org/fhir\">",
|
||||
"<expansion>",
|
||||
"<contains>",
|
||||
"<system value=\"http://loinc.org\"/>",
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>",
|
||||
"</contains>",
|
||||
"<contains>",
|
||||
"<system value=\"http://loinc.org\"/>",
|
||||
"<code value=\"8450-9\"/>",
|
||||
"<display value=\"Systolic blood pressure--expiration\"/>",
|
||||
"</contains>",
|
||||
"</expansion>"
|
||||
));
|
||||
//@formatter:on
|
||||
|
||||
/*
|
||||
* Filter with display name
|
||||
*/
|
||||
|
||||
//@formatter:off
|
||||
respParam = ourClient
|
||||
.operation()
|
||||
.onInstance(myExtensionalVsId)
|
||||
.named("expand")
|
||||
.withParameter(Parameters.class, "filter", new StringDt("systolic"))
|
||||
.execute();
|
||||
expanded = (ValueSet) respParam.getParameter().get(0).getResource();
|
||||
//@formatter:on
|
||||
|
||||
expanded = myValueSetDao.expand(myExtensionalVsId, ("systolic"));
|
||||
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
|
||||
/*
|
||||
* Filter with code
|
||||
*/
|
||||
|
||||
//@formatter:off
|
||||
respParam = ourClient
|
||||
.operation()
|
||||
.onInstance(myExtensionalVsId)
|
||||
.named("expand")
|
||||
.withParameter(Parameters.class, "filter", new StringDt("11378"))
|
||||
.execute();
|
||||
expanded = (ValueSet) respParam.getParameter().get(0).getResource();
|
||||
//@formatter:on
|
||||
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandByIdentifier() {
|
||||
//@formatter:off
|
||||
Parameters respParam = ourClient
|
||||
.operation()
|
||||
.onInstance(myExtensionalVsId)
|
||||
.named("expand")
|
||||
.withParameter(Parameters.class, "identifier", new UriDt("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2"))
|
||||
.andParameter("filter", new StringDt("11378"))
|
||||
.execute();
|
||||
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
|
||||
//@formatter:on
|
||||
|
||||
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
|
||||
assertThat(resp, not(containsString("<code value=\"8450-9\"/>")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandByValueSet() throws IOException {
|
||||
ValueSet toExpand = loadResourceFromClasspath(ValueSet.class, "/extensional-case-2.xml");
|
||||
|
||||
//@formatter:off
|
||||
Parameters respParam = ourClient
|
||||
.operation()
|
||||
.onInstance(myExtensionalVsId)
|
||||
.named("expand")
|
||||
.withParameter(Parameters.class, "valueSet", toExpand)
|
||||
.andParameter("filter", new StringDt("11378"))
|
||||
.execute();
|
||||
ValueSet expanded = (ValueSet) respParam.getParameter().get(0).getResource();
|
||||
//@formatter:on
|
||||
|
||||
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
//@formatter:off
|
||||
assertThat(resp, stringContainsInOrder(
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
//@formatter:on
|
||||
|
||||
assertThat(resp, not(containsString("<code value=\"8450-9\"/>")));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@ import org.apache.commons.io.IOUtils;
|
|||
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.IBaseOperationOutcome;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@ -26,9 +27,11 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
import ca.uhn.fhir.model.dstu.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class SystemProviderDstu2Test extends BaseJpaTest {
|
||||
|
||||
|
@ -38,6 +41,36 @@ public class SystemProviderDstu2Test extends BaseJpaTest {
|
|||
private static FhirContext ourCtx;
|
||||
private static IGenericClient ourClient;
|
||||
|
||||
|
||||
@Test
|
||||
public void testTransactionFromBundle4() throws Exception {
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle.xml");
|
||||
String bundle = IOUtils.toString(bundleRes);
|
||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||
ourLog.info(response);
|
||||
Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
|
||||
IdDt id = new IdDt(bundleResp.getEntry().get(0).getResponse().getLocation());
|
||||
assertEquals("Patient", id.getResourceType());
|
||||
assertTrue(id.hasIdPart());
|
||||
assertTrue(id.isIdPartValidLong());
|
||||
assertTrue(id.hasVersionIdPart());
|
||||
assertTrue(id.isVersionIdPartValidLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionFromBundle5() throws Exception {
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle2.xml");
|
||||
String bundle = IOUtils.toString(bundleRes);
|
||||
try {
|
||||
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
|
||||
assertEquals("Invalid placeholder ID found: uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'", oo.getIssue().get(0).getDiagnostics());
|
||||
assertEquals("processing", oo.getIssue().get(0).getCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransactionFromBundle() throws Exception {
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve.xml");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@
|
|||
<status value="generated" />
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">A selection of codes from http://loinc.org</div>
|
||||
</text>
|
||||
<url value="http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2"/>
|
||||
<identifier>
|
||||
<value
|
||||
value="http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2" />
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="20151003220331"/>
|
||||
<type value="transaction"/>
|
||||
<entry>
|
||||
<fullUrl value="urn:uuid:abd7a623-699e-46b5-5f5f-8d1d79fa33e6"/>
|
||||
<resource>
|
||||
<Patient>
|
||||
<identifier>
|
||||
<use value="usual"/>
|
||||
<type>
|
||||
<coding>
|
||||
<system value="http://hl7.org/fhir/identifier-type"/>
|
||||
<code value="NH"/>
|
||||
</coding>
|
||||
</type>
|
||||
<system value="urn:oid:2.16.840.1.113883.2.1.4.1"/>
|
||||
<value value="23455457476474754545"/>
|
||||
<assigner>
|
||||
<display value="NHS"/>
|
||||
</assigner>
|
||||
</identifier>
|
||||
<identifier>
|
||||
<use value="usual"/>
|
||||
<type>
|
||||
<coding>
|
||||
<system value="http://hl7.org/fhir/identifier-type"/>
|
||||
<code value="MR"/>
|
||||
</coding>
|
||||
</type>
|
||||
<system value="http://www.ghh.org/identifiers/"/>
|
||||
<value value="4567567567"/>
|
||||
<assigner>
|
||||
<display value="TCPAS"/>
|
||||
</assigner>
|
||||
</identifier>
|
||||
<name>
|
||||
<use value="official"/>
|
||||
<family value="Connectathon"/>
|
||||
<given value="Ann"/>
|
||||
</name>
|
||||
<telecom>
|
||||
<system value="phone"/>
|
||||
<value value="277543"/>
|
||||
<use value="home"/>
|
||||
</telecom>
|
||||
<gender value="female"/>
|
||||
<birthDate value="1928-05-24"/>
|
||||
<address>
|
||||
<line value="22 Stable Road"/>
|
||||
<city value="Whitstable"/>
|
||||
<state value="Kent"/>
|
||||
<country value="CR5 1EL"/>
|
||||
</address>
|
||||
<contact>
|
||||
<relationship>
|
||||
<coding>
|
||||
<system value="http://hl7.org/fhir/patient-contact-relationship"/>
|
||||
<code value="parent"/>
|
||||
</coding>
|
||||
</relationship>
|
||||
<name>
|
||||
<family value="Connectathon"/>
|
||||
<given value="Joe"/>
|
||||
</name>
|
||||
</contact>
|
||||
</Patient>
|
||||
</resource>
|
||||
<request>
|
||||
<method value="PUT"/>
|
||||
<url value="/Patient?identifier=http://www.ghh.org/identifiers/|4567567567"/>
|
||||
</request>
|
||||
</entry>
|
||||
<entry>
|
||||
<fullUrl value="urn:uuid:491aabbf-fcff-4697-5bb2-84e856d5786b"/>
|
||||
<resource>
|
||||
<Encounter>
|
||||
<identifier>
|
||||
<use value="usual"/>
|
||||
<type>
|
||||
<coding>
|
||||
<system value="http://hl7.org/fhir/identifier-type"/>
|
||||
<code value="MR"/>
|
||||
</coding>
|
||||
</type>
|
||||
<system value="http://general-hospital.co.uk/Identifiers/"/>
|
||||
<value value="123447878787866666"/>
|
||||
<assigner>
|
||||
<display value="GENHOS"/>
|
||||
</assigner>
|
||||
</identifier>
|
||||
<status value="in-progress"/>
|
||||
<class value="inpatient"/>
|
||||
<patient>
|
||||
<reference value="urn:uuid:abd7a623-699e-46b5-5f5f-8d1d79fa33e6"/>
|
||||
<display value="Connectathon, Ann(*24.05.1928)"/>
|
||||
</patient>
|
||||
<period>
|
||||
<start value="2015-05-02T09:00:00+01:00"/>
|
||||
</period>
|
||||
</Encounter>
|
||||
</resource>
|
||||
<request>
|
||||
<method value="PUT"/>
|
||||
<url value="/Encounter?identifier=http://general-hospital.co.uk/Identifiers/|123447878787866666"/>
|
||||
</request>
|
||||
</entry>
|
||||
</Bundle>
|
|
@ -0,0 +1,73 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir" xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
<type value="transaction"/>
|
||||
<entry>
|
||||
<fullUrl value="uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d"/>
|
||||
<resource>
|
||||
<Patient>
|
||||
<text>
|
||||
<status value="generated"/>
|
||||
<xhtml:div>
|
||||
<xhtml:img src="http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png" alt="Twitter Avatar"/>
|
||||
@fhirabend
|
||||
</xhtml:div>
|
||||
</text>
|
||||
<identifier>
|
||||
<use value="secondary"/>
|
||||
<system value="http://twitter.com"/>
|
||||
<value value="2922960201"/>
|
||||
</identifier>
|
||||
<name>
|
||||
<family value="fhirabend"/>
|
||||
</name>
|
||||
<photo>
|
||||
<url value="http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png"/>
|
||||
</photo>
|
||||
</Patient>
|
||||
</resource>
|
||||
<request>
|
||||
<method value="PUT"/>
|
||||
<url value="Patient?identifier=http://twitter.com|2922960201"/>
|
||||
</request>
|
||||
</entry>
|
||||
<entry>
|
||||
<resource>
|
||||
<Communication>
|
||||
<meta>
|
||||
<profile value="http://foo/Profile1"/>
|
||||
<tag>
|
||||
<system value="http://twitter.com"/>
|
||||
<code value="http://twitter.com/hashtag/FHIR"/>
|
||||
<display value="#FHIR"/>
|
||||
</tag>
|
||||
</meta>
|
||||
<text>
|
||||
<status value="generated"/>
|
||||
<xhtml:div>
|
||||
<xhtml:b> @fhirabend:</xhtml:b>
|
||||
RT @kainamti: Motto of the FHIR calendar 2016: the #FHIR is strong in you @HL7 http://t.co/E03Y3NIjME
|
||||
</xhtml:div>
|
||||
</text>
|
||||
<identifier>
|
||||
<system value="http://twitter.com"/>
|
||||
<value value="650408456562823168"/>
|
||||
</identifier>
|
||||
<sender>
|
||||
<reference value="uri:uuid:bb0cd4bc-1839-4606-8c46-ba3069e69b1d"/>
|
||||
</sender>
|
||||
<payload>
|
||||
<contentString value="RT @kainamti: Motto of the FHIR calendar 2016: the #FHIR is strong in you @HL7 http://t.co/E03Y3NIjME"/>
|
||||
</payload>
|
||||
<medium>
|
||||
<coding>
|
||||
<code value="Twitter"/>
|
||||
</coding>
|
||||
</medium>
|
||||
<sent value="2015-10-03T22:33:54+02:00"/>
|
||||
</Communication>
|
||||
</resource>
|
||||
<request>
|
||||
<method value="PUT"/>
|
||||
<url value="Communication?identifier=http://twitter.com|650408456562823168"/>
|
||||
</request>
|
||||
</entry>
|
||||
</Bundle>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="bundle-transaction"/>
|
||||
<meta>
|
||||
<lastUpdated value="2014-08-18T01:43:30Z"/>
|
||||
</meta>
|
||||
<type value="transaction"/>
|
||||
<entry>
|
||||
<fullUrl value="urn:uuid:61ebe359-bfdc-4613-8bf2-c5e300945f0b"/>
|
||||
<resource>
|
||||
<Medication>
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://snomed.info/sct"/>
|
||||
<code value="408036003"/>
|
||||
<display value="Rosuvastatin 10mg tablet"/>
|
||||
</coding>
|
||||
</code>
|
||||
</Medication>
|
||||
</resource>
|
||||
<request>
|
||||
<method value="POST"/>
|
||||
<url value="Medication"/>
|
||||
<ifNoneExist value="code=408036003"/>
|
||||
</request>o
|
||||
</entry>
|
||||
</Bundle>
|
||||
|
|
@ -98,7 +98,6 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- You may not need this if you are deploying to an application server which provides database connection pools itself. -->
|
||||
|
@ -148,6 +147,11 @@
|
|||
<artifactId>jetty-webapp</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -166,6 +170,9 @@
|
|||
<webApp>
|
||||
<contextPath>/hapi-fhir-jpaserver-example</contextPath>
|
||||
</webApp>
|
||||
<webAppConfig>
|
||||
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
|
||||
</webAppConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.springframework.web.context.WebApplicationContext;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
||||
|
@ -80,7 +81,7 @@ public class JpaServerDemo extends RestfulServer {
|
|||
setServerConformanceProvider(confProvider);
|
||||
} else {
|
||||
IFhirSystemDao<Bundle> systemDao = myAppCtx.getBean("mySystemDaoDstu2", IFhirSystemDao.class);
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao);
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao, myAppCtx.getBean(DaoConfig.class));
|
||||
confProvider.setImplementationDescription("Example Server");
|
||||
setServerConformanceProvider(confProvider);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.springframework.web.context.ContextLoaderListener;
|
|||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
||||
|
@ -83,7 +84,7 @@ public class TestRestfulServer extends RestfulServer {
|
|||
systemProviderDstu2 = myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class);
|
||||
systemDao = myAppCtx.getBean("mySystemDaoDstu2", IFhirSystemDao.class);
|
||||
etagSupport = ETagSupportEnum.ENABLED;
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao);
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao, myAppCtx.getBean(DaoConfig.class));
|
||||
confProvider.setImplementationDescription(implDesc);
|
||||
setServerConformanceProvider(confProvider);
|
||||
baseUrlProperty = "fhir.baseurl.dstu2";
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
package ca.uhn.fhirtest.mvc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.rest.client.GenericClient;
|
||||
import ca.uhn.fhir.to.BaseController;
|
||||
import ca.uhn.fhir.to.model.HomeRequest;
|
||||
|
||||
|
@ -21,6 +30,30 @@ public class SubscriptionPlaygroundController extends BaseController {
|
|||
|
||||
ourLog.info(logPrefix(theModel) + "Displayed subscriptions playground page");
|
||||
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
|
||||
//@formatter:off
|
||||
Bundle resp = client
|
||||
.search()
|
||||
.forResource(Subscription.class)
|
||||
// .where(Subscription.TYPE.exactly().code(SubscriptionChannelTypeEnum.WEBSOCKET.getCode()))
|
||||
// .and(Subscription.STATUS.exactly().code(SubscriptionStatusEnum.ACTIVE.getCode()))
|
||||
.returnBundle(Bundle.class)
|
||||
.sort().descending(Subscription.TYPE)
|
||||
.sort().ascending(Subscription.STATUS)
|
||||
.execute();
|
||||
//@formatter:off
|
||||
|
||||
List<Subscription> subscriptions = new ArrayList<Subscription>();
|
||||
for (Entry next : resp.getEntry()) {
|
||||
if (next.getResource() instanceof Subscription) {
|
||||
subscriptions.add((Subscription) next.getResource());
|
||||
}
|
||||
}
|
||||
|
||||
theModel.put("subscriptions", subscriptions);
|
||||
|
||||
return "subscriptions";
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,24 @@
|
|||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="SUBSCRIPTION_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<file>${fhir.logdir}/subscription.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<fileNamePattern>${fhir.logdir}/subscription.%i.log.zip</fileNamePattern>
|
||||
<minIndex>1</minIndex>
|
||||
<maxIndex>10</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<maxFileSize>5MB</maxFileSize>
|
||||
</triggeringPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{req.remoteAddr}] [%X{req.userAgent}] %-5level %logger{36} %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>DEBUG</level>
|
||||
|
@ -39,19 +57,25 @@
|
|||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="fhirtest.access" level="INFO" additivity="false">
|
||||
<appender-ref ref="ACCESS" />
|
||||
</logger>
|
||||
<logger name="fhirtest.access" level="INFO" additivity="false">
|
||||
<appender-ref ref="ACCESS"/>
|
||||
</logger>
|
||||
|
||||
<logger name="ca.uhn.fhir.jpa.dao.FhirResourceDaoSubscriptionDstu2" additivity="true" level="debug">
|
||||
<appender-ref ref="SUBSCRIPTION_FILE"/>
|
||||
</logger>
|
||||
|
||||
<logger name="ca.uhn.fhir.jpa.subscription" additivity="true" level="debug">
|
||||
<appender-ref ref="SUBSCRIPTION_FILE"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator" additivity="false" level="debug">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="FILE"/>
|
||||
<appender-ref ref="SUBSCRIPTION_FILE"/>
|
||||
</logger>
|
||||
|
||||
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -17,6 +17,7 @@
|
|||
<property name="subscriptionEnabled" value="true"></property>
|
||||
<property name="subscriptionPurgeInactiveAfterSeconds" value="3600" /> <!-- 1 hour -->
|
||||
<property name="subscriptionPollDelay" value="5000"></property>
|
||||
<property name="allowMultipleDelete" value="true"/>
|
||||
</bean>
|
||||
|
||||
<util:list id="myServerInterceptors">
|
||||
|
@ -54,6 +55,8 @@
|
|||
<property name="loggerName" value="fhirtest.access"/>
|
||||
<property name="messageFormat"
|
||||
value="Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]"/>
|
||||
<property name="logExceptions" value="true"/>
|
||||
<property name="errorMessageFormat" value="ERROR - ${requestVerb} ${requestUrl}"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -30,99 +30,153 @@
|
|||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
This page is a test playground for WebSocket Subscriptions
|
||||
</p>
|
||||
<p>This page is a test playground for WebSocket
|
||||
Subscriptions</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#wss"
|
||||
aria-controls="wss" role="tab" data-toggle="tab">Static
|
||||
Websocket</a></li>
|
||||
<li role="presentation"><a href="#wsd" aria-controls="wsd"
|
||||
role="tab" data-toggle="tab">Dynamic Websocket</a></li>
|
||||
</ul>
|
||||
<!-- Subscription Creation -->
|
||||
<div id="subscription_creation">
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="wss">...1</div>
|
||||
|
||||
<!-- Dynamic WebSocket -->
|
||||
<div role="tabpanel" class="tab-pane" id="wsd">
|
||||
<script type="text/javascript">
|
||||
function dwsCreate() {
|
||||
try {
|
||||
var socket = new WebSocket("ws://localhost:8888/websocket/dstu2");
|
||||
alert('Socket Status: '+socket.readyState);
|
||||
|
||||
socket.onopen = function() {
|
||||
alert("Opening Socket: " + socket.readyState);
|
||||
socket.send("bind Observation?");
|
||||
}
|
||||
socket.onmessage = function(msg) {
|
||||
alert("New message: " + msg);
|
||||
}
|
||||
socket.onerror = function(error) {
|
||||
alert("error: " + error);
|
||||
}
|
||||
} catch (exception) {
|
||||
alert('Error'+exception);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
Enter a criteria in the text box below and then click subscribe to
|
||||
create a dynamic subscription and then display the results as they
|
||||
arrive.
|
||||
</div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#wss"
|
||||
aria-controls="wss" role="tab" data-toggle="tab">Static
|
||||
Websocket</a></li>
|
||||
<li role="presentation"><a href="#wsd" aria-controls="wsd"
|
||||
role="tab" data-toggle="tab">Dynamic Websocket</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
|
||||
<!-- Static Websocket -->
|
||||
<div role="tabpanel" class="tab-pane active" id="wss">
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>Criteria</td>
|
||||
<td>Type</td>
|
||||
<td>Status</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr th:each="subscription : ${subscriptions}">
|
||||
<td><a th:href="${subscription.id}" th:text="${subscription.id.toUnqualifiedVersionless().getIdPart()}"/>
|
||||
</td>
|
||||
<td th:text="${subscription.criteria}" style="max-width: 200px;"/>
|
||||
<td th:text="${subscription.channel.type}" />
|
||||
<td th:text="${subscription.status}" />
|
||||
<td>
|
||||
<button th:if="${subscription.channel.type} == 'websocket' AND ${subscription.status} == 'active'" type="button" class="btn btn-default btn-primary btn-block" id="dws_create" th:onclick="'dwsCreate(\'' + ${subscription.id.getIdPart()} + '\');'"> <i class="glyphicon glyphicon-cog"></i> Subscribe</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p th:if="${subscriptions.isEmpty()}">There are
|
||||
currently no subscriptions on this server.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Dynamic WebSocket -->
|
||||
<div role="tabpanel" class="tab-pane" id="wsd">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">Enter a criteria in the text box
|
||||
below and then click subscribe to create a dynamic
|
||||
subscription and then display the results as they arrive.</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="boorder-top: 10px;">
|
||||
<div class="col-sm-7">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">Criteria</div>
|
||||
<input class="form-control"
|
||||
placeholder="e.g: Observation?patient=123" id="dws_criteria" />
|
||||
</div>
|
||||
|
||||
<div class="row" style="boorder-top: 10px;">
|
||||
<div class="col-sm-7">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">
|
||||
Criteria
|
||||
</div>
|
||||
<input class="form-control" placeholder="e.g: Observation?patient=123" id="dws_criteria"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<button type="button" class="btn btn-default btn-primary btn-block" id="dws_create" onclick="dwsCreate();"><i class="glyphicon glyphicon-cog"></i> Subscribe</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<button type="button"
|
||||
class="btn btn-default btn-primary btn-block" id="dws_create"
|
||||
onclick="dwsCreate(document.getElementById('dws_criteria').value, true);">
|
||||
<i class="glyphicon glyphicon-cog"></i> Subscribe
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Dynamic Subscription Results -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Subscription Results</div>
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
This will be status...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- List group -->
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">Cras justo odio</li>
|
||||
<li class="list-group-item">Dapibus ac facilisis in</li>
|
||||
<li class="list-group-item">Morbi leo risus</li>
|
||||
<li class="list-group-item">Porta ac consectetur ac</li>
|
||||
<li class="list-group-item">Vestibulum at eros</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Subscription Results -->
|
||||
<div class="panel panel-default" style="display: none;"
|
||||
id="resultsDiv">
|
||||
<div class="panel-heading">Subscription Results</div>
|
||||
<ul class="list-group" id="subscription_status_list">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function messageStatus(message) {
|
||||
var listItem = $('<li />', {
|
||||
'class' : 'list-group-item'
|
||||
});
|
||||
listItem.append($('<div class="glyphicon glyphicon-info-sign" style="width: 20px;"/>'));
|
||||
listItem.append($('<span>' + message + '</span>'));
|
||||
$('#subscription_status_list').append(listItem);
|
||||
}
|
||||
|
||||
function messageIn(message, remainder) {
|
||||
var listItem = $('<li />', {
|
||||
'class' : 'list-group-item'
|
||||
});
|
||||
listItem.append($('<div class="glyphicon glyphicon-download" style="width: 20px;"/>'));
|
||||
listItem.append($('<span>' + message + '</span>'));
|
||||
if (remainder) {
|
||||
listItem.append($('<p>(' + remainder + ' bytes)</p>'));
|
||||
listItem.append($('<pre style="display:none;"/>').text(remainder));
|
||||
}
|
||||
$('#subscription_status_list').append(listItem);
|
||||
}
|
||||
|
||||
function dwsCreate(bindArgument, dynamic) {
|
||||
$('#resultsDiv').css("display", "");
|
||||
$('#subscription_creation').hide();
|
||||
try {
|
||||
var url = "ws://fhirtest.uhn.ca/websocket/dstu2";
|
||||
messageStatus("Connecting to: " + url);
|
||||
var socket = new WebSocket(url);
|
||||
|
||||
socket.onopen = function() {
|
||||
messageStatus("Connected to: " + url);
|
||||
$('#subscription_status_list').append($('<li />', {
|
||||
'class' : 'list-group-item'
|
||||
}).append($('<div class="glyphicon glyphicon-upload" style="width: 20px;"/>')).append($('<span>bind ' + bindArgument + '</span>')));
|
||||
socket.send("bind " + bindArgument);
|
||||
}
|
||||
|
||||
// This function is called when a new message comes from the server
|
||||
socket.onmessage = function(msg) {
|
||||
var data = msg.data;
|
||||
var remainder = null;
|
||||
if (data.indexOf('\n') != -1) {
|
||||
data = data.substring(0, data.indexOf('\n'));
|
||||
remainder = data.substring(data.indexOf('\n') + 1);
|
||||
}
|
||||
messageIn(data, remainder);
|
||||
}
|
||||
socket.onerror = function(error) {
|
||||
messageStatus("Error: " + error);
|
||||
}
|
||||
} catch (exception) {
|
||||
messageStatus("Error: " + exception);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
|||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
|
@ -21,7 +24,7 @@ public class UhnFhirTestApp {
|
|||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int myPort = 8888;
|
||||
String base = "http://localhost:" + myPort + "/base";
|
||||
String base = "http://localhost:" + myPort + "/baseDstu2";
|
||||
|
||||
// new File("target/testdb").mkdirs();
|
||||
System.setProperty("fhir.db.location", "./target/testdb");
|
||||
|
@ -47,13 +50,13 @@ public class UhnFhirTestApp {
|
|||
// base = "http://spark.furore.com/fhir";
|
||||
|
||||
if (true) {
|
||||
FhirContext ctx = new FhirContext();
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IGenericClient client = ctx.newRestfulGenericClient(base);
|
||||
// client.setLogRequestAndResponse(true);
|
||||
|
||||
Organization o1 = new Organization();
|
||||
o1.getName().setValue("Some Org");
|
||||
MethodOutcome create = client.create(o1);
|
||||
MethodOutcome create = client.create().resource(o1).execute();
|
||||
IdDt orgId = (IdDt) create.getId();
|
||||
|
||||
Patient p1 = new Patient();
|
||||
|
@ -64,11 +67,14 @@ public class UhnFhirTestApp {
|
|||
TagList list = new TagList();
|
||||
list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource");
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put(p1, list);
|
||||
client.create(p1);
|
||||
|
||||
List<IResource> resources = ctx.newJsonParser().parseBundle(IOUtils.toString(UhnFhirTestApp.class.getResourceAsStream("/bundle.json"))).toListOfResources();
|
||||
// client.transaction().withResources(resources).execute();
|
||||
client.create().resource(p1).execute();
|
||||
|
||||
Subscription subs = new Subscription();
|
||||
subs.setStatus(SubscriptionStatusEnum.ACTIVE);
|
||||
subs.getChannel().setType(SubscriptionChannelTypeEnum.WEBSOCKET);
|
||||
subs.setCriteria("Observation?");
|
||||
client.create().resource(subs).execute();
|
||||
|
||||
// for (int i = 0; i < 1000; i++) {
|
||||
//
|
||||
// Patient p = (Patient) resources.get(0);
|
||||
|
@ -78,22 +84,22 @@ public class UhnFhirTestApp {
|
|||
// client.transaction(resources);
|
||||
// }
|
||||
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create(p1);
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
client.create().resource(p1).execute();
|
||||
|
||||
client.create(p1);
|
||||
client.create().resource(p1).execute();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<Embed-Dependency>*;scope=!provided|test</Embed-Dependency>
|
||||
<Embed-Directory>lib</Embed-Directory>
|
||||
<Embed-Transitive>true</Embed-Transitive>
|
||||
<_removeheaders>Built-By</_removeheaders>
|
||||
<_removeheaders>Built-By, Include-Resource, Private-Package</_removeheaders>
|
||||
<!-- <Private-Package>org.foo.myproject.*</Private-Package> <Bundle-Activator>org.foo.myproject.impl1.Activator</Bundle-Activator> -->
|
||||
</instructions>
|
||||
</configuration>
|
||||
|
@ -70,6 +70,24 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<phase>integration-test</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package ca.uhn.fhir.osgi;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.FileReader;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ManifestIT {
|
||||
|
||||
/**
|
||||
* See #234
|
||||
*/
|
||||
@Test
|
||||
public void testValidateManifest() throws Exception {
|
||||
|
||||
FileReader r = new FileReader("./target/classes/META-INF/MANIFEST.MF");
|
||||
String file = IOUtils.toString(r);
|
||||
|
||||
assertThat(file, not(containsString(".jar=/")));
|
||||
}
|
||||
|
||||
}
|
|
@ -178,7 +178,12 @@ public class GenericClientTest {
|
|||
assertThat(extractBody(capt, count), containsString("value=\"John\""));
|
||||
count++;
|
||||
|
||||
client.create().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).execute();
|
||||
String resourceAsString = ourCtx.newJsonParser().encodeResourceToString(p1);
|
||||
client
|
||||
.create()
|
||||
.resource(resourceAsString)
|
||||
.execute();
|
||||
|
||||
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, count), containsString("[\"John\"]"));
|
||||
|
|
|
@ -69,9 +69,6 @@ import ca.uhn.fhir.rest.param.TokenOrListParam;
|
|||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class SearchSearchServerDstu1Test {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
@ -559,9 +556,6 @@ public class SearchSearchServerDstu1Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,6 +54,39 @@ public class JsonParserDstu2Test {
|
|||
private static final FhirContext ourCtx = FhirContext.forDstu2();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserDstu2Test.class);
|
||||
|
||||
@Test
|
||||
public void testNamespacePreservationEncode() throws Exception {
|
||||
//@formatter:off
|
||||
String input = "<Patient xmlns=\"http://hl7.org/fhir\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">" +
|
||||
"<text>" +
|
||||
"<xhtml:div>" +
|
||||
"<xhtml:img src=\"foo\"/>" +
|
||||
"@fhirabend" +
|
||||
"</xhtml:div>" +
|
||||
"</text>" +
|
||||
"</Patient>";
|
||||
//@formatter:on
|
||||
Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, input);
|
||||
|
||||
String expected = "<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><xhtml:img src=\"foo\"/>@fhirabend</xhtml:div>";
|
||||
assertEquals(expected, parsed.getText().getDiv().getValueAsString());
|
||||
|
||||
String encoded = ourCtx.newJsonParser().encodeResourceToString(parsed);
|
||||
ourLog.info(encoded);
|
||||
assertThat(encoded, containsString("\"div\":\"" + expected.replace("\"", "\\\"") + "\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamespacePreservationParse() throws Exception {
|
||||
String input = "{\"resourceType\":\"Patient\",\"text\":{\"div\":\"<xhtml:div xmlns:xhtml=\\\"http://www.w3.org/1999/xhtml\\\"><xhtml:img src=\\\"foo\\\"/>@fhirabend</xhtml:div>\"}}";
|
||||
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, input);
|
||||
|
||||
assertEquals("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><xhtml:img src=\"foo\"/>@fhirabend</xhtml:div>", parsed.getText().getDiv().getValueAsString());
|
||||
|
||||
String encoded = ourCtx.newXmlParser().encodeResourceToString(parsed);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><text><xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><xhtml:img src=\"foo\"/>@fhirabend</xhtml:div></text></Patient>",encoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseExtensions() throws Exception {
|
||||
|
||||
|
@ -98,8 +131,10 @@ public class JsonParserDstu2Test {
|
|||
assertThat(enc, Matchers.stringContainsInOrder("{\"resourceType\":\"Patient\",", "\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
|
||||
"{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"));
|
||||
assertThat(enc, Matchers.stringContainsInOrder("\"modifierExtension\":[" + "{" + "\"url\":\"http://example.com/extensions#modext\"," + "\"valueDate\":\"1995-01-02\"" + "}" + "],"));
|
||||
assertThat(enc, containsString("\"_given\":[" + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext\"," + "\"valueString\":\"given\"" + "}" + "]" + "}," + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext_parent\"," + "\"extension\":[" + "{"
|
||||
+ "\"url\":\"http://examples.com#givenext_child\"," + "\"valueString\":\"CHILD\"" + "}" + "]" + "}" + "]" + "}"));
|
||||
assertThat(enc,
|
||||
containsString("\"_given\":[" + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext\"," + "\"valueString\":\"given\"" + "}" + "]" + "}," + "{" + "\"extension\":[" + "{"
|
||||
+ "\"url\":\"http://examples.com#givenext_parent\"," + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext_child\"," + "\"valueString\":\"CHILD\"" + "}" + "]" + "}"
|
||||
+ "]" + "}"));
|
||||
|
||||
/*
|
||||
* Now parse this back
|
||||
|
@ -402,7 +437,8 @@ public class JsonParserDstu2Test {
|
|||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, containsString("Patient"));
|
||||
assertThat(encoded, stringContainsInOrder("\"tag\"", "\"system\":\"foo\",", "\"code\":\"bar\"", "\"system\":\"" + Constants.TAG_SUBSETTED_SYSTEM + "\",", "\"code\":\"" + Constants.TAG_SUBSETTED_CODE + "\","));
|
||||
assertThat(encoded, stringContainsInOrder("\"tag\"", "\"system\":\"foo\",", "\"code\":\"bar\"", "\"system\":\"" + Constants.TAG_SUBSETTED_SYSTEM + "\",",
|
||||
"\"code\":\"" + Constants.TAG_SUBSETTED_CODE + "\","));
|
||||
assertThat(encoded, not(containsString("THE DIV")));
|
||||
assertThat(encoded, containsString("family"));
|
||||
assertThat(encoded, not(containsString("maritalStatus")));
|
||||
|
@ -423,7 +459,8 @@ public class JsonParserDstu2Test {
|
|||
String enc = ourCtx.newJsonParser().encodeResourceToString(pt);
|
||||
ourLog.info(enc);
|
||||
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"meta\":{\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"display\"}]},\"identifier\":[{\"system\":\"sys\",\"value\":\"val\"}]}", enc);
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"meta\":{\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"display\"}]},\"identifier\":[{\"system\":\"sys\",\"value\":\"val\"}]}",
|
||||
enc);
|
||||
|
||||
}
|
||||
|
||||
|
@ -517,7 +554,7 @@ public class JsonParserDstu2Test {
|
|||
assertEquals(exp, act);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for #146
|
||||
*/
|
||||
|
@ -636,9 +673,9 @@ public class JsonParserDstu2Test {
|
|||
String content = IOUtils.toString(JsonParserDstu2Test.class.getResourceAsStream("/bundle-transaction2.json"));
|
||||
|
||||
ourCtx.newJsonParser().parseBundle(content);
|
||||
|
||||
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newJsonParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, content);
|
||||
|
||||
|
||||
// TODO: preserve comments
|
||||
}
|
||||
|
||||
|
@ -857,7 +894,7 @@ public class JsonParserDstu2Test {
|
|||
assertEquals(exp, act);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParsePatientInBundle() {
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
|||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -42,6 +43,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Link;
|
||||
|
@ -69,8 +71,11 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
|
|||
public class GenericClientDstu2Test {
|
||||
private static FhirContext ourCtx;
|
||||
private HttpClient myHttpClient;
|
||||
|
||||
private HttpResponse myHttpResponse;
|
||||
|
||||
private int myResponseCount = 0;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
|
@ -106,6 +111,133 @@ public class GenericClientDstu2Test {
|
|||
return msg;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderFetchConformance() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
client.fetchConformance().ofType(Conformance.class).execute();
|
||||
assertEquals("http://example.com/fhir/metadata", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
idx++;
|
||||
|
||||
client.fetchConformance().ofType(Conformance.class).encodedJson().execute();
|
||||
assertEquals("http://example.com/fhir/metadata?_format=json", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
idx++;
|
||||
|
||||
client.fetchConformance().ofType(Conformance.class).encodedXml().execute();
|
||||
assertEquals("http://example.com/fhir/metadata?_format=xml", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderPreflightConformance() throws Exception {
|
||||
String methodName = "testAcceptHeaderPreflightConformance";
|
||||
final IParser p = ourCtx.newXmlParser();
|
||||
|
||||
final Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAMILY");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myResponseCount++ == 0) {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(conf)), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(patient)), Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://" + methodName + ".example.com/fhir");
|
||||
|
||||
Patient resp = client.read(Patient.class, new IdDt("123"));
|
||||
assertEquals("FAMILY", resp.getName().get(0).getFamily().get(0).getValue());
|
||||
assertEquals("http://" + methodName + ".example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertEquals("http://" + methodName + ".example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderPreflightConformancePreferJson() throws Exception {
|
||||
String methodName = "testAcceptHeaderPreflightConformancePreferJson";
|
||||
final IParser p = ourCtx.newXmlParser();
|
||||
|
||||
final Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAMILY");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myResponseCount++ == 0) {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(conf)), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(patient)), Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://" + methodName + ".example.com/fhir");
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
|
||||
Patient resp = client.read(Patient.class, new IdDt("123"));
|
||||
assertEquals("FAMILY", resp.getName().get(0).getFamily().get(0).getValue());
|
||||
assertEquals("http://" + methodName + ".example.com/fhir/metadata?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
assertEquals("http://" + methodName + ".example.com/fhir/Patient/123?_format=json", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testConformance() throws Exception {
|
||||
|
@ -141,136 +273,6 @@ public class GenericClientDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderFetchConformance() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Conformance resp = (Conformance)client.fetchConformance().ofType(Conformance.class).execute();
|
||||
assertEquals("http://example.com/fhir/metadata", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
idx++;
|
||||
|
||||
resp = (Conformance)client.fetchConformance().ofType(Conformance.class).encodedJson().execute();
|
||||
assertEquals("http://example.com/fhir/metadata?_format=json", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
idx++;
|
||||
|
||||
resp = (Conformance)client.fetchConformance().ofType(Conformance.class).encodedXml().execute();
|
||||
assertEquals("http://example.com/fhir/metadata?_format=xml", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(idx).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
idx++;
|
||||
}
|
||||
|
||||
private int myResponseCount = 0;
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderPreflightConformancePreferJson() throws Exception {
|
||||
String methodName = "testAcceptHeaderPreflightConformancePreferJson";
|
||||
final IParser p = ourCtx.newXmlParser();
|
||||
|
||||
final Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAMILY");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myResponseCount++ == 0) {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(conf)), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(patient)), Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://"+methodName+".example.com/fhir");
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
|
||||
Patient resp = client.read(Patient.class, new IdDt("123"));
|
||||
assertEquals("FAMILY", resp.getName().get(0).getFamily().get(0).getValue());
|
||||
assertEquals("http://"+methodName+".example.com/fhir/metadata?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
assertEquals("http://"+methodName+".example.com/fhir/Patient/123?_format=json", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderPreflightConformance() throws Exception {
|
||||
String methodName = "testAcceptHeaderPreflightConformance";
|
||||
final IParser p = ourCtx.newXmlParser();
|
||||
|
||||
final Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAMILY");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myResponseCount++ == 0) {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(conf)), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(patient)), Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://"+methodName+".example.com/fhir");
|
||||
|
||||
Patient resp = client.read(Patient.class, new IdDt("123"));
|
||||
assertEquals("FAMILY", resp.getName().get(0).getFamily().get(0).getValue());
|
||||
assertEquals("http://"+methodName+".example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertEquals("http://"+methodName+".example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -382,44 +384,6 @@ public class GenericClientDstu2Test {
|
|||
idx++;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testUpdateNonFluent() throws Exception {
|
||||
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), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
client.update(new IdDt("Patient/123"), p);
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
client.update("123", p);
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreatePrefer() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -450,7 +414,7 @@ public class GenericClientDstu2Test {
|
|||
idx++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateReturningResourceBody() throws Exception {
|
||||
Patient p = new Patient();
|
||||
|
@ -535,7 +499,7 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("DELETE", capt.getAllValues().get(idx).getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
|
||||
client.delete(Patient.class, "123");
|
||||
assertEquals("DELETE", capt.getAllValues().get(idx).getMethod());
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
|
@ -631,7 +595,8 @@ public class GenericClientDstu2Test {
|
|||
.since(new InstantDt("2001-01-02T11:22:33Z"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertThat(capt.getAllValues().get(idx).getURI().toString(), either(equalTo("http://example.com/fhir/Patient/123/_history?_since=2001-01-02T11:22:33Z&_count=123")).or(equalTo("http://example.com/fhir/Patient/123/_history?_count=123&_since=2001-01-02T11:22:33Z")));
|
||||
assertThat(capt.getAllValues().get(idx).getURI().toString(), either(equalTo("http://example.com/fhir/Patient/123/_history?_since=2001-01-02T11:22:33Z&_count=123"))
|
||||
.or(equalTo("http://example.com/fhir/Patient/123/_history?_count=123&_since=2001-01-02T11:22:33Z")));
|
||||
assertEquals(1, response.getEntry().size());
|
||||
idx++;
|
||||
|
||||
|
@ -646,7 +611,7 @@ public class GenericClientDstu2Test {
|
|||
assertThat(capt.getAllValues().get(idx).getURI().toString(), containsString("_since=2001-01"));
|
||||
assertEquals(1, response.getEntry().size());
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaAdd() throws Exception {
|
||||
|
@ -684,12 +649,12 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("http://example.com/fhir/Patient/123/$meta-add", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("urn:profile:out", resp.getProfile().get(0).getValue());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"meta\"/><valueMeta><profile value=\"urn:profile:in\"/></valueMeta></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"meta\"/><valueMeta><profile value=\"urn:profile:in\"/></valueMeta></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMetaGet() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
@ -946,9 +911,8 @@ public class GenericClientDstu2Test {
|
|||
Parameters outParams = client.operation().onInstance(new IdDt("Patient", "18066")).named("$everything").withParameters(inParams).execute();
|
||||
|
||||
/*
|
||||
* Note that the $everything operation returns a Bundle instead of a Parameters resource. The client operation
|
||||
* methods return a Parameters instance however, so HAPI creates a Parameters object with a single parameter
|
||||
* containing the value.
|
||||
* Note that the $everything operation returns a Bundle instead of a Parameters resource. The client operation methods return a Parameters instance however, so HAPI creates a Parameters object
|
||||
* with a single parameter containing the value.
|
||||
*/
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle responseBundle = (ca.uhn.fhir.model.dstu2.resource.Bundle) outParams.getParameter().get(0).getResource();
|
||||
|
||||
|
@ -1001,6 +965,121 @@ public class GenericClientDstu2Test {
|
|||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithInlineParams() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
Parameters outParams = new Parameters();
|
||||
outParams.addParameter().setValue(new StringDt("STRINGVALOUT1"));
|
||||
outParams.addParameter().setValue(new StringDt("STRINGVALOUT2"));
|
||||
final String respString = p.encodeResourceToString(outParams);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
Parameters resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameter(Parameters.class, "name1", new StringDt("value1"))
|
||||
.andParameter("name2", new StringDt("value1"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"name1\"/><valueString value=\"value1\"/></parameter><parameter><name value=\"name2\"/><valueString value=\"value1\"/></parameter></Parameters>",
|
||||
(extractBody(capt, idx)));
|
||||
idx++;
|
||||
|
||||
/*
|
||||
* Composite type
|
||||
*/
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameter(Parameters.class, "name1", new IdentifierDt("system1", "value1"))
|
||||
.andParameter("name2", new StringDt("value1"))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"name1\"/><valueIdentifier><system value=\"system1\"/><value value=\"value1\"/></valueIdentifier></parameter><parameter><name value=\"name2\"/><valueString value=\"value1\"/></parameter></Parameters>",
|
||||
(extractBody(capt, idx)));
|
||||
idx++;
|
||||
|
||||
/*
|
||||
* Resource
|
||||
*/
|
||||
|
||||
//@formatter:off
|
||||
resp = client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameter(Parameters.class, "name1", new IdentifierDt("system1", "value1"))
|
||||
.andParameter("name2", new Patient().setActive(true))
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/$SOMEOPERATION", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals(respString, p.encodeResourceToString(resp));
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"name1\"/><valueIdentifier><system value=\"system1\"/><value value=\"value1\"/></valueIdentifier></parameter><parameter><name value=\"name2\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><active value=\"true\"/></Patient></resource></parameter></Parameters>",
|
||||
(extractBody(capt, idx)));
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testOperationWithInvalidParam() {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
// Who knows what the heck this is!
|
||||
IBase weirdBase = new IBase() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//@formatter:off
|
||||
client
|
||||
.operation()
|
||||
.onServer()
|
||||
.named("$SOMEOPERATION")
|
||||
.withParameter(Parameters.class, "name1", weirdBase)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationWithListOfParameterResponse() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
@ -1315,11 +1394,7 @@ public class GenericClientDstu2Test {
|
|||
Patient response;
|
||||
|
||||
int idx = 0;
|
||||
response = (Patient)client
|
||||
.read()
|
||||
.resource(Patient.class)
|
||||
.withUrl(new IdDt("http://domain2.example.com/base/Patient/123"))
|
||||
.execute();
|
||||
response = (Patient) client.read().resource(Patient.class).withUrl(new IdDt("http://domain2.example.com/base/Patient/123")).execute();
|
||||
assertEquals("http://domain2.example.com/base/Patient/123", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("FAM", response.getName().get(0).getFamily().get(0).getValue());
|
||||
}
|
||||
|
@ -1369,7 +1444,7 @@ public class GenericClientDstu2Test {
|
|||
|
||||
assertEquals("2015-06-22T15:48:57.554-04:00", ResourceMetadataKeyEnum.UPDATED.get(response).getValueAsString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReadWithElementsParam() throws Exception {
|
||||
String msg = "{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}";
|
||||
|
@ -1390,7 +1465,8 @@ public class GenericClientDstu2Test {
|
|||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertThat(capt.getValue().getURI().toString(), either(equalTo("http://example.com/fhir/Patient/123?_elements=name%2Cidentifier")).or(equalTo("http://example.com/fhir/Patient/123?_elements=identifier%2Cname")));
|
||||
assertThat(capt.getValue().getURI().toString(),
|
||||
either(equalTo("http://example.com/fhir/Patient/123?_elements=name%2Cidentifier")).or(equalTo("http://example.com/fhir/Patient/123?_elements=identifier%2Cname")));
|
||||
assertEquals(Patient.class, response.getClass());
|
||||
|
||||
}
|
||||
|
@ -1420,8 +1496,7 @@ public class GenericClientDstu2Test {
|
|||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testReadWithSummaryParamHtml() throws Exception {
|
||||
String msg = "<div>HELP IM A DIV</div>";
|
||||
|
@ -1524,7 +1599,8 @@ public class GenericClientDstu2Test {
|
|||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertThat(capt.getValue().getURI().toString(), either(equalTo("http://example.com/fhir/Patient?name=james&_elements=name%2Cidentifier")).or(equalTo("http://example.com/fhir/Patient?name=james&_elements=identifier%2Cname")));
|
||||
assertThat(capt.getValue().getURI().toString(),
|
||||
either(equalTo("http://example.com/fhir/Patient?name=james&_elements=name%2Cidentifier")).or(equalTo("http://example.com/fhir/Patient?name=james&_elements=identifier%2Cname")));
|
||||
assertEquals(Patient.class, response.getEntries().get(0).getResource().getClass());
|
||||
|
||||
}
|
||||
|
@ -1835,6 +1911,43 @@ public class GenericClientDstu2Test {
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testUpdateNonFluent() throws Exception {
|
||||
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), Constants.STATUS_HTTP_204_NO_CONTENT, ""));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
int idx = 0;
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("FOOFAMILY");
|
||||
|
||||
client.update(new IdDt("Patient/123"), p);
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
|
||||
client.update("123", p);
|
||||
assertEquals(1, capt.getAllValues().get(idx).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
|
||||
assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
|
||||
assertThat(extractBody(capt, idx), containsString("<family value=\"FOOFAMILY\"/>"));
|
||||
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(idx).getURI().toString());
|
||||
assertEquals("PUT", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
idx++;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePrefer() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
|
@ -1924,7 +2037,9 @@ public class GenericClientDstu2Test {
|
|||
response = client.validate().resource(p).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDiagnosticsElement().getValue());
|
||||
idx++;
|
||||
|
@ -1932,7 +2047,9 @@ public class GenericClientDstu2Test {
|
|||
response = client.validate().resource(ourCtx.newXmlParser().encodeResourceToString(p)).execute();
|
||||
assertEquals("http://example.com/fhir/Patient/$validate?_format=xml", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDiagnosticsElement().getValue());
|
||||
idx++;
|
||||
|
@ -1986,7 +2103,9 @@ public class GenericClientDstu2Test {
|
|||
|
||||
assertEquals("http://example.com/fhir/Patient/$validate", capt.getAllValues().get(idx).getURI().toASCIIString());
|
||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||
assertEquals(
|
||||
"<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>",
|
||||
extractBody(capt, idx));
|
||||
assertNotNull(response.getOperationOutcome());
|
||||
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDiagnosticsElement().getValue());
|
||||
idx++;
|
||||
|
|
|
@ -46,6 +46,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
|
|||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -78,6 +79,30 @@ public class LoggingInterceptorDstu2Test {
|
|||
assertThat(captor.getValue(), StringContains.containsString("read - Patient/1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testException() throws Exception {
|
||||
|
||||
LoggingInterceptor interceptor = new LoggingInterceptor();
|
||||
interceptor.setLogExceptions(true);
|
||||
assertTrue(interceptor.isLogExceptions());
|
||||
interceptor.setErrorMessageFormat("ERROR - ${requestVerb} ${requestUrl}");
|
||||
assertEquals("ERROR - ${requestVerb} ${requestUrl}", interceptor.getErrorMessageFormat());
|
||||
|
||||
servlet.setInterceptors(Collections.singletonList((IServerInterceptor) interceptor));
|
||||
|
||||
Logger logger = mock(Logger.class);
|
||||
interceptor.setLogger(logger);
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/EX");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(logger, times(2)).info(captor.capture());
|
||||
assertThat(captor.getAllValues().get(0), StringContains.containsString("read - Patient/EX"));
|
||||
assertThat(captor.getAllValues().get(1), StringContains.containsString("ERROR - GET http://localhost:"+ourPort+"/Patient/EX"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearch() throws Exception {
|
||||
|
||||
|
@ -242,6 +267,9 @@ public class LoggingInterceptorDstu2Test {
|
|||
*/
|
||||
@Read()
|
||||
public Patient getResourceById(@IdParam IdDt theId) {
|
||||
if (theId.getIdPart().equals("EX")) {
|
||||
throw new InvalidRequestException("FOO");
|
||||
}
|
||||
String key = theId.getIdPart();
|
||||
Patient retVal = getIdToPatient().get(key);
|
||||
return retVal;
|
||||
|
|
|
@ -14,22 +14,8 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.formats.IParser;
|
||||
import org.hl7.fhir.instance.formats.ParserType;
|
||||
import org.hl7.fhir.instance.model.ConceptMap;
|
||||
import org.hl7.fhir.instance.model.OperationOutcome.IssueSeverity;
|
||||
import org.hl7.fhir.instance.model.Resource;
|
||||
import org.hl7.fhir.instance.model.StructureDefinition;
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.instance.terminologies.ValueSetExpander;
|
||||
import org.hl7.fhir.instance.terminologies.ValueSetExpanderFactory;
|
||||
import org.hl7.fhir.instance.terminologies.ValueSetExpanderSimple;
|
||||
import org.hl7.fhir.instance.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.instance.utils.INarrativeGenerator;
|
||||
import org.hl7.fhir.instance.utils.IWorkerContext;
|
||||
import org.hl7.fhir.instance.validation.IResourceValidator;
|
||||
import org.hl7.fhir.instance.validation.IResourceValidator.BestPracticeWarningLevel;
|
||||
import org.hl7.fhir.instance.validation.ValidationMessage;
|
||||
import org.w3c.dom.Document;
|
||||
|
@ -46,7 +32,6 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.validation.IValidationSupport.CodeValidationResult;
|
||||
|
||||
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
||||
|
||||
|
@ -151,7 +136,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
|||
}
|
||||
|
||||
protected List<ValidationMessage> validate(final FhirContext theCtx, String theInput, EncodingEnum theEncoding) {
|
||||
HapiWorkerContext workerContext = new HapiWorkerContext(theCtx);
|
||||
HapiWorkerContext workerContext = new HapiWorkerContext(theCtx, myValidationSupport);
|
||||
|
||||
org.hl7.fhir.instance.validation.InstanceValidator v;
|
||||
try {
|
||||
|
@ -260,125 +245,4 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
|||
return profile;
|
||||
}
|
||||
|
||||
private final class HapiWorkerContext implements IWorkerContext, ValueSetExpanderFactory, ValueSetExpander {
|
||||
private final FhirContext myCtx;
|
||||
|
||||
private HapiWorkerContext(FhirContext theCtx) {
|
||||
myCtx = theCtx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandVS(ConceptSetComponent theInc) {
|
||||
return myValidationSupport.expandValueSet(myCtx, theInc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet theSource) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet fetchCodeSystem(String theSystem) {
|
||||
if (myValidationSupport == null) {
|
||||
return null;
|
||||
} else {
|
||||
return myValidationSupport.fetchCodeSystem(myCtx, theSystem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Resource> T fetchResource(Class<T> theClass, String theUri) throws EOperationOutcome, Exception {
|
||||
if (myValidationSupport == null) {
|
||||
return null;
|
||||
} else {
|
||||
return myValidationSupport.fetchResource(myCtx, theClass, theUri);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public INarrativeGenerator getNarrativeGenerator(String thePrefix, String theBasePath) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser getParser(ParserType theType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser getParser(String theType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Resource> boolean hasResource(Class<T> theClass_, String theUri) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser newJsonParser() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceValidator newValidator() throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser newXmlParser() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSystem(String theSystem) {
|
||||
if (myValidationSupport == null) {
|
||||
return false;
|
||||
} else {
|
||||
return myValidationSupport.isCodeSystemSupported(myCtx, theSystem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay) {
|
||||
CodeValidationResult result = myValidationSupport.validateCode(myCtx, theSystem, theCode, theDisplay);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return new ValidationResult(result.getSeverity(), result.getMessage(), result.asConceptDefinition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay,
|
||||
ConceptSetComponent theVsi) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay, ValueSet theVs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpander getExpander() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expand(ValueSet theSource) throws ETooCostly, Exception {
|
||||
ValueSetExpander vse = new ValueSetExpanderSimple(this, this);
|
||||
ValueSetExpansionOutcome vso = vse.expand(theSource);
|
||||
if (vso.getError() != null) {
|
||||
return null;
|
||||
} else {
|
||||
return vso;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConceptMap> findMapsForSource(String theUrl) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.formats.IParser;
|
||||
import org.hl7.fhir.instance.formats.ParserType;
|
||||
import org.hl7.fhir.instance.model.ConceptMap;
|
||||
import org.hl7.fhir.instance.model.Resource;
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.instance.terminologies.ValueSetExpander;
|
||||
import org.hl7.fhir.instance.terminologies.ValueSetExpanderFactory;
|
||||
import org.hl7.fhir.instance.terminologies.ValueSetExpanderSimple;
|
||||
import org.hl7.fhir.instance.utils.EOperationOutcome;
|
||||
import org.hl7.fhir.instance.utils.INarrativeGenerator;
|
||||
import org.hl7.fhir.instance.utils.IWorkerContext;
|
||||
import org.hl7.fhir.instance.validation.IResourceValidator;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.IValidationSupport.CodeValidationResult;
|
||||
|
||||
public final class HapiWorkerContext implements IWorkerContext, ValueSetExpanderFactory, ValueSetExpander {
|
||||
private final FhirContext myCtx;
|
||||
private IValidationSupport myValidationSupport;
|
||||
|
||||
public HapiWorkerContext(FhirContext theCtx, IValidationSupport theValidationSupport) {
|
||||
myCtx = theCtx;
|
||||
myValidationSupport = theValidationSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandVS(ConceptSetComponent theInc) {
|
||||
return myValidationSupport.expandValueSet(myCtx, theInc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet theSource) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet fetchCodeSystem(String theSystem) {
|
||||
if (myValidationSupport == null) {
|
||||
return null;
|
||||
} else {
|
||||
return myValidationSupport.fetchCodeSystem(myCtx, theSystem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Resource> T fetchResource(Class<T> theClass, String theUri) throws EOperationOutcome, Exception {
|
||||
if (myValidationSupport == null) {
|
||||
return null;
|
||||
} else {
|
||||
return myValidationSupport.fetchResource(myCtx, theClass, theUri);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public INarrativeGenerator getNarrativeGenerator(String thePrefix, String theBasePath) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser getParser(ParserType theType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser getParser(String theType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Resource> boolean hasResource(Class<T> theClass_, String theUri) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser newJsonParser() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResourceValidator newValidator() throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParser newXmlParser() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSystem(String theSystem) {
|
||||
if (myValidationSupport == null) {
|
||||
return false;
|
||||
} else {
|
||||
return myValidationSupport.isCodeSystemSupported(myCtx, theSystem);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay) {
|
||||
CodeValidationResult result = myValidationSupport.validateCode(myCtx, theSystem, theCode, theDisplay);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
return new ValidationResult(result.getSeverity(), result.getMessage(), result.asConceptDefinition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay,
|
||||
ConceptSetComponent theVsi) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay, ValueSet theVs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpander getExpander() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionOutcome expand(ValueSet theSource) throws ETooCostly, Exception {
|
||||
ValueSetExpander vse = new ValueSetExpanderSimple(this, this);
|
||||
ValueSetExpansionOutcome vso = vse.expand(theSource);
|
||||
if (vso.getError() != null) {
|
||||
return null;
|
||||
} else {
|
||||
return vso;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConceptMap> findMapsForSource(String theUrl) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package ca.uhn.fhir.tinder;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
|
||||
import ca.uhn.fhir.tinder.parser.CompartmentParser;
|
||||
|
||||
public class CompartmentGeneratorMojo extends AbstractMojo {
|
||||
|
||||
@Parameter(required = true)
|
||||
private String fhirVersion;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
CompartmentParser p = new CompartmentParser(fhirVersion);
|
||||
try {
|
||||
p.parse();
|
||||
} catch (MojoExecutionException e) {
|
||||
throw e;
|
||||
} catch (MojoFailureException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failure during parse", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws MojoExecutionException, MojoFailureException {
|
||||
CompartmentGeneratorMojo mojo = new CompartmentGeneratorMojo();
|
||||
mojo.fhirVersion = "dstu2";
|
||||
mojo.execute();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package ca.uhn.fhir.tinder.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CompartmentDef {
|
||||
|
||||
private String myOwnerResourceName;
|
||||
private List<Target> myTargets;
|
||||
|
||||
public String getOwnerResourceName() {
|
||||
return myOwnerResourceName;
|
||||
}
|
||||
|
||||
public List<Target> getTargets() {
|
||||
if (myTargets == null) {
|
||||
myTargets = new ArrayList<Target>();
|
||||
}
|
||||
|
||||
return myTargets;
|
||||
}
|
||||
|
||||
public void setOwnerResourceName(String theOwnerResourceName) {
|
||||
myOwnerResourceName = theOwnerResourceName;
|
||||
}
|
||||
|
||||
public void setTargets(List<Target> theTargets) {
|
||||
myTargets = theTargets;
|
||||
}
|
||||
|
||||
public class Target {
|
||||
private List<String> myPaths;
|
||||
private String myResourceName;
|
||||
|
||||
public List<String> getPaths() {
|
||||
if (myPaths == null) {
|
||||
myPaths = new ArrayList<String>();
|
||||
}
|
||||
return myPaths;
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return myResourceName;
|
||||
}
|
||||
|
||||
public void setPaths(List<String> thePaths) {
|
||||
myPaths = thePaths;
|
||||
}
|
||||
|
||||
public void setResourceName(String theResourceName) {
|
||||
myResourceName = theResourceName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package ca.uhn.fhir.tinder.parser;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import ca.uhn.fhir.tinder.util.XMLUtils;
|
||||
|
||||
public class CompartmentParser {
|
||||
|
||||
private String myVersion;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CompartmentParser.class);
|
||||
|
||||
public CompartmentParser(String theVersion) {
|
||||
myVersion = theVersion;
|
||||
}
|
||||
|
||||
public void parse() throws Exception {
|
||||
String resName = "/compartment/" + myVersion + "/compartments.xml";
|
||||
InputStream nextRes = getClass().getResourceAsStream(resName);
|
||||
if (nextRes == null) {
|
||||
throw new MojoFailureException("Unknown base resource name: " + resName);
|
||||
}
|
||||
|
||||
ourLog.info("Reading spreadsheet file {}", resName);
|
||||
|
||||
Document file;
|
||||
try {
|
||||
file = XMLUtils.parse(nextRes, false);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Failed during reading: " + resName, e);
|
||||
}
|
||||
|
||||
Element resourcesSheet = null;
|
||||
for (int i = 0; i < file.getElementsByTagName("Worksheet").getLength() && resourcesSheet == null; i++) {
|
||||
resourcesSheet = (Element) file.getElementsByTagName("Worksheet").item(i);
|
||||
if (!"resources".equals(resourcesSheet.getAttributeNS("urn:schemas-microsoft-com:office:spreadsheet", "Name"))) {
|
||||
resourcesSheet = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (resourcesSheet == null) {
|
||||
throw new Exception("Failed to find worksheet with name 'Data Elements' in spreadsheet: " + resName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,636 @@
|
|||
<?xml version="1.0"?>
|
||||
<?mso-application progid="Excel.Sheet"?>
|
||||
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:html="http://www.w3.org/TR/REC-html40">
|
||||
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<Author>Grahame</Author>
|
||||
<LastAuthor>Eric Haas</LastAuthor>
|
||||
<Created>2013-07-04T21:40:46Z</Created>
|
||||
<LastSaved>2015-04-10T01:54:05Z</LastSaved>
|
||||
<Version>15.00</Version>
|
||||
</DocumentProperties>
|
||||
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<AllowPNG/>
|
||||
</OfficeDocumentSettings>
|
||||
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<WindowHeight>8400</WindowHeight>
|
||||
<WindowWidth>19170</WindowWidth>
|
||||
<WindowTopX>0</WindowTopX>
|
||||
<WindowTopY>0</WindowTopY>
|
||||
<ActiveSheet>1</ActiveSheet>
|
||||
<RefModeR1C1/>
|
||||
<ProtectStructure>False</ProtectStructure>
|
||||
<ProtectWindows>False</ProtectWindows>
|
||||
</ExcelWorkbook>
|
||||
<Styles>
|
||||
<Style ss:ID="Default" ss:Name="Normal">
|
||||
<Alignment ss:Vertical="Bottom"/>
|
||||
<Borders/>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
|
||||
<Interior/>
|
||||
<NumberFormat/>
|
||||
<Protection/>
|
||||
</Style>
|
||||
<Style ss:ID="s62">
|
||||
<Alignment ss:Horizontal="Left" ss:Vertical="Top"/>
|
||||
</Style>
|
||||
<Style ss:ID="s63">
|
||||
<Alignment ss:Horizontal="Left" ss:Vertical="Top"/>
|
||||
<Borders>
|
||||
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
|
||||
</Borders>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"
|
||||
ss:Bold="1"/>
|
||||
<Interior ss:Color="#FFFFFF" ss:Pattern="Solid"/>
|
||||
</Style>
|
||||
<Style ss:ID="s64">
|
||||
<Alignment ss:Horizontal="Left" ss:Vertical="Top" ss:WrapText="1"/>
|
||||
</Style>
|
||||
<Style ss:ID="s65">
|
||||
<Borders>
|
||||
<Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
|
||||
</Borders>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"
|
||||
ss:Bold="1"/>
|
||||
<Interior ss:Color="#FFFFFF" ss:Pattern="Solid"/>
|
||||
</Style>
|
||||
<Style ss:ID="s66">
|
||||
<Font ss:FontName="Verdana" x:Family="Swiss" ss:Size="9" ss:Color="#333333"/>
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="compartments">
|
||||
<Table ss:ExpandedColumnCount="5" ss:ExpandedRowCount="6" x:FullColumns="1"
|
||||
x:FullRows="1" ss:StyleID="s62" ss:DefaultColumnWidth="65.25"
|
||||
ss:DefaultRowHeight="15">
|
||||
<Column ss:StyleID="s62" ss:AutoFitWidth="0" ss:Width="108.75" ss:Span="1"/>
|
||||
<Column ss:Index="3" ss:StyleID="s62" ss:AutoFitWidth="0" ss:Width="129.75"/>
|
||||
<Column ss:StyleID="s62" ss:AutoFitWidth="0" ss:Width="207.75"/>
|
||||
<Column ss:StyleID="s62" ss:AutoFitWidth="0" ss:Width="254.25"/>
|
||||
<Row ss:AutoFitHeight="0" ss:StyleID="s63">
|
||||
<Cell><Data ss:Type="String">Name</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Title</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Description</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Identification</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Inclusion</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0" ss:Height="75">
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Patient</Data></Cell>
|
||||
<Cell ss:StyleID="s64"><Data ss:Type="String">The set of resources associated with a particular patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">There is an instance of the patient compartment for each patient resource, and the identity of the compartment is the same as the patient. When a patient is linked to another patient, all the records associated with the linked patient are in the compartment associated with the target of the link. </Data></Cell>
|
||||
<Cell ss:StyleID="s64"><Data ss:Type="String">The patient compartment includes any resources where the subject of the resource is the patient, and some other resources that are directly linked to resources in the patient compartment</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">The set of resources associated with a particular encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">There is an instance of the encounter compartment for each encounter resource, and the identity of the compartment is the same as the encounter</Data></Cell>
|
||||
<Cell ss:StyleID="s64"><Data ss:Type="String">The encounter compartment includes any resources where the resource has an explicitly nominated encounter, and some other resources that them selves link to resources in the encounter compartment. Note that for many resources, the exact nature of the link to encounter can be ambiguous (e.g. for a DiagnosticReport, is it the encounter when it was initiated, or when it was reported?)</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">relatedPerson</Data></Cell>
|
||||
<Cell><Data ss:Type="String">RelatedPerson</Data></Cell>
|
||||
<Cell><Data ss:Type="String">The set of resources associated with a particular 'related person'</Data></Cell>
|
||||
<Cell><Data ss:Type="String">There is an instance of the relatedPerson compartment for each relatedPerson resource, and the identity of the compartment is the same as the relatedPerson</Data></Cell>
|
||||
<Cell ss:StyleID="s64"><Data ss:Type="String">The relatedPerson compartment includes any resources where the resource is explicitly linked to relatedPerson (usually as author)</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">practitioner</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Practitioner</Data></Cell>
|
||||
<Cell><Data ss:Type="String">The set of resources associated with a particular practitioner</Data></Cell>
|
||||
<Cell><Data ss:Type="String">There is an instance of the practitioner compartment for each Practitioner resource, and the identity of the compartment is the same as the Practitioner</Data></Cell>
|
||||
<Cell ss:StyleID="s64"><Data ss:Type="String">The practitioner compartment includes any resources where the resource is explicitly linked to a Practitioner (usually as author, but other kinds of linkage exist)</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">device</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Device</Data></Cell>
|
||||
<Cell><Data ss:Type="String">The set of resources associated with a particular device</Data></Cell>
|
||||
<Cell><Data ss:Type="String">There is an instance of the practitioner compartment for each Device resource, and the identity of the compartment is the same as the Device</Data></Cell>
|
||||
<Cell ss:StyleID="s64"><Data ss:Type="String">The device compartment includes any resources where the resource is explicitly linked to a Device (mostly subject or performer)</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<Unsynced/>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
<ActiveRow>4</ActiveRow>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
<x:PageLayoutZoom>0</x:PageLayoutZoom>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="resources">
|
||||
<Table ss:ExpandedColumnCount="6" ss:ExpandedRowCount="94" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultColumnWidth="65.25" ss:DefaultRowHeight="15">
|
||||
<Column ss:AutoFitWidth="0" ss:Width="156.75"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="198"/>
|
||||
<Column ss:Index="5" ss:AutoFitWidth="0" ss:Width="96"/>
|
||||
<Row ss:AutoFitHeight="0" ss:StyleID="s65">
|
||||
<Cell><Data ss:Type="String">Resource</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">RelatedPerson</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Practitioner</Data></Cell>
|
||||
<Cell><Data ss:Type="String">Device</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">AllergyIntolerance</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | recorder | reporter</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">reporter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">recorder | reporter</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Account</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Appointment</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">AppointmentResponse</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">AuditEvent</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | participant.patient | reference.patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">participant</Data></Cell>
|
||||
<Cell><Data ss:Type="String">participant</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Basic</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | author</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Binary</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">BodySite</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Bundle</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">CarePlan</Data></Cell>
|
||||
<Cell ss:StyleID="s66"><Data ss:Type="String">patient | participant | performer</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">participant | performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">participant | performer</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Claim</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">provider</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ClaimResponse</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ClinicalImpression</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">assessor</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Communication</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | sender | recipient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">sender | recipient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">sender | recipient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">sender | recipient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">CommunicationRequest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | sender | recipient | requester</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">sender | recipient | requester</Data></Cell>
|
||||
<Cell><Data ss:Type="String">sender | recipient | requester</Data></Cell>
|
||||
<Cell><Data ss:Type="String">sender | recipient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Composition</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author | attester</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author | attester</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ConceptMap</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Condition</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:StyleID="s66"><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">asserter</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Conformance</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DetectedIssue</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Contract</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Coverage</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DataElement</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Device</Data></Cell>
|
||||
<Cell ss:Index="6"><Data ss:Type="String">{def}</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DeviceComponent</Data></Cell>
|
||||
<Cell ss:Index="6"><Data ss:Type="String">source</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DeviceMetric</Data></Cell>
|
||||
<Cell ss:Index="6"><Data ss:Type="String">source</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DeviceUseRequest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="6"><Data ss:Type="String">device</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DeviceUseStatement</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="6"><Data ss:Type="String">device</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DiagnosticOrder</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:StyleID="s66"><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">actor | orderer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor | subject</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DiagnosticReport</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:StyleID="s66"><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DocumentManifest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author | recipient</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author | recipient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">DocumentReference</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author | authenticator</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">EligibilityRequest</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">EligibilityResponse</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">{def}</Data></Cell>
|
||||
<Cell><Data ss:Type="String">participant</Data></Cell>
|
||||
<Cell><Data ss:Type="String">practitioner | participant</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">EnrollmentRequest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">EnrollmentResponse</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">EpisodeOfCare</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5" ss:StyleID="s66"><Data ss:Type="String">care-manager | team-member</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ExplanationOfBenefit</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">FamilyMemberHistory</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Flag</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Goal</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Group</Data></Cell>
|
||||
<Cell><Data ss:Type="String">member</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">member</Data></Cell>
|
||||
<Cell><Data ss:Type="String">member</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">HealthcareService</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ImagingObjectSelection</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | author</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ImagingStudy</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Immunization</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">performer | requester</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ImmunizationRecommendation</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ImplementationGuide</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">List</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | source</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">source</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | source</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Location</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Media</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">subject | operator</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Medication</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">MedicationAdministration</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">practitioner</Data></Cell>
|
||||
<Cell><Data ss:Type="String">device</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">MedicationDispense</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">dispenser | receiver | responsibleparty</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">MedicationOrder</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">prescriber</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">MedicationStatement</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | source</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">source</Data></Cell>
|
||||
<Cell><Data ss:Type="String">source</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">MessageHeader</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">receiver | author | responsible | enterer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">target</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">NamingSystem</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">NutritionOrder</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">provider</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Observation</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | device</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">OperationDefinition</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">OperationOutcome</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Order</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">source | target</Data></Cell>
|
||||
<Cell><Data ss:Type="String">target</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">OrderResponse</Data></Cell>
|
||||
<Cell><Data ss:Type="String">request.patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">who</Data></Cell>
|
||||
<Cell><Data ss:Type="String">who</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Organization</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Patient</Data></Cell>
|
||||
<Cell><Data ss:Type="String">link</Data></Cell>
|
||||
<Cell ss:Index="5" ss:StyleID="s66"><Data ss:Type="String">careprovider</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">PaymentNotice</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">PaymentReconciliation</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Person</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">link</Data></Cell>
|
||||
<Cell><Data ss:Type="String">practitioner</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Practitioner</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">{def}</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Procedure</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ProcedureRequest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | orderer | performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer | orderer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer | orderer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">orderer</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ProcessRequest</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">provider</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ProcessResponse</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">requestprovider</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Provenance</Data></Cell>
|
||||
<Cell><Data ss:Type="String">target.subject | target.patient | patient</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">agent</Data></Cell>
|
||||
<Cell><Data ss:Type="String">agent</Data></Cell>
|
||||
<Cell><Data ss:Type="String">agent</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Questionnaire</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">QuestionnaireResponse</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject | author</Data></Cell>
|
||||
<Cell ss:StyleID="s66"><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author | source</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author | source</Data></Cell>
|
||||
<Cell><Data ss:Type="String">author</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ReferralRequest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient | requester</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">requester | recipient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">RelatedPerson</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">{def}</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">RiskAssessment</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">performer</Data></Cell>
|
||||
<Cell><Data ss:Type="String">performer</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Schedule</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell ss:Index="4"><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
<Cell><Data ss:Type="String">actor</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">SearchParameter</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Slot</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Specimen</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">collector</Data></Cell>
|
||||
<Cell><Data ss:Type="String">subject</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">StructureDefinition</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Subscription</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">Substance</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0" ss:Height="15.75">
|
||||
<Cell><Data ss:Type="String">SupplyRequest</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0" ss:Height="15.75">
|
||||
<Cell><Data ss:Type="String">SupplyDelivery</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">supplier | receiver</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">TestScript</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">ValueSet</Data></Cell>
|
||||
</Row>
|
||||
<Row ss:AutoFitHeight="0">
|
||||
<Cell><Data ss:Type="String">VisionPrescription</Data></Cell>
|
||||
<Cell><Data ss:Type="String">patient</Data></Cell>
|
||||
<Cell ss:StyleID="s66"><Data ss:Type="String">encounter</Data></Cell>
|
||||
<Cell ss:Index="5"><Data ss:Type="String">prescriber</Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<Unsynced/>
|
||||
<Print>
|
||||
<ValidPrinterInfo/>
|
||||
<PaperSizeIndex>9</PaperSizeIndex>
|
||||
<HorizontalResolution>600</HorizontalResolution>
|
||||
<VerticalResolution>600</VerticalResolution>
|
||||
</Print>
|
||||
<Selected/>
|
||||
<FreezePanes/>
|
||||
<FrozenNoSplit/>
|
||||
<SplitHorizontal>1</SplitHorizontal>
|
||||
<TopRowBottomPane>10</TopRowBottomPane>
|
||||
<ActivePane>2</ActivePane>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
</Pane>
|
||||
<Pane>
|
||||
<Number>2</Number>
|
||||
<ActiveRow>20</ActiveRow>
|
||||
<RangeSelection>R21</RangeSelection>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
<x:PageLayoutZoom>0</x:PageLayoutZoom>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
</Workbook>
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
<bean id="myFhirContext${versionCapitalized}" class="ca.uhn.fhir.context.FhirContext" factory-method="for${versionCapitalized}"/>
|
||||
|
||||
|
||||
<bean id="mySystemDao${versionCapitalized}" class="ca.uhn.fhir.jpa.dao.FhirSystemDao${versionCapitalized}">
|
||||
<property name="context" ref="myFhirContext${versionCapitalized}"/>
|
||||
</bean>
|
||||
|
@ -23,6 +24,7 @@
|
|||
</bean>
|
||||
|
||||
#if ( ${versionCapitalized} == 'Dstu2' )
|
||||
<bean id="myFhirContextDstu2Hl7Org" class="ca.uhn.fhir.context.FhirContext" factory-method="forDstu2Hl7Org"/>
|
||||
<jpa:repositories base-package="ca.uhn.fhir.jpa.dao.data" />
|
||||
|
||||
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
|
||||
|
@ -41,7 +43,7 @@
|
|||
#foreach ( $res in $resources )
|
||||
<bean id="my${res.name}Dao${versionCapitalized}"
|
||||
## Some resource types have customized DAOs for resource specific functionality
|
||||
#if ( ${versionCapitalized} == 'Dstu2' && ( ${res.name} == 'Bundle' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'ValueSet'))
|
||||
#if ( ${versionCapitalized} == 'Dstu2' && ( ${res.name} == 'Bundle' || ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'ValueSet'))
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||
#else
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${versionCapitalized}">
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -186,6 +186,10 @@
|
|||
<id>SingingTree</id>
|
||||
<name>Bryce Van Dyk</name>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>botunge</id>
|
||||
<name>Thomas Andersen</name>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
|
|
|
@ -106,6 +106,39 @@
|
|||
did not have latest valueset definitions applied. Thanks
|
||||
to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
JPA server can now successfully search for tokens pointing at code values
|
||||
(values with no explicit system but an implied one, such as Patient.gender)
|
||||
even if the system is supplied in the query.
|
||||
</action>
|
||||
<action type="fix" issue="235">
|
||||
Correct issues with Android library. Thanks to
|
||||
Thomas Andersen for the submission!
|
||||
</action>
|
||||
<action type="fix">
|
||||
JPA server incorrectly rejected match URLs
|
||||
if they did not contain a question mark. Thanks
|
||||
to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix" issue="234">
|
||||
Remove invalid entries in OSGi Manifest. Thanks
|
||||
to Alexander Kley for the fix!
|
||||
</action>
|
||||
<action type="add">
|
||||
JPA server now supports $everything on Patient and Encounter types (patient and encounter instance was already supported)
|
||||
</action>
|
||||
<action type="add">
|
||||
Generic client operation invocations now
|
||||
have an additional inline method for generating the input
|
||||
Parameters using chained method calls instead
|
||||
of by passing a Parameters resource in
|
||||
</action>
|
||||
<action type="fix">
|
||||
Parsing an XML resource where the XHTML
|
||||
namespace was declared before the beginning
|
||||
of the narrative section caused an invalid
|
||||
re-encoding when encoding to JSON.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
|
|
2
sync.sh
2
sync.sh
|
@ -8,6 +8,8 @@ for i in $(find $FHIRTRUNK/build/source -name *-spreadsheet.xml | egrep "/[a-z0-
|
|||
rm hapi-tinder-plugin/src/main/resources/dt/dstu2/*
|
||||
for i in $(find $FHIRTRUNK/build/source/datatypes | grep xml | grep -v spreadsheet | grep -v -); do cp -v $i hapi-tinder-plugin/src/main/resources/dt/dstu2/; done
|
||||
|
||||
cp ~/workspace/fhir/trunk/build/source/compartments.xml hapi-tinder-plugin/src/main/resources/compartment/
|
||||
|
||||
cp $FHIRTRUNK/build/publish/valuesets.xml hapi-fhir-validation-resources/src/main/resources/org/hl7/fhir/instance/model/valueset/
|
||||
cp $FHIRTRUNK/build/publish/v3-codesystems.xml hapi-fhir-validation-resources/src/main/resources/org/hl7/fhir/instance/model/valueset/
|
||||
cp $FHIRTRUNK/build/publish/v2-codesystems.xml hapi-fhir-validation-resources/src/main/resources/org/hl7/fhir/instance/model/valueset/
|
||||
|
|
Loading…
Reference in New Issue