Merge branch 'master' of github.com:jamesagnew/hapi-fhir into hl7org_structs
This commit is contained in:
commit
9755ae8d35
|
@ -12,6 +12,7 @@ Servers/
|
||||||
*.log*
|
*.log*
|
||||||
nohup.out
|
nohup.out
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.orig
|
||||||
|
|
||||||
# Vagrant stuff.
|
# Vagrant stuff.
|
||||||
.vagrant
|
.vagrant
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package example;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
|
import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor;
|
||||||
|
import ca.uhn.fhir.util.ITestingUiClientFactory;
|
||||||
|
|
||||||
|
public class AuthorizingTesterUiClientFactory implements ITestingUiClientFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IGenericClient newClient(FhirContext theFhirContext, HttpServletRequest theRequest, String theServerBaseUrl) {
|
||||||
|
// Create a client
|
||||||
|
IGenericClient client = theFhirContext.newRestfulGenericClient(theServerBaseUrl);
|
||||||
|
|
||||||
|
// Register an interceptor which adds credentials
|
||||||
|
client.registerInterceptor(new BasicAuthInterceptor("someusername", "somepassword"));
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,22 @@ public class ClientExamples {
|
||||||
// END SNIPPET: proxy
|
// END SNIPPET: proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void createTimeouts() {
|
||||||
|
// START SNIPPET: timeouts
|
||||||
|
FhirContext ctx = new FhirContext();
|
||||||
|
|
||||||
|
// Set how long to try and establish the initial TCP connection (in ms)
|
||||||
|
ctx.getRestfulClientFactory().setConnectTimeout(20 * 1000);
|
||||||
|
|
||||||
|
// Set how long to block for individual read/write operations (in ms)
|
||||||
|
ctx.getRestfulClientFactory().setSocketTimeout(20 * 1000);
|
||||||
|
|
||||||
|
// Create the client
|
||||||
|
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||||
|
// END SNIPPET: timeouts
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void createSecurity() {
|
public void createSecurity() {
|
||||||
// START SNIPPET: security
|
// START SNIPPET: security
|
||||||
|
|
|
@ -3,6 +3,8 @@ package example;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -273,7 +275,7 @@ public class GenericClientExample {
|
||||||
// .. populate this list - note that you can also pass in a populated
|
// .. populate this list - note that you can also pass in a populated
|
||||||
// Bundle if you want to create one manually ..
|
// Bundle if you want to create one manually ..
|
||||||
|
|
||||||
List<IResource> response = client.transaction().withResources(resources).execute();
|
List<IBaseResource> response = client.transaction().withResources(resources).execute();
|
||||||
// END SNIPPET: transaction
|
// END SNIPPET: transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package example;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
|
@ -43,7 +45,7 @@ public class PagingPatientProvider implements IResourceProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IResource> getResources(int theFromIndex, int theToIndex) {
|
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||||
int end = Math.max(theToIndex, matchingResourceIds.size() - 1);
|
int end = Math.max(theToIndex, matchingResourceIds.size() - 1);
|
||||||
List<Long> idsToReturn = matchingResourceIds.subList(theFromIndex, end);
|
List<Long> idsToReturn = matchingResourceIds.subList(theFromIndex, end);
|
||||||
return loadResourcesByIds(idsToReturn);
|
return loadResourcesByIds(idsToReturn);
|
||||||
|
@ -65,7 +67,7 @@ public class PagingPatientProvider implements IResourceProvider {
|
||||||
/**
|
/**
|
||||||
* Load a list of patient resources given their IDs
|
* Load a list of patient resources given their IDs
|
||||||
*/
|
*/
|
||||||
private List<IResource> loadResourcesByIds(List<Long> theIdsToReturn) {
|
private List<IBaseResource> loadResourcesByIds(List<Long> theIdsToReturn) {
|
||||||
// .. implement this search against the database ..
|
// .. implement this search against the database ..
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,20 +63,22 @@
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-android</artifactId>
|
<artifactId>slf4j-android</artifactId>
|
||||||
<version>${slf4j_version}</version>
|
<version>${slf4j_version}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>stax2-api</artifactId>
|
<dependency>
|
||||||
<version>3.1.4</version> </dependency> -->
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${slf4j_version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>${commons_io_version}</version>
|
<version>${commons_io_version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!-- Android does not come with the Servlet API bundled, and MethodUtil
|
||||||
Android does not come with the Servlet API bundled, and MethodUtil requires it
|
requires it -->
|
||||||
-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
@ -139,7 +141,6 @@
|
||||||
<artifactSet>
|
<artifactSet>
|
||||||
<includes>
|
<includes>
|
||||||
<include>commons-codec:commons-codec</include>
|
<include>commons-codec:commons-codec</include>
|
||||||
<include>commons-io:commons-io</include>
|
|
||||||
<include>ca.uhn.hapi.fhir:hapi-fhir-base</include>
|
<include>ca.uhn.hapi.fhir:hapi-fhir-base</include>
|
||||||
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include>
|
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include>
|
||||||
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</include>
|
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2</include>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ca.uhn.fhir.android;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
|
||||||
|
public class AndroidLoader {
|
||||||
|
|
||||||
|
public static void main(String[] theArgs) {
|
||||||
|
FhirContext ctx = FhirContext.forDstu2();
|
||||||
|
ctx.newJsonParser();
|
||||||
|
ctx.newXmlParser();
|
||||||
|
ctx.newRestfulGenericClient("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -368,6 +368,13 @@ public class FhirContext {
|
||||||
return new FhirTerser(this);
|
return new FhirTerser(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new validator instance.
|
||||||
|
* <p>
|
||||||
|
* Note on thread safety: Validators are thread safe, you may use a single validator
|
||||||
|
* in multiple threads. (This is in contrast to parsers)
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
public FhirValidator newValidator() {
|
public FhirValidator newValidator() {
|
||||||
return new FhirValidator(this);
|
return new FhirValidator(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
|
||||||
if (myUndeclaredExtensions == null) {
|
if (myUndeclaredExtensions == null) {
|
||||||
myUndeclaredExtensions = new ArrayList<ExtensionDt>();
|
myUndeclaredExtensions = new ArrayList<ExtensionDt>();
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableList(myUndeclaredExtensions);
|
return (myUndeclaredExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -111,7 +111,7 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
|
||||||
if (myUndeclaredModifierExtensions == null) {
|
if (myUndeclaredModifierExtensions == null) {
|
||||||
myUndeclaredModifierExtensions = new ArrayList<ExtensionDt>();
|
myUndeclaredModifierExtensions = new ArrayList<ExtensionDt>();
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableList(myUndeclaredModifierExtensions);
|
return (myUndeclaredModifierExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -293,6 +293,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
return myLinkSelf;
|
return myLinkSelf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public InstantDt getPublished() {
|
public InstantDt getPublished() {
|
||||||
InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
|
InstantDt retVal = (InstantDt) getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
|
||||||
if (retVal == null) {
|
if (retVal == null) {
|
||||||
|
@ -301,6 +302,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a resource from a bundle given its logical ID.
|
* Retrieves a resource from a bundle given its logical ID.
|
||||||
|
@ -394,9 +396,11 @@ public class Bundle extends BaseBundle /* implements IElement */{
|
||||||
myCategories = theCategories;
|
myCategories = theCategories;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public void setPublished(InstantDt thePublished) {
|
public void setPublished(InstantDt thePublished) {
|
||||||
getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, thePublished);
|
getResourceMetadata().put(ResourceMetadataKeyEnum.PUBLISHED, thePublished);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
public void setType(BoundCodeDt<BundleTypeEnum> theType) {
|
public void setType(BoundCodeDt<BundleTypeEnum> theType) {
|
||||||
myType = theType;
|
myType = theType;
|
||||||
|
|
|
@ -27,22 +27,28 @@ import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
public interface ISupportsUndeclaredExtensions extends IElement {
|
public interface ISupportsUndeclaredExtensions extends IElement {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list containing all undeclared non-modifier extensions
|
* Returns a list containing all undeclared non-modifier extensions. The returned list
|
||||||
|
* is mutable, so it may be modified (e.g. to add or remove an extension).
|
||||||
*/
|
*/
|
||||||
List<ExtensionDt> getUndeclaredExtensions();
|
List<ExtensionDt> getUndeclaredExtensions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list containing all undeclared extensions (modifier and non-modifier) by extension URL
|
* Returns an <b>immutable</b> list containing all undeclared extensions (modifier and non-modifier) by extension URL
|
||||||
|
*
|
||||||
|
* @see #getUndeclaredExtensions() To return a mutable list which may be used to remove extensions
|
||||||
*/
|
*/
|
||||||
List<ExtensionDt> getUndeclaredExtensionsByUrl(String theUrl);
|
List<ExtensionDt> getUndeclaredExtensionsByUrl(String theUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an <b>immutable</b> list containing all extensions (modifier and non-modifier)
|
* Returns an <b>immutable</b> list containing all extensions (modifier and non-modifier).
|
||||||
|
*
|
||||||
|
* @see #getUndeclaredExtensions() To return a mutable list which may be used to remove extensions
|
||||||
*/
|
*/
|
||||||
List<ExtensionDt> getAllUndeclaredExtensions();
|
List<ExtensionDt> getAllUndeclaredExtensions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list containing all undeclared modifier extensions
|
* Returns a list containing all undeclared modifier extensions. The returned list
|
||||||
|
* is mutable, so it may be modified (e.g. to add or remove an extension).
|
||||||
*/
|
*/
|
||||||
List<ExtensionDt> getUndeclaredModifierExtensions();
|
List<ExtensionDt> getUndeclaredModifierExtensions();
|
||||||
|
|
||||||
|
@ -65,6 +71,8 @@ public interface ISupportsUndeclaredExtensions extends IElement {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an extension to this object
|
* Adds an extension to this object
|
||||||
|
*
|
||||||
|
* @see #getUndeclaredExtensions() To return a mutable list which may be used to remove extensions
|
||||||
*/
|
*/
|
||||||
ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IBaseDatatype theValue);
|
ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IBaseDatatype theValue);
|
||||||
|
|
||||||
|
@ -72,6 +80,8 @@ public interface ISupportsUndeclaredExtensions extends IElement {
|
||||||
* Adds an extension to this object. This method is intended for use when
|
* Adds an extension to this object. This method is intended for use when
|
||||||
* an extension is being added which will contain child extensions, as opposed to
|
* an extension is being added which will contain child extensions, as opposed to
|
||||||
* a datatype.
|
* a datatype.
|
||||||
|
*
|
||||||
|
* @see #getUndeclaredExtensions() To return a mutable list which may be used to remove extensions
|
||||||
*/
|
*/
|
||||||
ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl);
|
ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import static ca.uhn.fhir.model.api.TemporalPrecisionEnum.YEAR;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
@ -64,6 +65,8 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
||||||
private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");
|
private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");
|
||||||
private static final FastDateFormat ourYearMonthFormat = FastDateFormat.getInstance("yyyy-MM");
|
private static final FastDateFormat ourYearMonthFormat = FastDateFormat.getInstance("yyyy-MM");
|
||||||
private static final FastDateFormat ourYearMonthNoDashesFormat = FastDateFormat.getInstance("yyyyMM");
|
private static final FastDateFormat ourYearMonthNoDashesFormat = FastDateFormat.getInstance("yyyyMM");
|
||||||
|
private static final FastDateFormat ourHumanDateTimeFormat = FastDateFormat.getDateTimeInstance(FastDateFormat.MEDIUM, FastDateFormat.MEDIUM);
|
||||||
|
private static final FastDateFormat ourHumanDateFormat = FastDateFormat.getDateInstance(FastDateFormat.MEDIUM);
|
||||||
private static final Pattern ourYearMonthPattern = Pattern.compile("[0-9]{4}[0-9]{2}");
|
private static final Pattern ourYearMonthPattern = Pattern.compile("[0-9]{4}[0-9]{2}");
|
||||||
private static final Pattern ourYearPattern = Pattern.compile("[0-9]{4}");
|
private static final Pattern ourYearPattern = Pattern.compile("[0-9]{4}");
|
||||||
|
|
||||||
|
@ -89,6 +92,54 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
|
||||||
private boolean myTimeZoneZulu = false;
|
private boolean myTimeZoneZulu = false;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseDateTimeDt.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseDateTimeDt.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a human readable version of this date/time using the system local format.
|
||||||
|
* <p>
|
||||||
|
* <b>Note on time zones:</b> This method renders the value using the time zone
|
||||||
|
* that is contained within the value. For example, if this date object contains the
|
||||||
|
* value "2012-01-05T12:00:00-08:00", the human display will be rendered as "12:00:00"
|
||||||
|
* even if the application is being executed on a system in a different time zone. If
|
||||||
|
* this behaviour is not what you want, use {@link #toHumanDisplayLocalTimezone()}
|
||||||
|
* instead.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public String toHumanDisplay() {
|
||||||
|
TimeZone tz = getTimeZone();
|
||||||
|
Calendar value = tz != null ? Calendar.getInstance(tz) : Calendar.getInstance();
|
||||||
|
value.setTime(getValue());
|
||||||
|
|
||||||
|
switch (getPrecision()) {
|
||||||
|
case YEAR:
|
||||||
|
case MONTH:
|
||||||
|
case DAY:
|
||||||
|
return ourHumanDateFormat.format(value);
|
||||||
|
case MILLI:
|
||||||
|
case SECOND:
|
||||||
|
default:
|
||||||
|
return ourHumanDateTimeFormat.format(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a human readable version of this date/time using the system local format,
|
||||||
|
* converted to the local timezone if neccesary.
|
||||||
|
*
|
||||||
|
* @see #toHumanDisplay() for a method which does not convert the time to the local
|
||||||
|
* timezone before rendering it.
|
||||||
|
*/
|
||||||
|
public String toHumanDisplayLocalTimezone() {
|
||||||
|
switch (getPrecision()) {
|
||||||
|
case YEAR:
|
||||||
|
case MONTH:
|
||||||
|
case DAY:
|
||||||
|
return ourHumanDateFormat.format(getValue());
|
||||||
|
case MILLI:
|
||||||
|
case SECOND:
|
||||||
|
default:
|
||||||
|
return ourHumanDateTimeFormat.format(getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,7 +24,6 @@ import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import ca.uhn.fhir.model.api.BasePrimitive;
|
import ca.uhn.fhir.model.api.BasePrimitive;
|
||||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||||
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
|
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
|
||||||
|
|
||||||
@DatatypeDef(name = "code")
|
@DatatypeDef(name = "code")
|
||||||
public class CodeDt extends BasePrimitive<String> implements ICodedDatatype, Comparable<CodeDt> {
|
public class CodeDt extends BasePrimitive<String> implements ICodedDatatype, Comparable<CodeDt> {
|
||||||
|
@ -44,6 +43,11 @@ public class CodeDt extends BasePrimitive<String> implements ICodedDatatype, Com
|
||||||
setValue(theCode);
|
setValue(theCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return super.isBaseEmpty() && isBlank(getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(CodeDt theCode) {
|
public int compareTo(CodeDt theCode) {
|
||||||
if (theCode == null) {
|
if (theCode == null) {
|
||||||
|
|
|
@ -48,6 +48,11 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return super.isBaseEmpty() && (getValue() == null || getValue().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor which accepts a string code
|
* Constructor which accepts a string code
|
||||||
*
|
*
|
||||||
|
|
|
@ -95,19 +95,20 @@ import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
import ca.uhn.fhir.model.primitive.DecimalDt;
|
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||||
import ca.uhn.fhir.util.ElementUtil;
|
import ca.uhn.fhir.util.ElementUtil;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use
|
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use {@link FhirContext#newJsonParser()} to get an instance.
|
||||||
* {@link FhirContext#newJsonParser()} to get an instance.
|
|
||||||
*/
|
*/
|
||||||
public class JsonParser extends BaseParser implements IParser {
|
public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
|
@ -196,7 +197,6 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
|
writeTagWithTextNode(eventWriter, "title", theBundle.getTitle());
|
||||||
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
|
writeTagWithTextNode(eventWriter, "id", theBundle.getBundleId());
|
||||||
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
||||||
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
|
||||||
|
|
||||||
boolean linkStarted = false;
|
boolean linkStarted = false;
|
||||||
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
|
linkStarted = writeAtomLinkInDstu1Format(eventWriter, "self", theBundle.getLinkSelf(), linkStarted);
|
||||||
|
@ -353,7 +353,8 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
theEventWriter.writeEnd();
|
theEventWriter.writeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theWriter, IBase theNextValue, BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theIsSubElementWithinResource) throws IOException {
|
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theWriter, IBase theNextValue,
|
||||||
|
BaseRuntimeElementDefinition<?> theChildDef, String theChildName, boolean theContainedResource) throws IOException {
|
||||||
|
|
||||||
switch (theChildDef.getChildType()) {
|
switch (theChildDef.getChildType()) {
|
||||||
case ID_DATATYPE: {
|
case ID_DATATYPE: {
|
||||||
|
@ -414,7 +415,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
if (theNextValue instanceof IBaseExtension) {
|
if (theNextValue instanceof IBaseExtension) {
|
||||||
theWriter.write("url", ((IBaseExtension<?>) theNextValue).getUrl());
|
theWriter.write("url", ((IBaseExtension<?>) theNextValue).getUrl());
|
||||||
}
|
}
|
||||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theIsSubElementWithinResource);
|
encodeCompositeElementToStreamWriter(theResDef, theResource, theNextValue, theWriter, childCompositeDef, theContainedResource);
|
||||||
theWriter.writeEnd();
|
theWriter.writeEnd();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -488,7 +489,8 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter, List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException {
|
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
|
||||||
|
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theContainedResource) throws IOException {
|
||||||
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
for (BaseRuntimeChildDefinition nextChild : theChildren) {
|
||||||
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
|
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -503,19 +505,19 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
if (gen != null) {
|
if (gen != null) {
|
||||||
BaseNarrativeDt<?> narr = ((IResource) theResource).getText();
|
BaseNarrativeDt<?> narr = ((IResource) theResource).getText();
|
||||||
gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr);
|
gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr);
|
||||||
if (narr != null) {
|
if (narr != null && !narr.isEmpty()) {
|
||||||
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
|
||||||
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
String childName = nextChild.getChildNameByDatatype(child.getDatatype());
|
||||||
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, type, childName, theContainedResource);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (nextChild instanceof RuntimeChildContainedResources) {
|
} else if (nextChild instanceof RuntimeChildContainedResources) {
|
||||||
if (theIsSubElementWithinResource == false) {
|
if (theContainedResource == false) {
|
||||||
String childName = nextChild.getValidChildNames().iterator().next();
|
String childName = nextChild.getValidChildNames().iterator().next();
|
||||||
BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName);
|
BaseRuntimeElementDefinition<?> child = nextChild.getChildByName(childName);
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, null, child, childName, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, null, child, childName, theContainedResource);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -535,7 +537,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
for (IBase nextValue : values) {
|
for (IBase nextValue : values) {
|
||||||
if (nextValue == null || nextValue.isEmpty()) {
|
if (nextValue == null || nextValue.isEmpty()) {
|
||||||
if (nextValue instanceof BaseContainedDt) {
|
if (nextValue instanceof BaseContainedDt) {
|
||||||
if (theIsSubElementWithinResource || getContainedResources().isEmpty()) {
|
if (theContainedResource || getContainedResources().isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -551,7 +553,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
|
boolean primitive = childDef.getChildType() == ChildTypeEnum.PRIMITIVE_DATATYPE;
|
||||||
|
|
||||||
if ((childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES||childDef.getChildType()==ChildTypeEnum.CONTAINED_RESOURCE_LIST) && theIsSubElementWithinResource) {
|
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && theContainedResource) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,15 +575,15 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
if (nextChild.getMax() > 1 || nextChild.getMax() == Child.MAX_UNLIMITED) {
|
||||||
theEventWriter.writeStartArray(childName);
|
theEventWriter.writeStartArray(childName);
|
||||||
inArray = true;
|
inArray = true;
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
|
||||||
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIsSubElementWithinResource) {
|
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theContainedResource) {
|
||||||
// suppress narratives from contained resources
|
// suppress narratives from contained resources
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, childName, theContainedResource);
|
||||||
}
|
}
|
||||||
currentChildName = childName;
|
currentChildName = childName;
|
||||||
} else {
|
} else {
|
||||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
|
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theContainedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitive) {
|
if (primitive) {
|
||||||
|
@ -655,13 +657,15 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIsSubElementWithinResource) throws IOException, DataFormatException {
|
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theContainedResource) throws IOException, DataFormatException {
|
||||||
extractAndWriteExtensionsAsDirectChild(theNextValue, theEventWriter, resDef, theResDef, theResource, null);
|
extractAndWriteExtensionsAsDirectChild(theNextValue, theEventWriter, resDef, theResDef, theResource, null);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theIsSubElementWithinResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getExtensions(), theContainedResource);
|
||||||
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theIsSubElementWithinResource);
|
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theNextValue, theEventWriter, resDef.getChildren(), theContainedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theContainedResource) throws IOException {
|
private void encodeResourceToJsonStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theObjectNameOrNull, boolean theContainedResource)
|
||||||
|
throws IOException {
|
||||||
String resourceId = null;
|
String resourceId = null;
|
||||||
if (theResource instanceof IResource) {
|
if (theResource instanceof IResource) {
|
||||||
IResource res = (IResource) theResource;
|
IResource res = (IResource) theResource;
|
||||||
|
@ -674,7 +678,7 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
} else if (theResource instanceof IAnyResource) {
|
} else if (theResource instanceof IAnyResource) {
|
||||||
IAnyResource res = (IAnyResource) theResource;
|
IAnyResource res = (IAnyResource) theResource;
|
||||||
if (StringUtils.isNotBlank(res.getId().getIdPart())) {
|
if (theContainedResource && StringUtils.isNotBlank(res.getId().getIdPart())) {
|
||||||
resourceId = res.getId().getIdPart();
|
resourceId = res.getId().getIdPart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,20 +706,22 @@ public class JsonParser extends BaseParser implements IParser {
|
||||||
|
|
||||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) && theResource instanceof IResource) {
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1) && theResource instanceof IResource) {
|
||||||
IResource resource = (IResource) theResource;
|
IResource resource = (IResource) theResource;
|
||||||
|
// Object securityLabelRawObj =
|
||||||
|
|
||||||
|
List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS);
|
||||||
|
List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES);
|
||||||
|
TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource);
|
||||||
InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||||
IdDt resourceId = resource.getId();
|
IdDt resourceId = resource.getId();
|
||||||
String versionIdPart = resourceId.getVersionIdPart();
|
String versionIdPart = resourceId.getVersionIdPart();
|
||||||
if (isBlank(versionIdPart)) {
|
if (isBlank(versionIdPart)) {
|
||||||
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource);
|
versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource);
|
||||||
}
|
}
|
||||||
List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS);
|
|
||||||
List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES);
|
|
||||||
TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource);
|
|
||||||
if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) {
|
if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) {
|
||||||
theEventWriter.writeStartObject("meta");
|
theEventWriter.writeStartObject("meta");
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "versionId", resource.getId().getVersionIdPart());
|
writeOptionalTagWithTextNode(theEventWriter, "versionId", versionIdPart);
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", ResourceMetadataKeyEnum.UPDATED.get(resource));
|
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", updated);
|
||||||
|
|
||||||
if (profiles != null && profiles.isEmpty() == false) {
|
if (profiles != null && profiles.isEmpty() == false) {
|
||||||
theEventWriter.writeStartArray("profile");
|
theEventWriter.writeStartArray("profile");
|
||||||
|
|
|
@ -683,8 +683,6 @@ class ParserState<T> {
|
||||||
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
|
||||||
if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
|
if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
|
||||||
push(new AtomEntryState(myInstance, myResourceType));
|
push(new AtomEntryState(myInstance, myResourceType));
|
||||||
} else if (theLocalPart.equals("published")) {
|
|
||||||
push(new AtomPrimitiveState(myInstance.getPublished()));
|
|
||||||
} else if (theLocalPart.equals("title")) {
|
} else if (theLocalPart.equals("title")) {
|
||||||
push(new AtomPrimitiveState(myInstance.getTitle()));
|
push(new AtomPrimitiveState(myInstance.getTitle()));
|
||||||
} else if ("id".equals(theLocalPart)) {
|
} else if ("id".equals(theLocalPart)) {
|
||||||
|
@ -1619,7 +1617,7 @@ class ParserState<T> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case RESOURCE: {
|
case RESOURCE: {
|
||||||
if (myInstance instanceof IResource) {
|
if (myInstance instanceof IResource || myInstance instanceof IElement) {
|
||||||
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
|
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
|
||||||
push(state);
|
push(state);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1900,7 +1898,7 @@ class ParserState<T> {
|
||||||
@Override
|
@Override
|
||||||
public void wereBack() {
|
public void wereBack() {
|
||||||
super.wereBack();
|
super.wereBack();
|
||||||
if (myEntry == null) {
|
if (myEntry == null && myMutator == null) {
|
||||||
myObject = (T) getCurrentElement();
|
myObject = (T) getCurrentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2068,7 +2066,7 @@ class ParserState<T> {
|
||||||
terser.visit(myInstance, new IModelVisitor() {
|
terser.visit(myInstance, new IModelVisitor() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
if (theElement instanceof BaseResourceReferenceDt) {
|
if (theElement instanceof BaseResourceReferenceDt) {
|
||||||
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
|
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
|
||||||
String ref = nextRef.getReference().getValue();
|
String ref = nextRef.getReference().getValue();
|
||||||
|
@ -2099,8 +2097,8 @@ class ParserState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
||||||
acceptElement(theNextExt.getValue(), null, null);
|
acceptElement(theNextExt.getValue(), null, null, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,6 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
writeOptionalTagWithTextNode(eventWriter, "updated", theBundle.getUpdated());
|
||||||
writeOptionalTagWithTextNode(eventWriter, "published", theBundle.getPublished());
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
|
||||||
eventWriter.writeStartElement("author");
|
eventWriter.writeStartElement("author");
|
||||||
|
@ -804,6 +803,7 @@ public class XmlParser extends BaseParser implements IParser {
|
||||||
if (updated != null) {
|
if (updated != null) {
|
||||||
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IdDt profile : profiles) {
|
for (IdDt profile : profiles) {
|
||||||
theEventWriter.writeStartElement("profile");
|
theEventWriter.writeStartElement("profile");
|
||||||
theEventWriter.writeAttribute("value", profile.getValue());
|
theEventWriter.writeAttribute("value", profile.getValue());
|
||||||
|
|
|
@ -153,10 +153,14 @@ public abstract class BaseClient implements IRestfulClient {
|
||||||
return invokeClient(theContext, binding, clientInvocation, null, null, theLogRequestAndResponse);
|
return invokeClient(theContext, binding, clientInvocation, null, null, theLogRequestAndResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void forceConformanceCheck() {
|
||||||
|
myFactory.validateServerBase(myUrlBase, myClient, this);
|
||||||
|
}
|
||||||
|
|
||||||
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, EncodingEnum theEncoding, Boolean thePrettyPrint, boolean theLogRequestAndResponse) {
|
<T> T invokeClient(FhirContext theContext, IClientResponseHandler<T> binding, BaseHttpClientInvocation clientInvocation, EncodingEnum theEncoding, Boolean thePrettyPrint, boolean theLogRequestAndResponse) {
|
||||||
|
|
||||||
if (!myDontValidateConformance) {
|
if (!myDontValidateConformance) {
|
||||||
myFactory.validateServerBaseIfConfiguredToDoSo(myUrlBase, myClient);
|
myFactory.validateServerBaseIfConfiguredToDoSo(myUrlBase, myClient, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle non 2xx status codes by throwing the correct exception,
|
// TODO: handle non 2xx status codes by throwing the correct exception,
|
||||||
|
@ -441,4 +445,8 @@ public abstract class BaseClient implements IRestfulClient {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<IClientInterceptor> getInterceptors() {
|
||||||
|
return Collections.unmodifiableList(myInterceptors);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
|
@ -145,7 +146,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseConformance conformance() {
|
public BaseConformance conformance() {
|
||||||
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
|
||||||
|
@ -165,6 +165,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forceConformanceCheck() {
|
||||||
|
super.forceConformanceCheck();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICreate create() {
|
public ICreate create() {
|
||||||
return new CreateInternal();
|
return new CreateInternal();
|
||||||
|
@ -590,23 +595,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IBaseResource parseResourceBody(String theResourceBody) {
|
protected IBaseResource parseResourceBody(String theResourceBody) {
|
||||||
EncodingEnum encoding = null;
|
EncodingEnum encoding = MethodUtil.detectEncodingNoDefault(theResourceBody);
|
||||||
for (int i = 0; i < theResourceBody.length() && encoding == null; i++) {
|
|
||||||
switch (theResourceBody.charAt(i)) {
|
|
||||||
case '<':
|
|
||||||
encoding = EncodingEnum.XML;
|
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
encoding = EncodingEnum.JSON;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (encoding == null) {
|
if (encoding == null) {
|
||||||
throw new InvalidRequestException("FHIR client can't determine resource encoding");
|
throw new InvalidRequestException("FHIR client can't determine resource encoding");
|
||||||
}
|
}
|
||||||
return encoding.newParser(myContext).parseResource(theResourceBody);
|
return encoding.newParser(myContext).parseResource(theResourceBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public T prettyPrint() {
|
public T prettyPrint() {
|
||||||
|
@ -636,6 +632,15 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class StringResponseHandler implements IClientResponseHandler<String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||||
|
BaseServerResponseException {
|
||||||
|
return IOUtils.toString(theResponseReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class CreateInternal extends BaseClientExecutable<ICreateTyped, MethodOutcome> implements ICreate, ICreateTyped, ICreateWithQuery, ICreateWithQueryTyped {
|
private class CreateInternal extends BaseClientExecutable<ICreateTyped, MethodOutcome> implements ICreate, ICreateTyped, ICreateWithQuery, ICreateWithQueryTyped {
|
||||||
|
|
||||||
private CriterionList myCriterionList;
|
private CriterionList myCriterionList;
|
||||||
|
@ -1574,14 +1579,16 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
private final class TransactionExecutable<T> extends BaseClientExecutable<ITransactionTyped<T>, T> implements ITransactionTyped<T> {
|
private final class TransactionExecutable<T> extends BaseClientExecutable<ITransactionTyped<T>, T> implements ITransactionTyped<T> {
|
||||||
|
|
||||||
private Bundle myBundle;
|
private Bundle myBundle;
|
||||||
private List<IBaseResource> myResources;
|
private List<? extends IBaseResource> myResources;
|
||||||
private IBaseBundle myBaseBundle;
|
private IBaseBundle myBaseBundle;
|
||||||
|
private String myRawBundle;
|
||||||
|
private EncodingEnum myRawBundleEncoding;
|
||||||
|
|
||||||
public TransactionExecutable(Bundle theResources) {
|
public TransactionExecutable(Bundle theResources) {
|
||||||
myBundle = theResources;
|
myBundle = theResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransactionExecutable(List<IBaseResource> theResources) {
|
public TransactionExecutable(List<? extends IBaseResource> theResources) {
|
||||||
myResources = theResources;
|
myResources = theResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1589,6 +1596,14 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
myBaseBundle = theBundle;
|
myBaseBundle = theBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransactionExecutable(String theBundle) {
|
||||||
|
myRawBundle = theBundle;
|
||||||
|
myRawBundleEncoding = MethodUtil.detectEncodingNoDefault(myRawBundle);
|
||||||
|
if (myRawBundleEncoding == null) {
|
||||||
|
throw new IllegalArgumentException("Can not determine encoding of raw resource body");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
@Override
|
@Override
|
||||||
public T execute() {
|
public T execute() {
|
||||||
|
@ -1601,6 +1616,19 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
ResourceResponseHandler binding = new ResourceResponseHandler(myBaseBundle.getClass(), null);
|
ResourceResponseHandler binding = new ResourceResponseHandler(myBaseBundle.getClass(), null);
|
||||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myBaseBundle, myContext);
|
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myBaseBundle, myContext);
|
||||||
return (T) invoke(params, binding, invocation);
|
return (T) invoke(params, binding, invocation);
|
||||||
|
} else if (myRawBundle != null) {
|
||||||
|
StringResponseHandler binding = new StringResponseHandler();
|
||||||
|
/*
|
||||||
|
* If the user has explicitly requested a given encoding, we may need to reencode the raw string
|
||||||
|
*/
|
||||||
|
if (getParamEncoding() != null) {
|
||||||
|
if (MethodUtil.detectEncodingNoDefault(myRawBundle) != getParamEncoding()) {
|
||||||
|
IBaseResource parsed = parseResourceBody(myRawBundle);
|
||||||
|
myRawBundle = getParamEncoding().newParser(getFhirContext()).encodeResourceToString(parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myRawBundle, myContext);
|
||||||
|
return (T) invoke(params, binding, invocation);
|
||||||
} else {
|
} else {
|
||||||
BundleResponseHandler binding = new BundleResponseHandler(null);
|
BundleResponseHandler binding = new BundleResponseHandler(null);
|
||||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myBundle, myContext);
|
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(myBundle, myContext);
|
||||||
|
@ -1619,7 +1647,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITransactionTyped<List<IBaseResource>> withResources(List<IBaseResource> theResources) {
|
public ITransactionTyped<List<IBaseResource>> withResources(List<? extends IBaseResource> theResources) {
|
||||||
Validate.notNull(theResources, "theResources must not be null");
|
Validate.notNull(theResources, "theResources must not be null");
|
||||||
return new TransactionExecutable<List<IBaseResource>>(theResources);
|
return new TransactionExecutable<List<IBaseResource>>(theResources);
|
||||||
}
|
}
|
||||||
|
@ -1630,6 +1658,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return new TransactionExecutable<T>(theBundle);
|
return new TransactionExecutable<T>(theBundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ITransactionTyped<String> withBundle(String theBundle) {
|
||||||
|
Validate.notBlank(theBundle, "theBundle must not be null");
|
||||||
|
return new TransactionExecutable<String>(theBundle);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UpdateInternal extends BaseClientExecutable<IUpdateExecutable, MethodOutcome> implements IUpdate, IUpdateTyped, IUpdateExecutable, IUpdateWithQuery, IUpdateWithQueryTyped {
|
private class UpdateInternal extends BaseClientExecutable<IUpdateExecutable, MethodOutcome> implements IUpdate, IUpdateTyped, IUpdateExecutable, IUpdateWithQuery, IUpdateWithQueryTyped {
|
||||||
|
|
|
@ -34,6 +34,8 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.UriDt;
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientInnapropriateForServerException;
|
||||||
import ca.uhn.fhir.rest.gclient.ICreate;
|
import ca.uhn.fhir.rest.gclient.ICreate;
|
||||||
import ca.uhn.fhir.rest.gclient.IDelete;
|
import ca.uhn.fhir.rest.gclient.IDelete;
|
||||||
import ca.uhn.fhir.rest.gclient.IFetchConformanceUntyped;
|
import ca.uhn.fhir.rest.gclient.IFetchConformanceUntyped;
|
||||||
|
@ -109,6 +111,16 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
MethodOutcome delete(Class<? extends IResource> theType, String theId);
|
MethodOutcome delete(Class<? extends IResource> theType, String theId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the client to fetch the server's conformance statement and validate that it is appropriate for this client.
|
||||||
|
*
|
||||||
|
* @throws FhirClientConnectionException
|
||||||
|
* if the conformance statement cannot be read, or if the client
|
||||||
|
* @throws FhirClientInnapropriateForServerException
|
||||||
|
* If the conformance statement indicates that the server is inappropriate for this client (e.g. it implements the wrong version of FHIR)
|
||||||
|
*/
|
||||||
|
void forceConformanceCheck() throws FhirClientConnectionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fluent method for the "get tags" operation
|
* Fluent method for the "get tags" operation
|
||||||
*/
|
*/
|
||||||
|
@ -123,17 +135,15 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
* Implementation of the "history instance" method.
|
* Implementation of the "history instance" method.
|
||||||
*
|
*
|
||||||
* @param theType
|
* @param theType
|
||||||
* The type of resource to return the history for, or
|
* The type of resource to return the history for, or <code>null</code> to search for history across all resources
|
||||||
* <code>null</code> to search for history across all resources
|
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID of the resource to return the history for, or <code>null</code> to search for all resource
|
* The ID of the resource to return the history for, or <code>null</code> to search for all resource instances. Note that if this param is not null, <code>theType</code> must also not
|
||||||
* instances. Note that if this param is not null, <code>theType</code> must also not be null
|
* be null
|
||||||
* @param theSince
|
* @param theSince
|
||||||
* If not null, request that the server only return resources updated since this time
|
* If not null, request that the server only return resources updated since this time
|
||||||
* @param theLimit
|
* @param theLimit
|
||||||
* If not null, request that the server return no more than this number of resources. Note that the
|
* If not null, request that the server return no more than this number of resources. Note that the server may return less even if more are available, but should not return more
|
||||||
* server may return less even if more are available, but should not return more according to the FHIR
|
* according to the FHIR specification.
|
||||||
* specification.
|
|
||||||
* @return A bundle containing returned resources
|
* @return A bundle containing returned resources
|
||||||
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
||||||
*/
|
*/
|
||||||
|
@ -144,31 +154,21 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
* Implementation of the "history instance" method.
|
* Implementation of the "history instance" method.
|
||||||
*
|
*
|
||||||
* @param theType
|
* @param theType
|
||||||
* The type of resource to return the history for, or
|
* The type of resource to return the history for, or <code>null</code> to search for history across all resources
|
||||||
* <code>null</code> to search for history across all resources
|
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID of the resource to return the history for, or <code>null</code> to search for all resource
|
* The ID of the resource to return the history for, or <code>null</code> to search for all resource instances. Note that if this param is not null, <code>theType</code> must also not
|
||||||
* instances. Note that if this param is not null, <code>theType</code> must also not be null
|
* be null
|
||||||
* @param theSince
|
* @param theSince
|
||||||
* If not null, request that the server only return resources updated since this time
|
* If not null, request that the server only return resources updated since this time
|
||||||
* @param theLimit
|
* @param theLimit
|
||||||
* If not null, request that the server return no more than this number of resources. Note that the
|
* If not null, request that the server return no more than this number of resources. Note that the server may return less even if more are available, but should not return more
|
||||||
* server may return less even if more are available, but should not return more according to the FHIR
|
* according to the FHIR specification.
|
||||||
* specification.
|
|
||||||
* @return A bundle containing returned resources
|
* @return A bundle containing returned resources
|
||||||
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
* @deprecated As of 0.9, use the fluent {@link #history()} method instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
<T extends IResource> Bundle history(Class<T> theType, String theId, DateTimeDt theSince, Integer theLimit);
|
<T extends IResource> Bundle history(Class<T> theType, String theId, DateTimeDt theSince, Integer theLimit);
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the previous/next bundle of resources from a paged set, using the link specified in the "link type=next"
|
|
||||||
* tag within the atom bundle.
|
|
||||||
*
|
|
||||||
* @see Bundle#getLinkNext()
|
|
||||||
*/
|
|
||||||
IGetPage loadPage();
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Implementation of the "instance read" method. This method will only ever do a "read" for the latest version of a
|
// * Implementation of the "instance read" method. This method will only ever do a "read" for the latest version of a
|
||||||
// * given resource instance, even if the ID passed in contains a version. If you wish to request a specific version
|
// * given resource instance, even if the ID passed in contains a version. If you wish to request a specific version
|
||||||
|
@ -187,6 +187,13 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
// */
|
// */
|
||||||
// <T extends IBaseResource> T read(Class<T> theType, IdDt theId);
|
// <T extends IBaseResource> T read(Class<T> theType, IdDt theId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the previous/next bundle of resources from a paged set, using the link specified in the "link type=next" tag within the atom bundle.
|
||||||
|
*
|
||||||
|
* @see Bundle#getLinkNext()
|
||||||
|
*/
|
||||||
|
IGetPage loadPage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the FHIR "extended operations" action
|
* Implementation of the FHIR "extended operations" action
|
||||||
*/
|
*/
|
||||||
|
@ -229,8 +236,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
IBaseResource read(UriDt theUrl);
|
IBaseResource read(UriDt theUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new interceptor for this client. An interceptor can be used to add additional logging, or add security
|
* Register a new interceptor for this client. An interceptor can be used to add additional logging, or add security headers, or pre-process responses, etc.
|
||||||
* headers, or pre-process responses, etc.
|
|
||||||
*/
|
*/
|
||||||
void registerInterceptor(IClientInterceptor theInterceptor);
|
void registerInterceptor(IClientInterceptor theInterceptor);
|
||||||
|
|
||||||
|
@ -259,8 +265,8 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
Bundle search(UriDt theUrl);
|
Bundle search(UriDt theUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to <code>true</code>, the client will log all requests and all responses. This is probably not a good
|
* If set to <code>true</code>, the client will log all requests and all responses. This is probably not a good production setting since it will result in a lot of extra logging, but it can be
|
||||||
* production setting since it will result in a lot of extra logging, but it can be useful for troubleshooting.
|
* useful for troubleshooting.
|
||||||
*
|
*
|
||||||
* @param theLogRequestAndResponse
|
* @param theLogRequestAndResponse
|
||||||
* Should requests and responses be logged
|
* Should requests and responses be logged
|
||||||
|
@ -277,8 +283,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
*
|
*
|
||||||
* @param theResources
|
* @param theResources
|
||||||
* The resources to create/update in a single transaction
|
* The resources to create/update in a single transaction
|
||||||
* @return A list of resource stubs (<b>these will not be fully populated</b>) containing IDs and other
|
* @return A list of resource stubs (<b>these will not be fully populated</b>) containing IDs and other {@link IResource#getResourceMetadata() metadata}
|
||||||
* {@link IResource#getResourceMetadata() metadata}
|
|
||||||
* @deprecated Use {@link #transaction()}
|
* @deprecated Use {@link #transaction()}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -286,8 +291,7 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
List<IBaseResource> transaction(List<IBaseResource> theResources);
|
List<IBaseResource> transaction(List<IBaseResource> theResources);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an intercaptor that was previously registered using
|
* Remove an intercaptor that was previously registered using {@link IRestfulClient#registerInterceptor(IClientInterceptor)}
|
||||||
* {@link IRestfulClient#registerInterceptor(IClientInterceptor)}
|
|
||||||
*/
|
*/
|
||||||
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
void unregisterInterceptor(IClientInterceptor theInterceptor);
|
||||||
|
|
||||||
|
@ -328,18 +332,16 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
MethodOutcome validate(IResource theResource);
|
MethodOutcome validate(IResource theResource);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the "instance vread" method. Note that this method expects <code>theId</code> to contain a
|
* Implementation of the "instance vread" method. Note that this method expects <code>theId</code> to contain a resource ID as well as a version ID, and will fail if it does not.
|
||||||
* resource ID as well as a version ID, and will fail if it does not.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Note that if an absolute resource ID is passed in (i.e. a URL containing a protocol and host as well as the
|
* Note that if an absolute resource ID is passed in (i.e. a URL containing a protocol and host as well as the resource type and ID) the server base for the client will be ignored, and the URL
|
||||||
* resource type and ID) the server base for the client will be ignored, and the URL passed in will be queried.
|
* passed in will be queried.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theType
|
* @param theType
|
||||||
* The type of resource to load
|
* The type of resource to load
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID to load, including the resource ID and the resource version ID. Valid values include
|
* The ID to load, including the resource ID and the resource version ID. Valid values include "Patient/123/_history/222", or "http://example.com/fhir/Patient/123/_history/222"
|
||||||
* "Patient/123/_history/222", or "http://example.com/fhir/Patient/123/_history/222"
|
|
||||||
* @return The resource
|
* @return The resource
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T vread(Class<T> theType, IdDt theId);
|
<T extends IBaseResource> T vread(Class<T> theType, IdDt theId);
|
||||||
|
|
|
@ -72,6 +72,12 @@ public interface IRestfulClientFactory {
|
||||||
*/
|
*/
|
||||||
HttpClient getHttpClient();
|
HttpClient getHttpClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getServerValidationMode()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
ServerValidationModeEnum getServerValidationModeEnum();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the server validation mode for any clients created from this factory. Server
|
* Gets the server validation mode for any clients created from this factory. Server
|
||||||
* validation involves the client requesting the server's conformance statement
|
* validation involves the client requesting the server's conformance statement
|
||||||
|
@ -79,8 +85,10 @@ public interface IRestfulClientFactory {
|
||||||
* <p>
|
* <p>
|
||||||
* The default value for this setting is defined by {@link #DEFAULT_SERVER_VALIDATION_MODE}
|
* The default value for this setting is defined by {@link #DEFAULT_SERVER_VALIDATION_MODE}
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
ServerValidationModeEnum getServerValidationModeEnum();
|
ServerValidationModeEnum getServerValidationMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the socket timeout, in milliseconds. This is the SO_TIMEOUT time, which is the amount of time that a
|
* Gets the socket timeout, in milliseconds. This is the SO_TIMEOUT time, which is the amount of time that a
|
||||||
|
@ -158,6 +166,12 @@ public interface IRestfulClientFactory {
|
||||||
*/
|
*/
|
||||||
void setProxyCredentials(String theUsername, String thePassword);
|
void setProxyCredentials(String theUsername, String thePassword);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #setServerValidationMode(ServerValidationModeEnum)} instead. This method was incorrectly named.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
void setServerValidationModeEnum(ServerValidationModeEnum theServerValidationMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the server validation mode for any clients created from this factory. Server
|
* Sets the server validation mode for any clients created from this factory. Server
|
||||||
* validation involves the client requesting the server's conformance statement
|
* validation involves the client requesting the server's conformance statement
|
||||||
|
@ -165,8 +179,10 @@ public interface IRestfulClientFactory {
|
||||||
* <p>
|
* <p>
|
||||||
* The default value for this setting is defined by {@link #DEFAULT_SERVER_VALIDATION_MODE}
|
* The default value for this setting is defined by {@link #DEFAULT_SERVER_VALIDATION_MODE}
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
void setServerValidationModeEnum(ServerValidationModeEnum theServerValidationMode);
|
void setServerValidationMode(ServerValidationModeEnum theServerValidationMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the socket timeout, in milliseconds. This is the SO_TIMEOUT time, which is the amount of time that a
|
* Sets the socket timeout, in milliseconds. This is the SO_TIMEOUT time, which is the amount of time that a
|
||||||
|
|
|
@ -51,6 +51,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientInnapropriateForServerException;
|
||||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.util.FhirTerser;
|
import ca.uhn.fhir.util.FhirTerser;
|
||||||
|
@ -137,7 +138,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerValidationModeEnum getServerValidationModeEnum() {
|
public ServerValidationModeEnum getServerValidationMode() {
|
||||||
return myServerValidationMode;
|
return myServerValidationMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,25 +196,29 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
/**
|
/**
|
||||||
* This method is internal to HAPI - It may change in future versions, use with caution.
|
* This method is internal to HAPI - It may change in future versions, use with caution.
|
||||||
*/
|
*/
|
||||||
public void validateServerBaseIfConfiguredToDoSo(String theServerBase, HttpClient theHttpClient) {
|
public void validateServerBaseIfConfiguredToDoSo(String theServerBase, HttpClient theHttpClient, BaseClient theClient) {
|
||||||
String serverBase = theServerBase;
|
String serverBase = normalizeBaseUrlForMap(theServerBase);
|
||||||
if (!serverBase.endsWith("/")) {
|
|
||||||
serverBase = serverBase + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (myServerValidationMode) {
|
switch (myServerValidationMode) {
|
||||||
case NEVER:
|
case NEVER:
|
||||||
break;
|
break;
|
||||||
case ONCE:
|
case ONCE:
|
||||||
if (!myValidatedServerBaseUrls.contains(serverBase)) {
|
if (!myValidatedServerBaseUrls.contains(serverBase)) {
|
||||||
validateServerBase(serverBase, theHttpClient);
|
validateServerBase(serverBase, theHttpClient, theClient);
|
||||||
myValidatedServerBaseUrls.add(serverBase);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String normalizeBaseUrlForMap(String theServerBase) {
|
||||||
|
String serverBase = theServerBase;
|
||||||
|
if (!serverBase.endsWith("/")) {
|
||||||
|
serverBase = serverBase + "/";
|
||||||
|
}
|
||||||
|
return serverBase;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setConnectionRequestTimeout(int theConnectionRequestTimeout) {
|
public synchronized void setConnectionRequestTimeout(int theConnectionRequestTimeout) {
|
||||||
myConnectionRequestTimeout = theConnectionRequestTimeout;
|
myConnectionRequestTimeout = theConnectionRequestTimeout;
|
||||||
|
@ -258,7 +263,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setServerValidationModeEnum(ServerValidationModeEnum theServerValidationMode) {
|
public void setServerValidationMode(ServerValidationModeEnum theServerValidationMode) {
|
||||||
Validate.notNull(theServerValidationMode, "theServerValidationMode may not be null");
|
Validate.notNull(theServerValidationMode, "theServerValidationMode may not be null");
|
||||||
myServerValidationMode = theServerValidationMode;
|
myServerValidationMode = theServerValidationMode;
|
||||||
}
|
}
|
||||||
|
@ -269,10 +274,12 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
myHttpClient = null;
|
myHttpClient = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
void validateServerBase(String theServerBase, HttpClient theHttpClient, BaseClient theClient) {
|
||||||
private void validateServerBase(String theServerBase, HttpClient theHttpClient) {
|
|
||||||
|
|
||||||
GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this);
|
GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this);
|
||||||
|
for (IClientInterceptor interceptor : theClient.getInterceptors()) {
|
||||||
|
client.registerInterceptor(interceptor);
|
||||||
|
}
|
||||||
client.setDontValidateConformance(true);
|
client.setDontValidateConformance(true);
|
||||||
|
|
||||||
IBaseResource conformance;
|
IBaseResource conformance;
|
||||||
|
@ -296,7 +303,9 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
} else {
|
} else {
|
||||||
if (serverFhirVersionString.startsWith("0.80") || serverFhirVersionString.startsWith("0.0.8")) {
|
if (serverFhirVersionString.startsWith("0.80") || serverFhirVersionString.startsWith("0.0.8")) {
|
||||||
serverFhirVersionEnum = FhirVersionEnum.DSTU1;
|
serverFhirVersionEnum = FhirVersionEnum.DSTU1;
|
||||||
} else if (serverFhirVersionString.startsWith("0.4") || serverFhirVersionString.startsWith("0.5")) {
|
} else if (serverFhirVersionString.startsWith("0.4")) {
|
||||||
|
serverFhirVersionEnum = FhirVersionEnum.DSTU2;
|
||||||
|
} else if (serverFhirVersionString.startsWith("0.5")) {
|
||||||
serverFhirVersionEnum = FhirVersionEnum.DSTU2;
|
serverFhirVersionEnum = FhirVersionEnum.DSTU2;
|
||||||
} else {
|
} else {
|
||||||
// we'll be lenient and accept this
|
// we'll be lenient and accept this
|
||||||
|
@ -307,9 +316,22 @@ public class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
if (serverFhirVersionEnum != null) {
|
if (serverFhirVersionEnum != null) {
|
||||||
FhirVersionEnum contextFhirVersion = myContext.getVersion().getVersion();
|
FhirVersionEnum contextFhirVersion = myContext.getVersion().getVersion();
|
||||||
if (!contextFhirVersion.isEquivalentTo(serverFhirVersionEnum)) {
|
if (!contextFhirVersion.isEquivalentTo(serverFhirVersionEnum)) {
|
||||||
throw new FhirClientConnectionException(myContext.getLocalizer().getMessage(RestfulClientFactory.class, "wrongVersionInConformance", theServerBase + Constants.URL_TOKEN_METADATA, serverFhirVersionString, serverFhirVersionEnum, contextFhirVersion));
|
throw new FhirClientInnapropriateForServerException(myContext.getLocalizer().getMessage(RestfulClientFactory.class, "wrongVersionInConformance", theServerBase + Constants.URL_TOKEN_METADATA, serverFhirVersionString, serverFhirVersionEnum, contextFhirVersion));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myValidatedServerBaseUrls.add(normalizeBaseUrlForMap(theServerBase));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerValidationModeEnum getServerValidationModeEnum() {
|
||||||
|
return getServerValidationMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setServerValidationModeEnum(ServerValidationModeEnum theServerValidationMode) {
|
||||||
|
setServerValidationMode(theServerValidationMode);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ca.uhn.fhir.rest.client.exceptions;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%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 ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception will be thrown by FHIR clients if the client attempts to
|
||||||
|
* communicate with a server which is a valid FHIR server but is incompatible
|
||||||
|
* with this client for some reason.
|
||||||
|
*/
|
||||||
|
public class FhirClientInnapropriateForServerException extends BaseServerResponseException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public FhirClientInnapropriateForServerException(Throwable theCause) {
|
||||||
|
super(0, theCause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FhirClientInnapropriateForServerException(String theMessage, Throwable theCause) {
|
||||||
|
super(0, theMessage, theCause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FhirClientInnapropriateForServerException(String theMessage) {
|
||||||
|
super(0, theMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ public interface ITransaction {
|
||||||
/**
|
/**
|
||||||
* Use a list of resources as the transaction input
|
* Use a list of resources as the transaction input
|
||||||
*/
|
*/
|
||||||
ITransactionTyped<List<IBaseResource>> withResources(List<IBaseResource> theResources);
|
ITransactionTyped<List<IBaseResource>> withResources(List<? extends IBaseResource> theResources);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a DSTU1 Bundle (Atom) as the transaction input
|
* Use a DSTU1 Bundle (Atom) as the transaction input
|
||||||
|
@ -44,9 +44,9 @@ public interface ITransaction {
|
||||||
*/
|
*/
|
||||||
<T extends IBaseBundle> ITransactionTyped<T> withBundle(T theBundleResource);
|
<T extends IBaseBundle> ITransactionTyped<T> withBundle(T theBundleResource);
|
||||||
|
|
||||||
// *****
|
/**
|
||||||
// TODO: add withString version
|
* Use the given raw text (should be a Bundle resource) as the transaction input
|
||||||
// If we add a withString version, make sure to auto-detect content type!
|
*/
|
||||||
// *****
|
ITransactionTyped<String> withBundle(String theBundle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
|
@ -47,6 +48,7 @@ import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author James Agnew
|
* @author James Agnew
|
||||||
|
@ -63,7 +65,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
|
||||||
private String myIfNoneExistString;
|
private String myIfNoneExistString;
|
||||||
private Map<String, List<String>> myParams;
|
private Map<String, List<String>> myParams;
|
||||||
private final IBaseResource myResource;
|
private final IBaseResource myResource;
|
||||||
private final List<IBaseResource> myResources;
|
private final List<? extends IBaseResource> myResources;
|
||||||
private final TagList myTagList;
|
private final TagList myTagList;
|
||||||
private final String myUrlPath;
|
private final String myUrlPath;
|
||||||
|
|
||||||
|
@ -103,7 +105,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
|
||||||
myBundleType = null;
|
myBundleType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseHttpClientInvocationWithContents(FhirContext theContext, List<IBaseResource> theResources, BundleTypeEnum theBundleType) {
|
public BaseHttpClientInvocationWithContents(FhirContext theContext, List<? extends IBaseResource> theResources, BundleTypeEnum theBundleType) {
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
myResource = null;
|
myResource = null;
|
||||||
myTagList = null;
|
myTagList = null;
|
||||||
|
@ -270,7 +272,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
|
||||||
}
|
}
|
||||||
} else if (myContents != null) {
|
} else if (myContents != null) {
|
||||||
contents = myContents;
|
contents = myContents;
|
||||||
if (myContentsIsBundle) {
|
if (myContentsIsBundle && myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
||||||
contentType = encoding.getBundleContentType();
|
contentType = encoding.getBundleContentType();
|
||||||
} else {
|
} else {
|
||||||
contentType = encoding.getResourceContentType();
|
contentType = encoding.getResourceContentType();
|
||||||
|
|
|
@ -173,6 +173,25 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
*/
|
*/
|
||||||
public abstract String getResourceName();
|
public abstract String getResourceName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of {@link #getResourceOperationType()} or {@link #getSystemOperationType()} or {@link #getOtherOperationType()}
|
||||||
|
*/
|
||||||
|
public String getResourceOrSystemOperationType() {
|
||||||
|
Enum<?> retVal = getResourceOperationType();
|
||||||
|
if (retVal != null) {
|
||||||
|
return retVal.name();
|
||||||
|
}
|
||||||
|
retVal = getSystemOperationType();
|
||||||
|
if (retVal != null) {
|
||||||
|
return retVal.name();
|
||||||
|
}
|
||||||
|
retVal = getOtherOperationType();
|
||||||
|
if (retVal != null) {
|
||||||
|
return retVal.name();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract RestfulOperationTypeEnum getResourceOperationType();
|
public abstract RestfulOperationTypeEnum getResourceOperationType();
|
||||||
|
|
||||||
public abstract RestfulOperationSystemEnum getSystemOperationType();
|
public abstract RestfulOperationSystemEnum getSystemOperationType();
|
||||||
|
|
|
@ -20,9 +20,12 @@ package ca.uhn.fhir.rest.method;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
@ -32,6 +35,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.IBaseResource;
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
|
@ -53,6 +57,7 @@ import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
|
||||||
abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<MethodOutcome> {
|
abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<MethodOutcome> {
|
||||||
|
@ -65,7 +70,8 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
|
|
||||||
if (!theMethod.getReturnType().equals(MethodOutcome.class)) {
|
if (!theMethod.getReturnType().equals(MethodOutcome.class)) {
|
||||||
if (!allowVoidReturnType()) {
|
if (!allowVoidReturnType()) {
|
||||||
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " is a @" + theMethodAnnotation.getSimpleName() + " method but it does not return " + MethodOutcome.class);
|
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " is a @" + theMethodAnnotation.getSimpleName()
|
||||||
|
+ " method but it does not return " + MethodOutcome.class);
|
||||||
} else if (theMethod.getReturnType() == void.class) {
|
} else if (theMethod.getReturnType() == void.class) {
|
||||||
myReturnVoid = true;
|
myReturnVoid = true;
|
||||||
}
|
}
|
||||||
|
@ -101,8 +107,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
protected abstract BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource resource);
|
protected abstract BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource resource);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For servers, this method will match only incoming requests that match the given operation, or which have no
|
* For servers, this method will match only incoming requests that match the given operation, or which have no operation in the URL if this method returns null.
|
||||||
* operation in the URL if this method returns null.
|
|
||||||
*/
|
*/
|
||||||
protected abstract String getMatchingOperation();
|
protected abstract String getMatchingOperation();
|
||||||
|
|
||||||
|
@ -126,7 +131,8 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException,
|
||||||
|
BaseServerResponseException {
|
||||||
switch (theResponseStatusCode) {
|
switch (theResponseStatusCode) {
|
||||||
case Constants.STATUS_HTTP_200_OK:
|
case Constants.STATUS_HTTP_200_OK:
|
||||||
case Constants.STATUS_HTTP_201_CREATED:
|
case Constants.STATUS_HTTP_201_CREATED:
|
||||||
|
@ -198,7 +204,8 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
switch (getResourceOperationType()) {
|
switch (getResourceOperationType()) {
|
||||||
case CREATE:
|
case CREATE:
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
throw new InternalErrorException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName() + " returned null, which is not allowed for create operation");
|
throw new InternalErrorException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName()
|
||||||
|
+ " returned null, which is not allowed for create operation");
|
||||||
}
|
}
|
||||||
if (response.getCreated() == null || Boolean.TRUE.equals(response.getCreated())) {
|
if (response.getCreated() == null || Boolean.TRUE.equals(response.getCreated())) {
|
||||||
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||||
|
@ -272,9 +279,39 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected IBaseResource parseIncomingServerResource(Request theRequest) throws IOException {
|
protected IBaseResource parseIncomingServerResource(Request theRequest) throws IOException {
|
||||||
EncodingEnum encoding = RestfulServerUtils.determineRequestEncoding(theRequest);
|
|
||||||
|
Reader requestReader;
|
||||||
|
EncodingEnum encoding = RestfulServerUtils.determineRequestEncodingNoDefault(theRequest);
|
||||||
|
if (encoding == null) {
|
||||||
|
String ctValue = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
|
||||||
|
if (ctValue != null) {
|
||||||
|
if (ctValue.startsWith("application/x-www-form-urlencoded")) {
|
||||||
|
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBinding.class, "invalidContentTypeInRequest", ctValue, getResourceOrSystemOperationType());
|
||||||
|
throw new InvalidRequestException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isBlank(ctValue)) {
|
||||||
|
/*
|
||||||
|
* If the client didn't send a content type, try to guess
|
||||||
|
*/
|
||||||
|
requestReader = theRequest.getServletRequest().getReader();
|
||||||
|
String body = IOUtils.toString(requestReader);
|
||||||
|
encoding = MethodUtil.detectEncodingNoDefault(body);
|
||||||
|
if (encoding == null) {
|
||||||
|
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBinding.class, "noContentTypeInRequest", getResourceOrSystemOperationType());
|
||||||
|
throw new InvalidRequestException(msg);
|
||||||
|
} else {
|
||||||
|
requestReader = new StringReader(body);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBinding.class, "invalidContentTypeInRequest", ctValue, getResourceOrSystemOperationType());
|
||||||
|
throw new InvalidRequestException(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
requestReader = theRequest.getServletRequest().getReader();
|
||||||
|
}
|
||||||
|
|
||||||
IParser parser = encoding.newParser(getContext());
|
IParser parser = encoding.newParser(getContext());
|
||||||
BufferedReader requestReader = theRequest.getServletRequest().getReader();
|
|
||||||
|
|
||||||
Class<? extends IBaseResource> wantedResourceType = requestContainsResourceType();
|
Class<? extends IBaseResource> wantedResourceType = requestContainsResourceType();
|
||||||
IBaseResource retVal;
|
IBaseResource retVal;
|
||||||
|
@ -305,7 +342,8 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void streamOperationOutcome(BaseServerResponseException theE, RestfulServer theServer, EncodingEnum theEncodingNotNull, HttpServletResponse theResponse, Request theRequest) throws IOException {
|
protected void streamOperationOutcome(BaseServerResponseException theE, RestfulServer theServer, EncodingEnum theEncodingNotNull, HttpServletResponse theResponse, Request theRequest)
|
||||||
|
throws IOException {
|
||||||
theResponse.setStatus(theE.getStatusCode());
|
theResponse.setStatus(theE.getStatusCode());
|
||||||
|
|
||||||
theServer.addHeadersToResponse(theResponse);
|
theServer.addHeadersToResponse(theResponse);
|
||||||
|
|
|
@ -279,7 +279,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase());
|
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, respondGzip, theRequest.getFhirServerBase(), isAddContentLocationHeader());
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
Set<Include> includes = getRequestIncludesFromParams(params);
|
Set<Include> includes = getRequestIncludesFromParams(params);
|
||||||
|
@ -312,7 +312,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RestfulServerUtils.streamResponseAsResource(theServer, response, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase());
|
RestfulServerUtils.streamResponseAsResource(theServer, response, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase(), isAddContentLocationHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -336,12 +336,19 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, respondGzip, theRequest.getFhirServerBase());
|
RestfulServerUtils.streamResponseAsResource(theServer, response, resource, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, respondGzip, theRequest.getFhirServerBase(), isAddContentLocationHeader());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should the response include a Content-Location header. Search method bunding (and any others?) may override this to disable the content-location, since it doesn't make sense
|
||||||
|
*/
|
||||||
|
protected boolean isAddContentLocationHeader() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclasses may override
|
* Subclasses may override
|
||||||
*
|
*
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class HttpPostClientInvocation extends BaseHttpClientInvocationWithConten
|
||||||
super(theContext, theTagList, theUrlExtension);
|
super(theContext, theTagList, theUrlExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpPostClientInvocation(FhirContext theContext, List<IBaseResource> theResources, BundleTypeEnum theBundleType) {
|
public HttpPostClientInvocation(FhirContext theContext, List<? extends IBaseResource> theResources, BundleTypeEnum theBundleType) {
|
||||||
super(theContext, theResources, theBundleType);
|
super(theContext, theResources, theBundleType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,15 +249,26 @@ public class MethodUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EncodingEnum detectEncoding(String theBody) {
|
public static EncodingEnum detectEncoding(String theBody) {
|
||||||
for (int i = 0; i < theBody.length(); i++) {
|
EncodingEnum retVal = detectEncodingNoDefault(theBody);
|
||||||
|
if (retVal == null) {
|
||||||
|
retVal = EncodingEnum.XML;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EncodingEnum detectEncodingNoDefault(String theBody) {
|
||||||
|
EncodingEnum retVal = null;
|
||||||
|
for (int i = 0; i < theBody.length() && retVal == null; i++) {
|
||||||
switch (theBody.charAt(i)) {
|
switch (theBody.charAt(i)) {
|
||||||
case '<':
|
case '<':
|
||||||
return EncodingEnum.XML;
|
retVal = EncodingEnum.XML;
|
||||||
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
return EncodingEnum.JSON;
|
retVal = EncodingEnum.JSON;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return EncodingEnum.XML;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void extractDescription(SearchParameter theParameter, Annotation[] theAnnotations) {
|
public static void extractDescription(SearchParameter theParameter, Annotation[] theAnnotations) {
|
||||||
|
|
|
@ -132,6 +132,11 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
return RestfulOperationTypeEnum.SEARCH_TYPE;
|
return RestfulOperationTypeEnum.SEARCH_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BundleTypeEnum getResponseBundleType() {
|
||||||
|
return BundleTypeEnum.SEARCHSET;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReturnTypeEnum getReturnType() {
|
public ReturnTypeEnum getReturnType() {
|
||||||
return ReturnTypeEnum.BUNDLE;
|
return ReturnTypeEnum.BUNDLE;
|
||||||
|
@ -289,13 +294,9 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResourceType(Class<? extends IResource> resourceType) {
|
|
||||||
this.myDeclaredResourceType = resourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
protected boolean isAddContentLocationHeader() {
|
||||||
return getMethod().toString();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) {
|
private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) {
|
||||||
|
@ -313,6 +314,15 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResourceType(Class<? extends IResource> resourceType) {
|
||||||
|
this.myDeclaredResourceType = resourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getMethod().toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName,
|
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName,
|
||||||
SearchStyleEnum theSearchStyle) {
|
SearchStyleEnum theSearchStyle) {
|
||||||
SearchStyleEnum searchStyle = theSearchStyle;
|
SearchStyleEnum searchStyle = theSearchStyle;
|
||||||
|
@ -473,9 +483,4 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BundleTypeEnum getResponseBundleType() {
|
|
||||||
return BundleTypeEnum.SEARCHSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,8 +195,12 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
||||||
return new HttpPostClientInvocation(theContext, theBundle);
|
return new HttpPostClientInvocation(theContext, theBundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseHttpClientInvocation createTransactionInvocation(List<IBaseResource> theResources, FhirContext theContext) {
|
public static BaseHttpClientInvocation createTransactionInvocation(List<? extends IBaseResource> theResources, FhirContext theContext) {
|
||||||
return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
|
return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BaseHttpClientInvocation createTransactionInvocation(String theRawBundle, FhirContext theContext) {
|
||||||
|
return new HttpPostClientInvocation(theContext, theRawBundle, true, "");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,8 +203,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
addResourcesToBundle(new ArrayList<IBaseResource>(resourceList), theBundleType, theServerBase, theServer.getBundleInclusionRule(), theIncludes);
|
||||||
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
|
addRootPropertiesToBundle(null, theServerBase, theCompleteUrl, theResult.size(), theBundleType);
|
||||||
|
|
||||||
myBundle.setPublished(theResult.getPublished());
|
|
||||||
|
|
||||||
if (theServer.getPagingProvider() != null) {
|
if (theServer.getPagingProvider() != null) {
|
||||||
int limit;
|
int limit;
|
||||||
limit = theLimit != null ? theLimit : theServer.getPagingProvider().getDefaultPageSize();
|
limit = theLimit != null ? theLimit : theServer.getPagingProvider().getDefaultPageSize();
|
||||||
|
@ -232,10 +230,6 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
myBundle.getBundleId().setValue(UUID.randomUUID().toString());
|
myBundle.getBundleId().setValue(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myBundle.getPublished().isEmpty()) {
|
|
||||||
myBundle.getPublished().setToCurrentTimeInLocalTimeZone();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myBundle.getLinkBase().isEmpty()) {
|
if (myBundle.getLinkBase().isEmpty()) {
|
||||||
myBundle.getLinkBase().setValue(theServerBase);
|
myBundle.getLinkBase().setValue(theServerBase);
|
||||||
}
|
}
|
||||||
|
@ -264,12 +258,11 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||||
myBundle = new Bundle();
|
myBundle = new Bundle();
|
||||||
|
|
||||||
myBundle.getAuthorName().setValue(theAuthor);
|
myBundle.getAuthorName().setValue(theAuthor);
|
||||||
myBundle.getBundleId().setValue(UUID.randomUUID().toString());
|
myBundle.getBundleId().setValue(UUID.randomUUID().toString());
|
||||||
myBundle.getPublished().setToCurrentTimeInLocalTimeZone();
|
|
||||||
myBundle.getLinkBase().setValue(theServerBase);
|
myBundle.getLinkBase().setValue(theServerBase);
|
||||||
myBundle.getLinkSelf().setValue(theCompleteUrl);
|
myBundle.getLinkSelf().setValue(theCompleteUrl);
|
||||||
myBundle.getType().setValueAsEnum(theBundleType);
|
myBundle.getType().setValueAsEnum(theBundleType);
|
||||||
|
|
|
@ -46,7 +46,7 @@ public interface IVersionSpecificBundleFactory {
|
||||||
|
|
||||||
IBaseResource getResourceBundle();
|
IBaseResource getResourceBundle();
|
||||||
|
|
||||||
void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType);
|
void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType);
|
||||||
|
|
||||||
void initializeWithBundleResource(IBaseResource theResource);
|
void initializeWithBundleResource(IBaseResource theResource);
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,19 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||||
|
|
||||||
|
private String myServletPath;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
||||||
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
|
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
|
||||||
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
|
||||||
|
String servletPath;
|
||||||
|
if (myServletPath != null) {
|
||||||
|
servletPath = myServletPath;
|
||||||
|
} else {
|
||||||
|
servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
||||||
|
}
|
||||||
|
|
||||||
StringBuffer requestUrl = theRequest.getRequestURL();
|
StringBuffer requestUrl = theRequest.getRequestURL();
|
||||||
String servletContextPath = "";
|
String servletContextPath = "";
|
||||||
if (theServletContext != null) {
|
if (theServletContext != null) {
|
||||||
|
@ -48,7 +57,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
int startOfPath = requestUrl.indexOf("//");
|
int startOfPath = requestUrl.indexOf("//");
|
||||||
if (startOfPath != -1 && (startOfPath + 2) < requestUrl.length()) {
|
int requestUrlLength = requestUrl.length();
|
||||||
|
|
||||||
|
if (startOfPath != -1 && (startOfPath + 2) < requestUrlLength) {
|
||||||
startOfPath = requestUrl.indexOf("/", startOfPath + 2);
|
startOfPath = requestUrl.indexOf("/", startOfPath + 2);
|
||||||
}
|
}
|
||||||
if (startOfPath == -1) {
|
if (startOfPath == -1) {
|
||||||
|
@ -56,9 +67,9 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
int contextIndex;
|
int contextIndex;
|
||||||
if (servletPath.length() == 0) {
|
if (servletPath.length() == 0 || servletPath.equals("/")) {
|
||||||
if (requestPath.length() == 0) {
|
if (requestPath.length() == 0) {
|
||||||
contextIndex = requestUrl.length();
|
contextIndex = requestUrlLength;
|
||||||
} else {
|
} else {
|
||||||
contextIndex = requestUrl.indexOf(requestPath, startOfPath);
|
contextIndex = requestUrl.indexOf(requestPath, startOfPath);
|
||||||
}
|
}
|
||||||
|
@ -68,8 +79,30 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||||
|
|
||||||
String fhirServerBase;
|
String fhirServerBase;
|
||||||
int length = contextIndex + servletPath.length();
|
int length = contextIndex + servletPath.length();
|
||||||
|
if (length > requestUrlLength) {
|
||||||
|
length = requestUrlLength;
|
||||||
|
}
|
||||||
fhirServerBase = requestUrl.substring(0, length);
|
fhirServerBase = requestUrl.substring(0, length);
|
||||||
return fhirServerBase;
|
return fhirServerBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to a non-null value (default is <code>null</code>), this address strategy assumes that the FHIR endpoint is deployed to the given servlet path within the context. This is useful in some
|
||||||
|
* deployments where it isn't obvious to the servlet which part of the path is actually the root path to reach the servlet.
|
||||||
|
* <p>
|
||||||
|
* Example values could be:
|
||||||
|
* <ul>
|
||||||
|
* <li>null</li>
|
||||||
|
* <li>/</li>
|
||||||
|
* <li>/base</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>Wildcards are not supported!</b>
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void setServletPath(String theServletPath) {
|
||||||
|
myServletPath = theServletPath;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%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 java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -490,7 +490,7 @@ public class RestfulServer extends HttpServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RestfulServerUtils.streamResponseAsResource(this, theResponse, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase());
|
RestfulServerUtils.streamResponseAsResource(this, theResponse, (IResource) resBundle, responseEncoding, prettyPrint, requestIsBrowser, narrativeMode, Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), theRequest.getFhirServerBase(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,10 +76,10 @@ public class RestfulServerUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase) throws IOException {
|
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase, boolean theAddContentLocationHeader) throws IOException {
|
||||||
theHttpResponse.setStatus(stausCode);
|
theHttpResponse.setStatus(stausCode);
|
||||||
|
|
||||||
if (theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
|
if (theAddContentLocationHeader && theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {
|
||||||
String resName = theServer.getFhirContext().getResourceDefinition(theResource).getName();
|
String resName = theServer.getFhirContext().getResourceDefinition(theResource).getName();
|
||||||
IIdType fullId = theResource.getId().withServerBase(theServerBase, resName);
|
IIdType fullId = theResource.getId().withServerBase(theServerBase, resName);
|
||||||
theHttpResponse.addHeader(Constants.HEADER_CONTENT_LOCATION, fullId.getValue());
|
theHttpResponse.addHeader(Constants.HEADER_CONTENT_LOCATION, fullId.getValue());
|
||||||
|
@ -205,9 +205,18 @@ public class RestfulServerUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EncodingEnum determineRequestEncoding(Request theReq) {
|
public static EncodingEnum determineRequestEncoding(Request theReq) {
|
||||||
|
EncodingEnum retVal = determineRequestEncodingNoDefault(theReq);
|
||||||
|
if (retVal != null) {
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
return EncodingEnum.XML;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EncodingEnum determineRequestEncodingNoDefault(Request theReq) {
|
||||||
|
EncodingEnum retVal = null;
|
||||||
Enumeration<String> acceptValues = theReq.getServletRequest().getHeaders(Constants.HEADER_CONTENT_TYPE);
|
Enumeration<String> acceptValues = theReq.getServletRequest().getHeaders(Constants.HEADER_CONTENT_TYPE);
|
||||||
if (acceptValues != null) {
|
if (acceptValues != null) {
|
||||||
while (acceptValues.hasMoreElements()) {
|
while (acceptValues.hasMoreElements() && retVal == null) {
|
||||||
String nextAcceptHeaderValue = acceptValues.nextElement();
|
String nextAcceptHeaderValue = acceptValues.nextElement();
|
||||||
if (nextAcceptHeaderValue != null && isNotBlank(nextAcceptHeaderValue)) {
|
if (nextAcceptHeaderValue != null && isNotBlank(nextAcceptHeaderValue)) {
|
||||||
for (String nextPart : nextAcceptHeaderValue.split(",")) {
|
for (String nextPart : nextAcceptHeaderValue.split(",")) {
|
||||||
|
@ -219,16 +228,16 @@ public class RestfulServerUtils {
|
||||||
nextPart = nextPart.substring(0, scIdx);
|
nextPart = nextPart.substring(0, scIdx);
|
||||||
}
|
}
|
||||||
nextPart = nextPart.trim();
|
nextPart = nextPart.trim();
|
||||||
EncodingEnum retVal = Constants.FORMAT_VAL_TO_ENCODING.get(nextPart);
|
retVal = Constants.FORMAT_VAL_TO_ENCODING.get(nextPart);
|
||||||
if (retVal != null) {
|
if (retVal != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return EncodingEnum.XML;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createPagingLink(Set<Include> theIncludes, String theServerBase, String theSearchId, int theOffset, int theCount, EncodingEnum theResponseEncoding, boolean thePrettyPrint) {
|
public static String createPagingLink(Set<Include> theIncludes, String theServerBase, String theSearchId, int theOffset, int theCount, EncodingEnum theResponseEncoding, boolean thePrettyPrint) {
|
||||||
try {
|
try {
|
||||||
|
@ -413,12 +422,12 @@ public class RestfulServerUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
// public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
|
||||||
boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
|
// boolean theRequestIsBrowser, RestfulServer.NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
|
||||||
int stausCode = 200;
|
// int stausCode = 200;
|
||||||
RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
|
// RestfulServerUtils.streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip,
|
||||||
theServerBase);
|
// theServerBase);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static void validateResourceListNotNull(List<? extends IBaseResource> theResourceList) {
|
public static void validateResourceListNotNull(List<? extends IBaseResource> theResourceList) {
|
||||||
if (theResourceList == null) {
|
if (theResourceList == null) {
|
||||||
|
|
|
@ -20,6 +20,8 @@ package ca.uhn.fhir.rest.server.exceptions;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
||||||
|
@ -43,6 +45,14 @@ public class ResourceNotFoundException extends BaseServerResponseException {
|
||||||
super(STATUS_CODE, createErrorMessage(theClass, theId), theOperationOutcome);
|
super(STATUS_CODE, createErrorMessage(theClass, theId), theOperationOutcome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResourceNotFoundException(Class<? extends IResource> theClass, IIdType theId) {
|
||||||
|
super(STATUS_CODE, createErrorMessage(theClass, theId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceNotFoundException(Class<? extends IResource> theClass, IIdType theId, BaseOperationOutcome theOperationOutcome) {
|
||||||
|
super(STATUS_CODE, createErrorMessage(theClass, theId), theOperationOutcome);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
|
@ -66,6 +76,10 @@ public class ResourceNotFoundException extends BaseServerResponseException {
|
||||||
super(STATUS_CODE, createErrorMessage(theId));
|
super(STATUS_CODE, createErrorMessage(theId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResourceNotFoundException(IIdType theId) {
|
||||||
|
super(STATUS_CODE, createErrorMessage(theId));
|
||||||
|
}
|
||||||
|
|
||||||
public ResourceNotFoundException(IdDt theId, BaseOperationOutcome theOperationOutcome) {
|
public ResourceNotFoundException(IdDt theId, BaseOperationOutcome theOperationOutcome) {
|
||||||
super(STATUS_CODE, createErrorMessage(theId), theOperationOutcome);
|
super(STATUS_CODE, createErrorMessage(theId), theOperationOutcome);
|
||||||
}
|
}
|
||||||
|
@ -74,11 +88,11 @@ public class ResourceNotFoundException extends BaseServerResponseException {
|
||||||
super(STATUS_CODE, theMessage);
|
super(STATUS_CODE, theMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String createErrorMessage(Class<? extends IResource> theClass, IdDt theId) {
|
private static String createErrorMessage(Class<? extends IResource> theClass, IIdType theId) {
|
||||||
return "Resource of type " + theClass.getSimpleName() + " with ID " + theId + " is not known";
|
return "Resource of type " + theClass.getSimpleName() + " with ID " + theId + " is not known";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String createErrorMessage(IdDt theId) {
|
private static String createErrorMessage(IIdType theId) {
|
||||||
return "Resource " + (theId != null ? theId.getValue() : "") + " is not known";
|
return "Resource " + (theId != null ? theId.getValue() : "") + " is not known";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
||||||
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
|
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
|
||||||
String fhirServerBase = ((Request) theRequestDetails).getFhirServerBase();
|
String fhirServerBase = ((Request) theRequestDetails).getFhirServerBase();
|
||||||
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
|
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
|
||||||
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase);
|
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
|
||||||
|
|
||||||
// theResponse.setStatus(statusCode);
|
// theResponse.setStatus(statusCode);
|
||||||
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
package ca.uhn.fhir.rest.server.interceptor;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* #%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 static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
|
||||||
import ca.uhn.fhir.rest.method.Request;
|
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
|
|
||||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
|
|
||||||
public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptor.class);
|
|
||||||
private Class<?>[] myReturnStackTracesForExceptionTypes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* @return Returns an instance of this interceptor, to allow for easy method chaining.
|
|
||||||
*/
|
|
||||||
public ExceptionHandlingInterceptor setReturnStackTracesForExceptionTypes(Class<?>... theExceptionTypes) {
|
|
||||||
myReturnStackTracesForExceptionTypes = theExceptionTypes;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
<<<<<<< HEAD
|
|
||||||
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
|
||||||
=======
|
|
||||||
public boolean handleException(RestfulServer theRestfulServer, RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
|
||||||
ourLog.error("AA", theException);
|
|
||||||
>>>>>>> 5956ab75fd9186ccc8b9836b60bc421b19d3d288
|
|
||||||
BaseOperationOutcome oo = null;
|
|
||||||
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
FhirContext ctx = theRestfulServer.getFhirContext();
|
|
||||||
|
|
||||||
if (theException instanceof BaseServerResponseException) {
|
|
||||||
oo = ((BaseServerResponseException) theException).getOperationOutcome();
|
|
||||||
statusCode = ((BaseServerResponseException) theException).getStatusCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generate an OperationOutcome to return, unless the exception throw by the resource provider had one
|
|
||||||
*/
|
|
||||||
if (oo == null) {
|
|
||||||
try {
|
|
||||||
oo = (BaseOperationOutcome) ctx.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
|
|
||||||
} catch (Exception e1) {
|
|
||||||
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
|
|
||||||
throw new ServletException("Failed to instantiate OperationOutcome resource instance", e1);
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseIssue issue = oo.addIssue();
|
|
||||||
issue.getSeverityElement().setValue("error");
|
|
||||||
if (theException instanceof InternalErrorException) {
|
|
||||||
ourLog.error("Failure during REST processing", theException);
|
|
||||||
populateDetails(theException, issue);
|
|
||||||
} else if (theException instanceof BaseServerResponseException) {
|
|
||||||
ourLog.warn("Failure during REST processing: {}", theException);
|
|
||||||
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
|
|
||||||
statusCode = baseServerResponseException.getStatusCode();
|
|
||||||
populateDetails(theException, issue);
|
|
||||||
if (baseServerResponseException.getAdditionalMessages() != null) {
|
|
||||||
for (String next : baseServerResponseException.getAdditionalMessages()) {
|
|
||||||
BaseIssue issue2 = oo.addIssue();
|
|
||||||
issue2.getSeverityElement().setValue("error");
|
|
||||||
issue2.setDetails(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
|
|
||||||
populateDetails(theException, issue);
|
|
||||||
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ourLog.error("Unknown error during processing", theException);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add headers associated with the specific error code
|
|
||||||
if (theException instanceof BaseServerResponseException) {
|
|
||||||
Map<String, String[]> additional = ((BaseServerResponseException) theException).getAssociatedHeaders();
|
|
||||||
if (additional != null) {
|
|
||||||
for (Entry<String, String[]> next : additional.entrySet()) {
|
|
||||||
if (isNotBlank(next.getKey()) && next.getValue() != null) {
|
|
||||||
String nextKey = next.getKey();
|
|
||||||
for (String nextValue : next.getValue()) {
|
|
||||||
theResponse.addHeader(nextKey, nextValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
|
|
||||||
String fhirServerBase = theRestfulServer.getServerBaseForRequest(theRequest);
|
|
||||||
|
|
||||||
RestfulServerUtils.streamResponseAsResource(theRestfulServer, theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
|
|
||||||
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase);
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
// theResponse.setStatus(statusCode);
|
|
||||||
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
|
||||||
// theResponse.setContentType("text/plain");
|
|
||||||
// theResponse.setCharacterEncoding("UTF-8");
|
|
||||||
// theResponse.getWriter().append(theException.getMessage());
|
|
||||||
// theResponse.getWriter().close();
|
|
||||||
=======
|
|
||||||
theResponse.setStatus(statusCode);
|
|
||||||
theRestfulServer.addHeadersToResponse(theResponse);
|
|
||||||
theResponse.setContentType("text/plain");
|
|
||||||
theResponse.setCharacterEncoding("UTF-8");
|
|
||||||
theResponse.getWriter().append(theException.getMessage());
|
|
||||||
theResponse.getWriter().close();
|
|
||||||
>>>>>>> 5956ab75fd9186ccc8b9836b60bc421b19d3d288
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateDetails(Throwable theException, BaseIssue issue) {
|
|
||||||
if (myReturnStackTracesForExceptionTypes != null) {
|
|
||||||
for (Class<?> next : myReturnStackTracesForExceptionTypes) {
|
|
||||||
if (next.isAssignableFrom(theException.getClass())) {
|
|
||||||
issue.getDetailsElement().setValue(theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue.getDetailsElement().setValue(theException.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -61,7 +61,7 @@ public class FhirTerser {
|
||||||
if (theElement instanceof ISupportsUndeclaredExtensions) {
|
if (theElement instanceof ISupportsUndeclaredExtensions) {
|
||||||
ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement;
|
ISupportsUndeclaredExtensions containingElement = (ISupportsUndeclaredExtensions) theElement;
|
||||||
for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) {
|
for (ExtensionDt nextExt : containingElement.getUndeclaredExtensions()) {
|
||||||
theCallback.acceptUndeclaredExtension(containingElement, theChildDefinition, theDefinition, nextExt);
|
theCallback.acceptUndeclaredExtension(containingElement, null, theChildDefinition, theDefinition, nextExt);
|
||||||
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
|
addUndeclaredExtensions(nextExt, theDefinition, theChildDefinition, theCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,10 +90,10 @@ public class FhirTerser {
|
||||||
public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
|
public <T extends IBase> List<T> getAllPopulatedChildElementsOfType(IBaseResource theResource, final Class<T> theType) {
|
||||||
final ArrayList<T> retVal = new ArrayList<T>();
|
final ArrayList<T> retVal = new ArrayList<T>();
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(theResource, null, def, new IModelVisitor() {
|
visit(theResource, null, null, def, new IModelVisitor() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
if (theElement == null || theElement.isEmpty()) {
|
if (theElement == null || theElement.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,8 @@ public class FhirTerser {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
|
||||||
|
ExtensionDt theNextExt) {
|
||||||
if (theType.isAssignableFrom(theNextExt.getClass())) {
|
if (theType.isAssignableFrom(theNextExt.getClass())) {
|
||||||
retVal.add((T) theNextExt);
|
retVal.add((T) theNextExt);
|
||||||
}
|
}
|
||||||
|
@ -117,32 +118,25 @@ public class FhirTerser {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
public <T extends IBase> List<ResourceReferenceInfo> getAllResourceReferences(final IBaseResource theResource) {
|
||||||
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>();
|
final ArrayList<ResourceReferenceInfo> retVal = new ArrayList<ResourceReferenceInfo>();
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(theResource, null, def, new IModelVisitor() {
|
visit(theResource, null, null, def, new IModelVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||||
if (theElement == null || theElement.isEmpty()) {
|
if (theElement == null || theElement.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String name = null;
|
|
||||||
if (theChildDefinition != null) {
|
|
||||||
name = theChildDefinition.getElementName();
|
|
||||||
}
|
|
||||||
if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) {
|
if (BaseResourceReferenceDt.class.isAssignableFrom(theElement.getClass())) {
|
||||||
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theElement));
|
retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theElement));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition,
|
||||||
String name = null;
|
ExtensionDt theNextExt) {
|
||||||
if (theChildDefinition != null) {
|
|
||||||
name = theChildDefinition.getElementName();
|
|
||||||
}
|
|
||||||
if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) {
|
if (theNextExt.getValue() != null && BaseResourceReferenceDt.class.isAssignableFrom(theNextExt.getValue().getClass())) {
|
||||||
retVal.add(new ResourceReferenceInfo(theResource, name, (BaseResourceReferenceDt) theNextExt.getValue()));
|
retVal.add(new ResourceReferenceInfo(theResource, thePathToElement, (BaseResourceReferenceDt)theNextExt.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -222,8 +216,19 @@ public class FhirTerser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visit(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
|
private List<String> addNameToList(List<String> theCurrentList, BaseRuntimeChildDefinition theChildDefinition) {
|
||||||
theCallback.acceptElement(theElement, theChildDefinition, theDefinition);
|
if (theChildDefinition == null)
|
||||||
|
return null;
|
||||||
|
if (theCurrentList== null || theCurrentList.isEmpty())
|
||||||
|
return new ArrayList<String>(Arrays.asList(theChildDefinition.getElementName()));
|
||||||
|
List<String> newList = new ArrayList<String>(theCurrentList);
|
||||||
|
newList.add(theChildDefinition.getElementName());
|
||||||
|
return newList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visit(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, IModelVisitor theCallback) {
|
||||||
|
List<String> pathToElement = addNameToList(thePathToElement, theChildDefinition);
|
||||||
|
theCallback.acceptElement(theElement, pathToElement, theChildDefinition, theDefinition);
|
||||||
addUndeclaredExtensions(theElement, theDefinition, theChildDefinition, theCallback);
|
addUndeclaredExtensions(theElement, theDefinition, theChildDefinition, theCallback);
|
||||||
|
|
||||||
// if (theElement.isEmpty()) {
|
// if (theElement.isEmpty()) {
|
||||||
|
@ -243,7 +248,7 @@ public class FhirTerser {
|
||||||
IBaseResource theResource = resRefDt.getResource();
|
IBaseResource theResource = resRefDt.getResource();
|
||||||
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
|
if (theResource.getId() == null || theResource.getId().isEmpty() || theResource.getId().isLocal()) {
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(theResource, null, def, theCallback);
|
visit(theResource, pathToElement, null, def, theCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -285,9 +290,9 @@ public class FhirTerser {
|
||||||
|
|
||||||
if (nextChild instanceof RuntimeChildDirectResource) {
|
if (nextChild instanceof RuntimeChildDirectResource) {
|
||||||
// Don't descend into embedded resources
|
// Don't descend into embedded resources
|
||||||
theCallback.acceptElement(nextValue, nextChild, childElementDef);
|
theCallback.acceptElement(nextValue, null, nextChild, childElementDef);
|
||||||
} else {
|
} else {
|
||||||
visit(nextValue, nextChild, childElementDef, theCallback);
|
visit(nextValue, pathToElement, nextChild, childElementDef, theCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +303,7 @@ public class FhirTerser {
|
||||||
BaseContainedDt value = (BaseContainedDt) theElement;
|
BaseContainedDt value = (BaseContainedDt) theElement;
|
||||||
for (IResource next : value.getContainedResources()) {
|
for (IResource next : value.getContainedResources()) {
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(next);
|
||||||
visit(next, null, def, theCallback);
|
visit(next, pathToElement, null, def, theCallback);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +314,7 @@ public class FhirTerser {
|
||||||
case CONTAINED_RESOURCE_LIST:
|
case CONTAINED_RESOURCE_LIST:
|
||||||
if (theElement != null) {
|
if (theElement != null) {
|
||||||
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass());
|
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass());
|
||||||
visit(theElement, null, def, theCallback);
|
visit(theElement, null, theChildDefinition, def, theCallback);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -454,7 +459,7 @@ public class FhirTerser {
|
||||||
*/
|
*/
|
||||||
public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
|
public void visit(IBaseResource theResource, IModelVisitor theVisitor) {
|
||||||
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
BaseRuntimeElementCompositeDefinition<?> def = myContext.getResourceDefinition(theResource);
|
||||||
visit(theResource, null, def, theVisitor);
|
visit(theResource, null, null, def, theVisitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,6 +28,8 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||||
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see FhirTerser#visit(IBaseResource, IModelVisitor)
|
* @see FhirTerser#visit(IBaseResource, IModelVisitor)
|
||||||
*/
|
*/
|
||||||
|
@ -39,7 +41,7 @@ public interface IModelVisitor {
|
||||||
* @param theChildDefinition May be null if this is a root element
|
* @param theChildDefinition May be null if this is a root element
|
||||||
* @param theDefinition
|
* @param theDefinition
|
||||||
*/
|
*/
|
||||||
void acceptElement(IBase theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition);
|
void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -48,7 +50,7 @@ public interface IModelVisitor {
|
||||||
* @param theDefinition
|
* @param theDefinition
|
||||||
* @param theNextExt
|
* @param theNextExt
|
||||||
*/
|
*/
|
||||||
void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt);
|
void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%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 javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface isn't used by hapi-fhir-base, but is used by the
|
||||||
|
* <a href="http://jamesagnew.github.io/hapi-fhir/doc_server_tester.html">Web Testing UI</a>
|
||||||
|
*/
|
||||||
|
public interface ITestingUiClientFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate a new client
|
||||||
|
*/
|
||||||
|
IGenericClient newClient(FhirContext theFhirContext, HttpServletRequest theRequest, String theServerBaseUrl);
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,8 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hl7.fhir.instance.model.IBaseResource;
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,10 +40,21 @@ public class ResourceReferenceInfo {
|
||||||
private String myName;
|
private String myName;
|
||||||
private BaseResourceReferenceDt myResource;
|
private BaseResourceReferenceDt myResource;
|
||||||
|
|
||||||
public ResourceReferenceInfo(IBaseResource theOwningResource, String theName, BaseResourceReferenceDt theResource) {
|
public ResourceReferenceInfo(IBaseResource theOwningResource, List<String> thePathToElement, BaseResourceReferenceDt theResource) {
|
||||||
myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name();
|
myOwningResource = theOwningResource.getClass().getAnnotation(ResourceDef.class).name();
|
||||||
myName = theName;
|
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
|
if (thePathToElement != null && !thePathToElement.isEmpty()) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
thePathToElement.iterator();
|
||||||
|
for (Iterator<String> iterator = thePathToElement.iterator(); iterator.hasNext(); ) {
|
||||||
|
sb.append(iterator.next());
|
||||||
|
if (iterator.hasNext())
|
||||||
|
sb.append(".");
|
||||||
|
}
|
||||||
|
myName = sb.toString();
|
||||||
|
} else {
|
||||||
|
myName = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
@ -199,10 +200,10 @@ public class FhirValidator {
|
||||||
* @return the results of validation
|
* @return the results of validation
|
||||||
* @since 0.7
|
* @since 0.7
|
||||||
*/
|
*/
|
||||||
public ValidationResult validateWithResult(IResource theResource) {
|
public ValidationResult validateWithResult(IBaseResource theResource) {
|
||||||
Validate.notNull(theResource, "theResource must not be null");
|
Validate.notNull(theResource, "theResource must not be null");
|
||||||
|
|
||||||
ValidationContext<IResource> ctx = ValidationContext.forResource(myContext, theResource);
|
ValidationContext<IResource> ctx = ValidationContext.forResource(myContext, (IResource) theResource);
|
||||||
|
|
||||||
for (IValidator next : myValidators) {
|
for (IValidator next : myValidators) {
|
||||||
next.validateResource(ctx);
|
next.validateResource(ctx);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.hl7.fhir.instance.model.api;
|
package org.hl7.fhir.instance.model.api;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
|
@ -69,4 +68,8 @@ public interface IIdType {
|
||||||
|
|
||||||
boolean isAbsolute();
|
boolean isAbsolute();
|
||||||
|
|
||||||
|
boolean isIdPartValidLong();
|
||||||
|
|
||||||
|
Long getIdPartAsLong();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ ca.uhn.fhir.rest.client.GenericClient.cannotDetermineResourceTypeFromUri=Unable
|
||||||
ca.uhn.fhir.rest.client.RestfulClientFactory.failedToRetrieveConformance=Failed to retrieve the server's metadata statement during client initialization. URL used was: {0}
|
ca.uhn.fhir.rest.client.RestfulClientFactory.failedToRetrieveConformance=Failed to retrieve the server's metadata statement during client initialization. URL used was: {0}
|
||||||
ca.uhn.fhir.rest.client.RestfulClientFactory.wrongVersionInConformance=The server at base URL "{0}" returned a conformance statement indicating that it supports FHIR version "{1}" which corresponds to {2}, but this client is configured to use {3} (via the FhirContext).
|
ca.uhn.fhir.rest.client.RestfulClientFactory.wrongVersionInConformance=The server at base URL "{0}" returned a conformance statement indicating that it supports FHIR version "{1}" which corresponds to {2}, but this client is configured to use {3} (via the FhirContext).
|
||||||
|
|
||||||
|
ca.uhn.fhir.rest.method.BaseOutcomeReturningMethodBinding.noContentTypeInRequest=No Content-Type header was provided in the request. This is required for "{0}" operation
|
||||||
|
ca.uhn.fhir.rest.method.BaseOutcomeReturningMethodBinding.invalidContentTypeInRequest=Incorrect Content-Type header value of "{0}" was provided in the request. A FHIR Content-Type is required for "{1}" operation
|
||||||
|
|
||||||
ca.uhn.fhir.rest.method.OperationMethodBinding.methodNotSupported=HTTP Method {0} is not allowed for this operation. Allowed method(s): {1}
|
ca.uhn.fhir.rest.method.OperationMethodBinding.methodNotSupported=HTTP Method {0} is not allowed for this operation. Allowed method(s): {1}
|
||||||
ca.uhn.fhir.rest.method.OperationParamBinder.urlParamNotPrimitive=Can not invoke operation {0} using HTTP GET because parameter {1} is not a primitive datatype
|
ca.uhn.fhir.rest.method.OperationParamBinder.urlParamNotPrimitive=Can not invoke operation {0} using HTTP GET because parameter {1} is not a primitive datatype
|
||||||
ca.uhn.fhir.rest.method.IncludeParameter.invalidIncludeNameInRequest=Invalid {2} parameter value: "{0}". Valid values are: {1}
|
ca.uhn.fhir.rest.method.IncludeParameter.invalidIncludeNameInRequest=Invalid {2} parameter value: "{0}". Valid values are: {1}
|
||||||
|
|
|
@ -43,11 +43,13 @@
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
import org.hl7.fhir.instance.model.IBaseResource;
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
@ -444,12 +445,12 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IResource> getResources(final int theFromIndex, final int theToIndex) {
|
public List<IBaseResource> getResources(final int theFromIndex, final int theToIndex) {
|
||||||
final StopWatch timer = new StopWatch();
|
final StopWatch timer = new StopWatch();
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
return template.execute(new TransactionCallback<List<IResource>>() {
|
return template.execute(new TransactionCallback<List<IBaseResource>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<IResource> doInTransaction(TransactionStatus theStatus) {
|
public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
|
||||||
List<BaseHasResource> resEntities = Lists.newArrayList();
|
List<BaseHasResource> resEntities = Lists.newArrayList();
|
||||||
|
|
||||||
List<HistoryTuple> tupleSubList = tuples.subList(theFromIndex, theToIndex);
|
List<HistoryTuple> tupleSubList = tuples.subList(theFromIndex, theToIndex);
|
||||||
|
@ -471,7 +472,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
resEntities = resEntities.subList(0, limit);
|
resEntities = resEntities.subList(0, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||||
for (BaseHasResource next : resEntities) {
|
for (BaseHasResource next : resEntities) {
|
||||||
RuntimeResourceDefinition type;
|
RuntimeResourceDefinition type;
|
||||||
try {
|
try {
|
||||||
|
@ -503,7 +504,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isValidPid(IdDt theId) {
|
protected boolean isValidPid(IIdType theId) {
|
||||||
String idPart = theId.getIdPart();
|
String idPart = theId.getIdPart();
|
||||||
for (int i = 0; i < idPart.length(); i++) {
|
for (int i = 0; i < idPart.length(); i++) {
|
||||||
char nextChar = idPart.charAt(i);
|
char nextChar = idPart.charAt(i);
|
||||||
|
@ -514,9 +515,9 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<IResource> loadResourcesById(Set<IdDt> theIncludePids) {
|
protected List<IBaseResource> loadResourcesById(Set<? extends IIdType> theIncludePids) {
|
||||||
Set<Long> pids = new HashSet<Long>();
|
Set<Long> pids = new HashSet<Long>();
|
||||||
for (IdDt next : theIncludePids) {
|
for (IIdType next : theIncludePids) {
|
||||||
if (next.isIdPartValidLong()) {
|
if (next.isIdPartValidLong()) {
|
||||||
pids.add(next.getIdPartAsLong());
|
pids.add(next.getIdPartAsLong());
|
||||||
} else {
|
} else {
|
||||||
|
@ -538,7 +539,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
// }
|
// }
|
||||||
TypedQuery<ResourceTable> q = myEntityManager.createQuery(cq);
|
TypedQuery<ResourceTable> q = myEntityManager.createQuery(cq);
|
||||||
|
|
||||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||||
for (ResourceTable next : q.getResultList()) {
|
for (ResourceTable next : q.getResultList()) {
|
||||||
IResource resource = (IResource) toResource(next);
|
IResource resource = (IResource) toResource(next);
|
||||||
retVal.add(resource);
|
retVal.add(resource);
|
||||||
|
@ -956,7 +957,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
return myContext.getResourceDefinition(theResource).getName();
|
return myContext.getResourceDefinition(theResource).getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Long translateForcedIdToPid(IdDt theId) {
|
protected Long translateForcedIdToPid(IIdType theId) {
|
||||||
if (isValidPid(theId)) {
|
if (isValidPid(theId)) {
|
||||||
return theId.getIdPartAsLong();
|
return theId.getIdPartAsLong();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -56,6 +56,7 @@ import javax.persistence.criteria.Root;
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.IBaseResource;
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
@ -660,12 +661,12 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
return new HashSet<Long>(q.getResultList());
|
return new HashSet<Long>(q.getResultList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<IResource> addResourcesAsIncludesById(List<IResource> theListToPopulate, Set<IdDt> includePids, List<IResource> resources) {
|
private List<IBaseResource> addResourcesAsIncludesById(List<IBaseResource> theListToPopulate, Set<? extends IIdType> includePids, List<IBaseResource> resources) {
|
||||||
if (!includePids.isEmpty()) {
|
if (!includePids.isEmpty()) {
|
||||||
ourLog.info("Loading {} included resources", includePids.size());
|
ourLog.info("Loading {} included resources", includePids.size());
|
||||||
resources = loadResourcesById(includePids);
|
resources = loadResourcesById(includePids);
|
||||||
for (IResource next : resources) {
|
for (IBaseResource next : resources) {
|
||||||
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(next, BundleEntrySearchModeEnum.INCLUDE);
|
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put((IResource) next, BundleEntrySearchModeEnum.INCLUDE);
|
||||||
}
|
}
|
||||||
theListToPopulate.addAll(resources);
|
theListToPopulate.addAll(resources);
|
||||||
}
|
}
|
||||||
|
@ -1000,7 +1001,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IResource theResource, RuntimeResourceDefinition theResourceDef);
|
protected abstract List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef);
|
||||||
|
|
||||||
public Class<T> getResourceType() {
|
public Class<T> getResourceType() {
|
||||||
return myResourceType;
|
return myResourceType;
|
||||||
|
@ -1074,8 +1075,8 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IResource> getResources(int theFromIndex, int theToIndex) {
|
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||||
ArrayList<IResource> retVal = new ArrayList<IResource>();
|
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||||
if (theFromIndex == 0 && current != null) {
|
if (theFromIndex == 0 && current != null) {
|
||||||
retVal.add(current);
|
retVal.add(current);
|
||||||
}
|
}
|
||||||
|
@ -1128,7 +1129,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadResourcesByPid(Collection<Long> theIncludePids, List<IResource> theResourceListToPopulate, BundleEntrySearchModeEnum theBundleEntryStatus) {
|
private void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, BundleEntrySearchModeEnum theBundleEntryStatus) {
|
||||||
if (theIncludePids.isEmpty()) {
|
if (theIncludePids.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1520,15 +1521,15 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IResource> getResources(final int theFromIndex, final int theToIndex) {
|
public List<IBaseResource> getResources(final int theFromIndex, final int theToIndex) {
|
||||||
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
|
||||||
return template.execute(new TransactionCallback<List<IResource>>() {
|
return template.execute(new TransactionCallback<List<IBaseResource>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<IResource> doInTransaction(TransactionStatus theStatus) {
|
public List<IBaseResource> doInTransaction(TransactionStatus theStatus) {
|
||||||
List<Long> pidsSubList = pids.subList(theFromIndex, theToIndex);
|
List<Long> pidsSubList = pids.subList(theFromIndex, theToIndex);
|
||||||
|
|
||||||
// Execute the query and make sure we return distinct results
|
// Execute the query and make sure we return distinct results
|
||||||
List<IResource> retVal = new ArrayList<IResource>();
|
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||||
loadResourcesByPid(pidsSubList, retVal, BundleEntrySearchModeEnum.MATCH);
|
loadResourcesByPid(pidsSubList, retVal, BundleEntrySearchModeEnum.MATCH);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1537,19 +1538,19 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
* so they are loaded outside the bundle provider
|
* so they are loaded outside the bundle provider
|
||||||
*/
|
*/
|
||||||
if (theParams.getIncludes() != null && theParams.getIncludes().isEmpty() == false) {
|
if (theParams.getIncludes() != null && theParams.getIncludes().isEmpty() == false) {
|
||||||
Set<IdDt> previouslyLoadedPids = new HashSet<IdDt>();
|
Set<IIdType> previouslyLoadedPids = new HashSet<IIdType>();
|
||||||
for (IResource next : retVal) {
|
for (IBaseResource next : retVal) {
|
||||||
previouslyLoadedPids.add(next.getId().toUnqualifiedVersionless());
|
previouslyLoadedPids.add(next.getId().toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<IdDt> includePids = new HashSet<IdDt>();
|
Set<IdDt> includePids = new HashSet<IdDt>();
|
||||||
List<IResource> resources = retVal;
|
List<IBaseResource> resources = retVal;
|
||||||
do {
|
do {
|
||||||
includePids.clear();
|
includePids.clear();
|
||||||
|
|
||||||
FhirTerser t = getContext().newTerser();
|
FhirTerser t = getContext().newTerser();
|
||||||
for (Include next : theParams.getIncludes()) {
|
for (Include next : theParams.getIncludes()) {
|
||||||
for (IResource nextResource : resources) {
|
for (IBaseResource nextResource : resources) {
|
||||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource);
|
RuntimeResourceDefinition def = getContext().getResourceDefinition(nextResource);
|
||||||
List<Object> values = getIncludeValues(t, next, nextResource, def);
|
List<Object> values = getIncludeValues(t, next, nextResource, def);
|
||||||
|
|
||||||
|
@ -1875,7 +1876,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
if (Character.isDigit(theResource.getId().getIdPart().charAt(0))) {
|
if (Character.isDigit(theResource.getId().getIdPart().charAt(0))) {
|
||||||
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirResourceDao.class, "failedToCreateWithClientAssignedNumericId", theResource.getId().getIdPart()));
|
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseFhirResourceDao.class, "failedToCreateWithClientAssignedNumericId", theResource.getId().getIdPart()));
|
||||||
}
|
}
|
||||||
return doCreate(theResource, null, true);
|
return doCreate(theResource, null, thePerformIndexing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
@ -32,7 +34,7 @@ import ca.uhn.fhir.util.FhirTerser;
|
||||||
|
|
||||||
public class FhirResourceDaoDstu1<T extends IResource> extends BaseFhirResourceDao<T> {
|
public class FhirResourceDaoDstu1<T extends IResource> extends BaseFhirResourceDao<T> {
|
||||||
|
|
||||||
protected List<Object> getIncludeValues(FhirTerser t, Include next, IResource nextResource, RuntimeResourceDefinition def) {
|
protected List<Object> getIncludeValues(FhirTerser t, Include next, IBaseResource nextResource, RuntimeResourceDefinition def) {
|
||||||
List<Object> values;
|
List<Object> values;
|
||||||
if ("*".equals(next.getValue())) {
|
if ("*".equals(next.getValue())) {
|
||||||
values = new ArrayList<Object>();
|
values = new ArrayList<Object>();
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -33,7 +35,7 @@ import ca.uhn.fhir.util.FhirTerser;
|
||||||
|
|
||||||
public class FhirResourceDaoDstu2<T extends IResource> extends BaseFhirResourceDao<T> {
|
public class FhirResourceDaoDstu2<T extends IResource> extends BaseFhirResourceDao<T> {
|
||||||
|
|
||||||
protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IResource theResource, RuntimeResourceDefinition theResourceDef) {
|
protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef) {
|
||||||
List<Object> values;
|
List<Object> values;
|
||||||
if ("*".equals(theInclude.getValue())) {
|
if ("*".equals(theInclude.getValue())) {
|
||||||
values = new ArrayList<Object>();
|
values = new ArrayList<Object>();
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -241,9 +242,9 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
|
||||||
if (bundle.size() > configuredMax) {
|
if (bundle.size() > configuredMax) {
|
||||||
oo.addIssue().setSeverity(IssueSeverityEnum.WARNING).setDetails("Search nested within transaction found more than " + configuredMax + " matches, but paging is not supported in nested transactions");
|
oo.addIssue().setSeverity(IssueSeverityEnum.WARNING).setDetails("Search nested within transaction found more than " + configuredMax + " matches, but paging is not supported in nested transactions");
|
||||||
}
|
}
|
||||||
List<IResource> resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax));
|
List<IBaseResource> resourcesToAdd = bundle.getResources(0, Math.min(bundle.size(), configuredMax));
|
||||||
for (IResource next : resourcesToAdd) {
|
for (IBaseResource next : resourcesToAdd) {
|
||||||
searchBundle.addEntry().setResource(next);
|
searchBundle.addEntry().setResource((IResource) next);
|
||||||
}
|
}
|
||||||
|
|
||||||
response.addEntry().setResource(searchBundle);
|
response.addEntry().setResource(searchBundle);
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
-->
|
-->
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||||
<property name="jpaVendorAdapter">
|
<property name="jpaVendorAdapter">
|
||||||
|
@ -39,9 +39,11 @@
|
||||||
</bean>
|
</bean>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||||
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
|
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<tx:annotation-driven transaction-manager="myTxManager" />
|
<tx:annotation-driven transaction-manager="myTxManager" />
|
||||||
|
|
||||||
</beans>
|
</beans>
|
|
@ -27,6 +27,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -453,8 +454,8 @@ public class FhirResourceDaoDstu2Test {
|
||||||
|
|
||||||
IBundleProvider history = ourPatientDao.history(null);
|
IBundleProvider history = ourPatientDao.history(null);
|
||||||
assertEquals(4 + initialHistory, history.size());
|
assertEquals(4 + initialHistory, history.size());
|
||||||
List<IResource> resources = history.getResources(0, 4);
|
List<IBaseResource> resources = history.getResources(0, 4);
|
||||||
assertNotNull(resources.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.DELETED_AT));
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) resources.get(0)));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ourPatientDao.delete(id2);
|
ourPatientDao.delete(id2);
|
||||||
|
@ -534,9 +535,9 @@ public class FhirResourceDaoDstu2Test {
|
||||||
IBundleProvider history = ourPatientDao.history(id, null);
|
IBundleProvider history = ourPatientDao.history(id, null);
|
||||||
assertEquals(2, history.size());
|
assertEquals(2, history.size());
|
||||||
|
|
||||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)));
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
|
||||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)).getValue());
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)).getValue());
|
||||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(1, 1).get(0)));
|
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(1, 1).get(0)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,7 +880,7 @@ public class FhirResourceDaoDstu2Test {
|
||||||
map.setRevIncludes(Collections.singleton(Patient.INCLUDE_ORGANIZATION));
|
map.setRevIncludes(Collections.singleton(Patient.INCLUDE_ORGANIZATION));
|
||||||
IBundleProvider resultsP = ourOrganizationDao.search(map);
|
IBundleProvider resultsP = ourOrganizationDao.search(map);
|
||||||
assertEquals(2, resultsP.size());
|
assertEquals(2, resultsP.size());
|
||||||
List<IResource> results = resultsP.getResources(0, resultsP.size());
|
List<IBaseResource> results = resultsP.getResources(0, resultsP.size());
|
||||||
assertEquals(2, results.size());
|
assertEquals(2, results.size());
|
||||||
assertEquals(Organization.class, results.get(0).getClass());
|
assertEquals(Organization.class, results.get(0).getClass());
|
||||||
assertEquals(Patient.class, results.get(1).getClass());
|
assertEquals(Patient.class, results.get(1).getClass());
|
||||||
|
@ -2162,15 +2163,15 @@ public class FhirResourceDaoDstu2Test {
|
||||||
|
|
||||||
assertEquals(2, historyBundle.size());
|
assertEquals(2, historyBundle.size());
|
||||||
|
|
||||||
List<IResource> history = historyBundle.getResources(0, 2);
|
List<IBaseResource> history = historyBundle.getResources(0, 2);
|
||||||
assertEquals("1", history.get(1).getId().getVersionIdPart());
|
assertEquals("1", history.get(1).getId().getVersionIdPart());
|
||||||
assertEquals("2", history.get(0).getId().getVersionIdPart());
|
assertEquals("2", history.get(0).getId().getVersionIdPart());
|
||||||
assertEquals(published, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
assertEquals(published, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(1)));
|
||||||
assertEquals(published, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
assertEquals(published, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(1)));
|
||||||
assertEquals(updated, history.get(1).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
assertEquals(updated, ResourceMetadataKeyEnum.UPDATED.get((IResource) history.get(1)));
|
||||||
assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue());
|
assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue());
|
||||||
assertEquals(published2, history.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED));
|
assertEquals(published2, ResourceMetadataKeyEnum.PUBLISHED.get( (IResource) history.get(0)));
|
||||||
assertEquals(updated2, history.get(0).getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
|
assertEquals(updated2, ResourceMetadataKeyEnum.UPDATED.get((IResource) history.get(0)));
|
||||||
assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue());
|
assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2313,8 +2314,8 @@ public class FhirResourceDaoDstu2Test {
|
||||||
|
|
||||||
private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
|
private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
|
||||||
List<IdDt> retVal = new ArrayList<IdDt>();
|
List<IdDt> retVal = new ArrayList<IdDt>();
|
||||||
for (IResource next : theFound.getResources(0, theFound.size())) {
|
for (IBaseResource next : theFound.getResources(0, theFound.size())) {
|
||||||
retVal.add(next.getId().toUnqualifiedVersionless());
|
retVal.add((IdDt) next.getId().toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -2353,9 +2354,9 @@ public class FhirResourceDaoDstu2Test {
|
||||||
|
|
||||||
IBundleProvider value = ourDeviceDao.search(new SearchParameterMap());
|
IBundleProvider value = ourDeviceDao.search(new SearchParameterMap());
|
||||||
ourLog.info("Initial size: " + value.size());
|
ourLog.info("Initial size: " + value.size());
|
||||||
for (IResource next : value.getResources(0, value.size())) {
|
for (IBaseResource next : value.getResources(0, value.size())) {
|
||||||
ourLog.info("Deleting: {}", next.getId());
|
ourLog.info("Deleting: {}", next.getId());
|
||||||
ourDeviceDao.delete(next.getId());
|
ourDeviceDao.delete((IdDt) next.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
value = ourDeviceDao.search(new SearchParameterMap());
|
value = ourDeviceDao.search(new SearchParameterMap());
|
||||||
|
@ -2365,7 +2366,7 @@ public class FhirResourceDaoDstu2Test {
|
||||||
}
|
}
|
||||||
assertEquals(0, value.size());
|
assertEquals(0, value.size());
|
||||||
|
|
||||||
List<IResource> res = value.getResources(0, 0);
|
List<IBaseResource> res = value.getResources(0, 0);
|
||||||
assertTrue(res.isEmpty());
|
assertTrue(res.isEmpty());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -93,7 +95,7 @@ public class FhirSystemDaoDstu1Test {
|
||||||
IBundleProvider values = ourSystemDao.history(start);
|
IBundleProvider values = ourSystemDao.history(start);
|
||||||
assertEquals(4, values.size());
|
assertEquals(4, values.size());
|
||||||
|
|
||||||
List<IResource> res = values.getResources(0, 4);
|
List<IBaseResource> res = values.getResources(0, 4);
|
||||||
assertEquals(newpid3, res.get(0).getId());
|
assertEquals(newpid3, res.get(0).getId());
|
||||||
assertEquals(newpid2, res.get(1).getId());
|
assertEquals(newpid2, res.get(1).getId());
|
||||||
assertEquals(newpid, res.get(2).getId());
|
assertEquals(newpid, res.get(2).getId());
|
||||||
|
@ -146,7 +148,7 @@ public class FhirSystemDaoDstu1Test {
|
||||||
IBundleProvider patResults = ourPatientDao.search(Patient.SP_IDENTIFIER, new IdentifierDt("urn:system", "testPersistWithSimpleLinkP01"));
|
IBundleProvider patResults = ourPatientDao.search(Patient.SP_IDENTIFIER, new IdentifierDt("urn:system", "testPersistWithSimpleLinkP01"));
|
||||||
assertEquals(1, obsResults.size());
|
assertEquals(1, obsResults.size());
|
||||||
|
|
||||||
IdDt foundPatientId = patResults.getResources(0, 1).get(0).getId();
|
IIdType foundPatientId = patResults.getResources(0, 1).get(0).getId();
|
||||||
ResourceReferenceDt subject = obs.getSubject();
|
ResourceReferenceDt subject = obs.getSubject();
|
||||||
assertEquals(foundPatientId.getIdPart(), subject.getReference().getIdPart());
|
assertEquals(foundPatientId.getIdPart(), subject.getReference().getIdPart());
|
||||||
|
|
||||||
|
@ -371,7 +373,7 @@ public class FhirSystemDaoDstu1Test {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
res = new ArrayList<IResource>();
|
res = new ArrayList<IResource>();
|
||||||
List<IResource> existing = results.getResources(0, 3);
|
List<IBaseResource> existing = results.getResources(0, 3);
|
||||||
|
|
||||||
p1 = new Patient();
|
p1 = new Patient();
|
||||||
p1.setId(existing.get(0).getId());
|
p1.setId(existing.get(0).getId());
|
||||||
|
@ -391,7 +393,7 @@ public class FhirSystemDaoDstu1Test {
|
||||||
|
|
||||||
IBundleProvider results2 = ourPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testTransactionWithDelete"));
|
IBundleProvider results2 = ourPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testTransactionWithDelete"));
|
||||||
assertEquals(1, results2.size());
|
assertEquals(1, results2.size());
|
||||||
List<IResource> existing2 = results2.getResources(0, 1);
|
List<IBaseResource> existing2 = results2.getResources(0, 1);
|
||||||
assertEquals(existing2.get(0).getId(), existing.get(2).getId());
|
assertEquals(existing2.get(0).getId(), existing.get(2).getId());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.emptyString;
|
import static org.hamcrest.Matchers.emptyString;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
@ -11,9 +12,12 @@ import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.hl7.fhir.instance.model.IBaseResource;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -22,10 +26,12 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
|
import ca.uhn.fhir.jpa.provider.SystemProviderTest;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
@ -94,6 +100,30 @@ public class FhirSystemDaoDstu2Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionFromBundle() throws Exception {
|
||||||
|
|
||||||
|
InputStream bundleRes = SystemProviderTest.class.getResourceAsStream("/transaction_link_patient_eve.xml");
|
||||||
|
String bundleStr = IOUtils.toString(bundleRes);
|
||||||
|
Bundle bundle = ourFhirContext.newXmlParser().parseResource(Bundle.class, bundleStr);
|
||||||
|
|
||||||
|
Bundle resp = ourSystemDao.transaction(bundle);
|
||||||
|
|
||||||
|
ourLog.info(ourFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||||
|
|
||||||
|
OperationOutcome oo = (OperationOutcome) resp.getEntry().get(0).getResource();
|
||||||
|
assertThat(oo.getIssue().get(0).getDetailsElement().getValue(), containsString("Transaction completed"));
|
||||||
|
|
||||||
|
assertThat(resp.getEntry().get(1).getTransactionResponse().getLocation(), startsWith("Patient/a555-44-4444/_history/"));
|
||||||
|
assertThat(resp.getEntry().get(2).getTransactionResponse().getLocation(), startsWith("Patient/temp6789/_history/"));
|
||||||
|
assertThat(resp.getEntry().get(3).getTransactionResponse().getLocation(), startsWith("Organization/GHH/_history/"));
|
||||||
|
|
||||||
|
Patient p = ourPatientDao.read(new IdDt("Patient/a555-44-4444/_history/1"));
|
||||||
|
assertEquals("Patient/temp6789", p.getLink().get(0).getOther().getReference().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionReadAndSearch() {
|
public void testTransactionReadAndSearch() {
|
||||||
String methodName = "testTransactionReadAndSearch";
|
String methodName = "testTransactionReadAndSearch";
|
||||||
|
@ -262,9 +292,9 @@ public class FhirSystemDaoDstu2Test {
|
||||||
IBundleProvider history = ourPatientDao.history(id, null);
|
IBundleProvider history = ourPatientDao.history(id, null);
|
||||||
assertEquals(2, history.size());
|
assertEquals(2, history.size());
|
||||||
|
|
||||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)));
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
|
||||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(0, 0).get(0)).getValue());
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)).getValue());
|
||||||
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get(history.getResources(1, 1).get(0)));
|
assertNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(1, 1).get(0)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,9 +799,9 @@ public class FhirSystemDaoDstu2Test {
|
||||||
|
|
||||||
static void doDeleteEverything(IFhirSystemDao<Bundle> systemDao) {
|
static void doDeleteEverything(IFhirSystemDao<Bundle> systemDao) {
|
||||||
IBundleProvider all = systemDao.history(null);
|
IBundleProvider all = systemDao.history(null);
|
||||||
List<IResource> allRes = all.getResources(0, all.size());
|
List<IBaseResource> allRes = all.getResources(0, all.size());
|
||||||
for (IResource iResource : allRes) {
|
for (IBaseResource iResource : allRes) {
|
||||||
if (ResourceMetadataKeyEnum.DELETED_AT.get(iResource) == null) {
|
if (ResourceMetadataKeyEnum.DELETED_AT.get((IResource) iResource) == null) {
|
||||||
ourLog.info("Deleting: {}", iResource.getId());
|
ourLog.info("Deleting: {}", iResource.getId());
|
||||||
|
|
||||||
Bundle b = new Bundle();
|
Bundle b = new Bundle();
|
||||||
|
|
|
@ -273,6 +273,20 @@ public class ResourceProviderDstu2Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchBundleDoesntIncludeTextElement() throws Exception {
|
||||||
|
HttpGet read = new HttpGet(ourServerBase + "/Patient?_format=json");
|
||||||
|
CloseableHttpResponse response = ourHttpClient.execute(read);
|
||||||
|
try {
|
||||||
|
String text = IOUtils.toString(response.getEntity().getContent());
|
||||||
|
ourLog.info(text);
|
||||||
|
assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatusLine().getStatusCode());
|
||||||
|
assertThat(text, not(containsString("\"text\",\"type\"")));
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithInclude() throws Exception {
|
public void testSearchWithInclude() throws Exception {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package ca.uhn.fhir.jpa.provider;
|
package ca.uhn.fhir.jpa.provider;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
@ -14,15 +13,10 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
|
|
||||||
import ca.uhn.fhir.jpa.rp.dstu.ObservationResourceProvider;
|
import ca.uhn.fhir.jpa.rp.dstu.ObservationResourceProvider;
|
||||||
import ca.uhn.fhir.jpa.rp.dstu.OrganizationResourceProvider;
|
import ca.uhn.fhir.jpa.rp.dstu.OrganizationResourceProvider;
|
||||||
import ca.uhn.fhir.jpa.rp.dstu.PatientResourceProvider;
|
import ca.uhn.fhir.jpa.rp.dstu.PatientResourceProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.QuestionnaireResourceProvider;
|
|
||||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
|
||||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
|
@ -32,7 +26,7 @@ import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
|
||||||
public class SystemProviderTest {
|
public class SystemProviderTest {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderTest.class);
|
||||||
private static Server ourServer;
|
private static Server ourServer;
|
||||||
private static ClassPathXmlApplicationContext ourAppCtx;
|
private static ClassPathXmlApplicationContext ourAppCtx;
|
||||||
private static FhirContext ourCtx;
|
private static FhirContext ourCtx;
|
||||||
|
@ -41,12 +35,10 @@ public class SystemProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle() throws Exception {
|
public void testTransactionFromBundle() throws Exception {
|
||||||
|
|
||||||
InputStream bundleRes = SystemProviderTest.class.getResourceAsStream("/test-server-seed-bundle.json");
|
InputStream bundleRes = SystemProviderTest.class.getResourceAsStream("/transaction_link_patient_eve.xml");
|
||||||
Bundle bundle = FhirContext.forDstu1().newJsonParser().parseBundle(new InputStreamReader(bundleRes));
|
String bundle = IOUtils.toString(bundleRes);
|
||||||
List<IResource> res = bundle.toListOfResources();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
|
ourLog.info(response);
|
||||||
ourClient.transaction().withResources(res).execute();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,28 +51,28 @@ public class SystemProviderTest {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeClass() throws Exception {
|
public static void beforeClass() throws Exception {
|
||||||
ourAppCtx = new ClassPathXmlApplicationContext("fhir-jpabase-spring-test-config.xml", "hapi-fhir-server-resourceproviders-dstu1.xml");
|
ourAppCtx = new ClassPathXmlApplicationContext("fhir-jpabase-spring-test-config.xml", "hapi-fhir-server-resourceproviders-dstu2.xml");
|
||||||
|
|
||||||
IFhirResourceDao<Patient> patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDaoDstu1", IFhirResourceDao.class);
|
IFhirResourceDao<Patient> patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDaoDstu2", IFhirResourceDao.class);
|
||||||
PatientResourceProvider patientRp = new PatientResourceProvider();
|
PatientResourceProvider patientRp = new PatientResourceProvider();
|
||||||
patientRp.setDao(patientDao);
|
patientRp.setDao(patientDao);
|
||||||
|
|
||||||
IFhirResourceDao<Questionnaire> questionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDaoDstu1", IFhirResourceDao.class);
|
IFhirResourceDao<Questionnaire> questionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDaoDstu2", IFhirResourceDao.class);
|
||||||
QuestionnaireResourceProvider questionnaireRp = new QuestionnaireResourceProvider();
|
QuestionnaireResourceProvider questionnaireRp = new QuestionnaireResourceProvider();
|
||||||
questionnaireRp.setDao(questionnaireDao);
|
questionnaireRp.setDao(questionnaireDao);
|
||||||
|
|
||||||
IFhirResourceDao<Observation> observationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDaoDstu1", IFhirResourceDao.class);
|
IFhirResourceDao<Observation> observationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDaoDstu2", IFhirResourceDao.class);
|
||||||
ObservationResourceProvider observationRp = new ObservationResourceProvider();
|
ObservationResourceProvider observationRp = new ObservationResourceProvider();
|
||||||
observationRp.setDao(observationDao);
|
observationRp.setDao(observationDao);
|
||||||
|
|
||||||
IFhirResourceDao<Organization> organizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDaoDstu1", IFhirResourceDao.class);
|
IFhirResourceDao<Organization> organizationDao = (IFhirResourceDao<Organization>) ourAppCtx.getBean("myOrganizationDaoDstu2", IFhirResourceDao.class);
|
||||||
OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
|
OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
|
||||||
organizationRp.setDao(organizationDao);
|
organizationRp.setDao(organizationDao);
|
||||||
|
|
||||||
RestfulServer restServer = new RestfulServer();
|
RestfulServer restServer = new RestfulServer();
|
||||||
restServer.setResourceProviders(patientRp, questionnaireRp, observationRp, organizationRp);
|
restServer.setResourceProviders(patientRp, questionnaireRp, observationRp, organizationRp);
|
||||||
|
|
||||||
JpaSystemProviderDstu1 systemProv = ourAppCtx.getBean(JpaSystemProviderDstu1.class, "mySystemProviderDstu1");
|
JpaSystemProviderDstu2 systemProv = ourAppCtx.getBean(JpaSystemProviderDstu2.class, "mySystemProviderDstu2");
|
||||||
restServer.setPlainProviders(systemProv);
|
restServer.setPlainProviders(systemProv);
|
||||||
|
|
||||||
int myPort = RandomServerPortProvider.findFreePort();
|
int myPort = RandomServerPortProvider.findFreePort();
|
||||||
|
@ -95,10 +87,12 @@ public class SystemProviderTest {
|
||||||
servletHolder.setServlet(restServer);
|
servletHolder.setServlet(restServer);
|
||||||
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
proxyHandler.addServlet(servletHolder, "/fhir/context/*");
|
||||||
|
|
||||||
|
ourCtx = FhirContext.forDstu2();
|
||||||
|
restServer.setFhirContext(ourCtx);
|
||||||
|
|
||||||
ourServer.setHandler(proxyHandler);
|
ourServer.setHandler(proxyHandler);
|
||||||
ourServer.start();
|
ourServer.start();
|
||||||
|
|
||||||
ourCtx = restServer.getFhirContext();
|
|
||||||
|
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(600 * 1000);
|
ourCtx.getRestfulClientFactory().setSocketTimeout(600 * 1000);
|
||||||
ourClient = ourCtx.newRestfulGenericClient(serverBase);
|
ourClient = ourCtx.newRestfulGenericClient(serverBase);
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
-->
|
-->
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||||
<property name="jpaVendorAdapter">
|
<property name="jpaVendorAdapter">
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||||
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
|
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||||
</bean>
|
</bean>
|
||||||
<tx:annotation-driven transaction-manager="myTxManager" />
|
<tx:annotation-driven transaction-manager="myTxManager" />
|
||||||
|
|
||||||
|
|
|
@ -1,690 +0,0 @@
|
||||||
|
|
||||||
{
|
|
||||||
"resourceType":"Bundle",
|
|
||||||
"entry":[
|
|
||||||
{
|
|
||||||
"deleted":null,
|
|
||||||
"title":"Patient http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-1.0/Patient/5556918",
|
|
||||||
"id":"Patient/5556918",
|
|
||||||
"link":[
|
|
||||||
{
|
|
||||||
"rel":"self",
|
|
||||||
"href":"Patient/5556918"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"published":"2014-05-29T10:49:32-04:00",
|
|
||||||
"content":{
|
|
||||||
"resourceType":"Patient",
|
|
||||||
"id":"http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-1.0/Patient/5556918",
|
|
||||||
"text":{
|
|
||||||
"status":"generated",
|
|
||||||
"div":"<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> Donald null <b>DUCK </b></div><table class=\"hapiPropertyTable\"><tbody><tr><td>Identifier</td><td>7000135</td></tr><tr><td>Address</td><td><span>10 Duxon Street </span><br/><span>VICTORIA </span><span>BC </span><span>Can </span></td></tr><tr><td>Date of birth</td><td><span>01 June 1980</span></td></tr></tbody></table></div>"
|
|
||||||
},
|
|
||||||
"identifier":[
|
|
||||||
{
|
|
||||||
"use":"official",
|
|
||||||
"label":"University Health Network MRN 7000135",
|
|
||||||
"system":"urn:oid:2.16.840.1.113883.3.239.18.148",
|
|
||||||
"value":"7000135",
|
|
||||||
"assigner":{
|
|
||||||
"resource":"Organization/1.3.6.1.4.1.12201"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name":[
|
|
||||||
{
|
|
||||||
"family":[
|
|
||||||
"Duck"
|
|
||||||
],
|
|
||||||
"given":[
|
|
||||||
"Donald"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"telecom":[
|
|
||||||
{
|
|
||||||
"system":"phone",
|
|
||||||
"use":"home"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"system":"phone",
|
|
||||||
"use":"work"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"system":"phone",
|
|
||||||
"use":"mobile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"system":"email",
|
|
||||||
"use":"home"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"gender":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"http://hl7.org/fhir/v3/AdministrativeGender",
|
|
||||||
"code":"M"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"birthDate":"1980-06-01T00:00:00",
|
|
||||||
"address":[
|
|
||||||
{
|
|
||||||
"use":"home",
|
|
||||||
"line":[
|
|
||||||
"10 Duxon Street"
|
|
||||||
],
|
|
||||||
"city":"VICTORIA",
|
|
||||||
"state":"BC",
|
|
||||||
"zip":"V8N 1Y4",
|
|
||||||
"country":"Can"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"managingOrganization":{
|
|
||||||
"resource":"Organization/1.3.6.1.4.1.12201"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"deleted":null,
|
|
||||||
"title":"DiagnosticReport http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-1.0/DiagnosticReport/5978827",
|
|
||||||
"id":"DiagnosticReport/5978827",
|
|
||||||
"link":[
|
|
||||||
{
|
|
||||||
"rel":"self",
|
|
||||||
"href":"DiagnosticReport/5978827"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"published":"2014-05-29T10:49:33-04:00",
|
|
||||||
"content":{
|
|
||||||
"resourceType":"DiagnosticReport",
|
|
||||||
"id":"http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-1.0/DiagnosticReport/5978827",
|
|
||||||
"text":{
|
|
||||||
"status":"generated",
|
|
||||||
"div":"<div xmlns=\"http://www.w3.org/1999/xhtml\"><div class=\"hapiHeaderText\"> C&S </div><table class=\"hapiPropertyTable\"><tbody><tr><td>Status</td><td>partial</td></tr><tr><td>Issued</td><td> 29 April 2014 17:21:56 </td></tr></tbody></table><table class=\"hapiTableOfValues\"><thead><tr><td>Name</td><td>Value</td><td>Interpretation</td><td>Reference Range</td><td>Status</td></tr></thead><tbody><tr class=\"hapiTableOfValuesRowEven\"><td> Collection Info </td><td> Spec #102758: 26 Sep 08 1117</td><td/><td/><td>preliminary</td></tr><tr class=\"hapiTableOfValuesRowOdd\"><td> Direct Stain </td><td> pus cells</td><td/><td/><td>preliminary</td></tr><tr class=\"hapiTableOfValuesRowEven\"><td> Header </td><td> To view Culture & Sensitivity Results, select</td><td/><td/><td/></tr><tr class=\"hapiTableOfValuesRowOdd\"><td> Header </td><td> (Y) Report Query. Do NOT select number beside</td><td/><td/><td/></tr><tr class=\"hapiTableOfValuesRowEven\"><td> Header </td><td> Prelim or Final Result field, as there is</td><td/><td/><td/></tr><tr class=\"hapiTableOfValuesRowOdd\"><td> Header </td><td> potential for viewing an incomplete report.</td><td/><td/><td/></tr><tr class=\"hapiTableOfValuesRowEven\"><td> Organism </td><td> Haemophilus influenzae</td><td/><td/><td>final</td></tr><tr class=\"hapiTableOfValuesRowOdd\"><td> Qualifier </td><td> =>10 x E6 cfu/L SIGNIFICANT RESULT. Organisms cultured in quantities =>10 x E6 cfu/L are consistent with pneumonia. beta-lactamase positive result suggests resistance to ampicillin but generally susceptible to amoxicillin- clavulanic and cefuroxime.</td><td/><td/><td>final</td></tr><tr class=\"hapiTableOfValuesRowEven\"><td> Sensitivities </td><td> _Beta-lactamase Pos: </td><td/><td/><td>final</td></tr><tr class=\"hapiTableOfValuesRowOdd\"><td> Test Comment </td><td> =>10 x E6 cfu/L Commensal flora</td><td/><td/><td>final</td></tr></tbody></table></div>"
|
|
||||||
},
|
|
||||||
"contained":[
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"f816a276-cfad-4eca-a9fa-f1dff844a196",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"146151.1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Collection Info"
|
|
||||||
},
|
|
||||||
"valueString":"Spec #102758: 26 Sep 08 1117",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"N"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"preliminary"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"23b55496-1c2a-4d5f-9c24-8ca5042f4027",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"GM.2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Direct Stain"
|
|
||||||
},
|
|
||||||
"valueString":"pus cells",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"N"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"preliminary"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"74e6791a-d810-4545-8410-e9eca41e81d6",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H1.3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"To view Culture & Sensitivity Results, select",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"cd8c6a6c-7ef5-446f-b07b-47a21bfe28ee",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H2.4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"(Y) Report Query. Do NOT select number beside",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"4a3d453d-3a18-432f-8f1f-d7657c50dcd4",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H3.5"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"Prelim or Final Result field, as there is",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"0dd6cff6-f9db-42cc-89c9-2cd6ba6fe5af",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H4.6"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"potential for viewing an incomplete report.",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"6d6b0117-220f-4b9a-abf3-5faf772cfa61",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"F/O.4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Organism"
|
|
||||||
},
|
|
||||||
"valueString":"Haemophilus influenzae",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"64068acf-57f4-42c8-b0e6-416247067b16",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"F/31266.5"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Qualifier"
|
|
||||||
},
|
|
||||||
"valueString":"=>10 x E6 cfu/L SIGNIFICANT RESULT. Organisms cultured in quantities =>10 x E6 cfu/L are consistent with pneumonia. beta-lactamase positive result suggests resistance to ampicillin but generally susceptible to amoxicillin- clavulanic and cefuroxime.",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"0f9d254f-3ad1-404b-9be9-20258b3c242f",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"F/31415.6"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Sensitivities"
|
|
||||||
},
|
|
||||||
"valueString":"_Beta-lactamase Pos: ",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"349bb02b-fbbe-4ce0-b190-3f545240dcc0",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"Q.3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Test Comment"
|
|
||||||
},
|
|
||||||
"valueString":"=>10 x E6 cfu/L Commensal flora",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"N"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"f816a276-cfad-4eca-a9fa-f1dff844a196",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"146151.1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Collection Info"
|
|
||||||
},
|
|
||||||
"valueString":"Spec #102758: 26 Sep 08 1117",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"N"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"preliminary"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"23b55496-1c2a-4d5f-9c24-8ca5042f4027",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"GM.2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Direct Stain"
|
|
||||||
},
|
|
||||||
"valueString":"pus cells",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"N"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"preliminary"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"74e6791a-d810-4545-8410-e9eca41e81d6",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H1.3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"To view Culture & Sensitivity Results, select",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"cd8c6a6c-7ef5-446f-b07b-47a21bfe28ee",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H2.4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"(Y) Report Query. Do NOT select number beside",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"4a3d453d-3a18-432f-8f1f-d7657c50dcd4",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H3.5"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"Prelim or Final Result field, as there is",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"0dd6cff6-f9db-42cc-89c9-2cd6ba6fe5af",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"1H4.6"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Header"
|
|
||||||
},
|
|
||||||
"valueString":"potential for viewing an incomplete report.",
|
|
||||||
"issued":"2014-04-29T17:21:56"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"6d6b0117-220f-4b9a-abf3-5faf772cfa61",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"F/O.4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Organism"
|
|
||||||
},
|
|
||||||
"valueString":"Haemophilus influenzae",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"64068acf-57f4-42c8-b0e6-416247067b16",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"F/31266.5"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Qualifier"
|
|
||||||
},
|
|
||||||
"valueString":"=>10 x E6 cfu/L SIGNIFICANT RESULT. Organisms cultured in quantities =>10 x E6 cfu/L are consistent with pneumonia. beta-lactamase positive result suggests resistance to ampicillin but generally susceptible to amoxicillin- clavulanic and cefuroxime.",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"0f9d254f-3ad1-404b-9be9-20258b3c242f",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"F/31415.6"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Sensitivities"
|
|
||||||
},
|
|
||||||
"valueString":"_Beta-lactamase Pos: ",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"A"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Observation",
|
|
||||||
"id":"349bb02b-fbbe-4ce0-b190-3f545240dcc0",
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.6",
|
|
||||||
"code":"Q.3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"Test Comment"
|
|
||||||
},
|
|
||||||
"valueString":"=>10 x E6 cfu/L Commensal flora",
|
|
||||||
"interpretation":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"N"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"status":"final"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"system":"urn:oid:1.3.6.1.4.1.12201.102.5",
|
|
||||||
"code":"4140"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":"C&S"
|
|
||||||
},
|
|
||||||
"status":"partial",
|
|
||||||
"issued":"2014-04-29T17:21:56",
|
|
||||||
"subject":{
|
|
||||||
"resource":"Patient/5556918"
|
|
||||||
},
|
|
||||||
"identifier":{
|
|
||||||
"value":"2363922"
|
|
||||||
},
|
|
||||||
"diagnosticDateTime":"2014-04-14T00:00:00-04:00",
|
|
||||||
"result":[
|
|
||||||
{
|
|
||||||
"resource":"#f816a276-cfad-4eca-a9fa-f1dff844a196"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#23b55496-1c2a-4d5f-9c24-8ca5042f4027"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#74e6791a-d810-4545-8410-e9eca41e81d6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#cd8c6a6c-7ef5-446f-b07b-47a21bfe28ee"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#4a3d453d-3a18-432f-8f1f-d7657c50dcd4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#0dd6cff6-f9db-42cc-89c9-2cd6ba6fe5af"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#6d6b0117-220f-4b9a-abf3-5faf772cfa61"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#64068acf-57f4-42c8-b0e6-416247067b16"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#0f9d254f-3ad1-404b-9be9-20258b3c242f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#349bb02b-fbbe-4ce0-b190-3f545240dcc0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"deleted":null,
|
|
||||||
"title":"Organization http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-1.0/Organization/1.3.6.1.4.1.12201",
|
|
||||||
"id":"Organization/1.3.6.1.4.1.12201",
|
|
||||||
"link":[
|
|
||||||
{
|
|
||||||
"rel":"self",
|
|
||||||
"href":"Organization/1.3.6.1.4.1.12201"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"published":"2014-05-29T10:49:32-04:00",
|
|
||||||
"content":{
|
|
||||||
"resourceType":"Organization",
|
|
||||||
"id":"http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-1.0/Organization/1.3.6.1.4.1.12201",
|
|
||||||
"extension":[
|
|
||||||
{
|
|
||||||
"url":"http://fhir.connectinggta.ca/Profile/organization#providerIdPool",
|
|
||||||
"valueUri":"1.3.6.1.4.1.12201.1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"text":{
|
|
||||||
"status":"empty",
|
|
||||||
"div":"<div xmlns=\"http://www.w3.org/1999/xhtml\">No narrative template available for resource profile: http://fhir.connectinggta.ca/Profile/organization</div>"
|
|
||||||
},
|
|
||||||
"contained":[
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.1",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.1"
|
|
||||||
},
|
|
||||||
"name":"Toronto General Hospital"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.2",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.2"
|
|
||||||
},
|
|
||||||
"name":"Toronto Western Hospital"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.3",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.3"
|
|
||||||
},
|
|
||||||
"name":"Princess Margaret Hospital"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.4",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.4"
|
|
||||||
},
|
|
||||||
"name":"Toronto Rehab Institute"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.1",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.1"
|
|
||||||
},
|
|
||||||
"name":"Toronto General Hospital"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.2",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.2"
|
|
||||||
},
|
|
||||||
"name":"Toronto Western Hospital"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.3",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.3"
|
|
||||||
},
|
|
||||||
"name":"Princess Margaret Hospital"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceType":"Location",
|
|
||||||
"id":"1.3.6.1.4.1.12201.100.4",
|
|
||||||
"identifier":{
|
|
||||||
"system":"urn:cgta:facility_ids",
|
|
||||||
"value":"1.3.6.1.4.1.12201.100.4"
|
|
||||||
},
|
|
||||||
"name":"Toronto Rehab Institute"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name":"University Health Network",
|
|
||||||
"type":{
|
|
||||||
"coding":[
|
|
||||||
{
|
|
||||||
"code":"HOSPITAL"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"address":[
|
|
||||||
{
|
|
||||||
"line":[
|
|
||||||
"R. Fraser Elliott Building, 1st Floor",
|
|
||||||
"190 Elizabeth St."
|
|
||||||
],
|
|
||||||
"city":"Toronto",
|
|
||||||
"state":"ON",
|
|
||||||
"zip":"M5G 2C4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"location":[
|
|
||||||
{
|
|
||||||
"resource":"#1.3.6.1.4.1.12201.100.1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#1.3.6.1.4.1.12201.100.2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#1.3.6.1.4.1.12201.100.3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resource":"#1.3.6.1.4.1.12201.100.4"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
<Bundle xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="a130877d-a636-4993-97e6-0eeb7734e5"/>
|
||||||
|
<type value="transaction"/>
|
||||||
|
<entry>
|
||||||
|
<resource>
|
||||||
|
<Patient>
|
||||||
|
<!-- PID|||555-44-4444||EVERYWOMAN^EVE^E^^^^L|JONES|19620320|F|||153 FERNWOOD DR.^
|
||||||
|
^STATESVILLE^OH^35292||(206)3345232|(206)752-121||||AC555444444||67-A4335^OH^20030520 -->
|
||||||
|
<id value="a555-44-4444"/>
|
||||||
|
<extension url="http://ihe.net/ITI-78/Profile/pdqm#mothersMaidenName">
|
||||||
|
<valueHumanName>
|
||||||
|
<family value="Jones"/>
|
||||||
|
</valueHumanName>
|
||||||
|
</extension>
|
||||||
|
<identifier>
|
||||||
|
<use value="official"/>
|
||||||
|
<system value="http://ghh.org/patient"/>
|
||||||
|
<value value="555-44-4444"/>
|
||||||
|
</identifier>
|
||||||
|
<identifier>
|
||||||
|
<use value="official"/>
|
||||||
|
<system value="http://www.ohio.gov/dmv/driverslicence"/>
|
||||||
|
<value value="67-A4335"/>
|
||||||
|
<period>
|
||||||
|
<end value="2003-05-20"/>
|
||||||
|
</period>
|
||||||
|
</identifier>
|
||||||
|
<name>
|
||||||
|
<use value="official"/>
|
||||||
|
<family value="Everywoman"/>
|
||||||
|
<given value="Eve E."/>
|
||||||
|
</name>
|
||||||
|
<telecom>
|
||||||
|
<system value="phone"/>
|
||||||
|
<value value="(206)3345232"/>
|
||||||
|
<use value="home"/>
|
||||||
|
</telecom>
|
||||||
|
<telecom>
|
||||||
|
<system value="phone"/>
|
||||||
|
<value value="(206)752-121"/>
|
||||||
|
<use value="work"/>
|
||||||
|
</telecom>
|
||||||
|
<gender value="female"/>
|
||||||
|
<birthDate value="1962-03-20"/>
|
||||||
|
<address>
|
||||||
|
<line value="153 Fernwood Dr."/>
|
||||||
|
<city value="Statesville"/>
|
||||||
|
<state value="OH"/>
|
||||||
|
<postalCode value="35292"/>
|
||||||
|
</address>
|
||||||
|
<managingOrganization>
|
||||||
|
<reference value="Organization/GHH"/>
|
||||||
|
<display value="Good Health Hospital"/>
|
||||||
|
</managingOrganization>
|
||||||
|
<link>
|
||||||
|
<other>
|
||||||
|
<reference value="Patient/temp6789"/>
|
||||||
|
</other>
|
||||||
|
<type value="seealso"/>
|
||||||
|
</link>
|
||||||
|
<active value="true"/>
|
||||||
|
</Patient>
|
||||||
|
</resource>
|
||||||
|
<transaction>
|
||||||
|
<method value="PUT"/>
|
||||||
|
<url value="Patient/a555-44-4444"/>
|
||||||
|
</transaction>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<resource>
|
||||||
|
<Patient>
|
||||||
|
<!-- Jane Doe registered in the emergency department -->
|
||||||
|
<id value="temp6789"/>
|
||||||
|
<identifier>
|
||||||
|
<use value="temp"/>
|
||||||
|
<system value="http://ghh.org/patient"/>
|
||||||
|
<value value="temp6789"/>
|
||||||
|
</identifier>
|
||||||
|
<name>
|
||||||
|
<use value="temp"/>
|
||||||
|
<family value="Doe 6789"/>
|
||||||
|
<given value="Jane"/>
|
||||||
|
</name>
|
||||||
|
<gender value="female"/>
|
||||||
|
<managingOrganization>
|
||||||
|
<reference value="Organization/GHH"/>
|
||||||
|
<display value="Good Health Hospital"/>
|
||||||
|
</managingOrganization>
|
||||||
|
<link>
|
||||||
|
<other>
|
||||||
|
<reference value="Patient/a555-44-4444"/>
|
||||||
|
</other>
|
||||||
|
<type value="replace"/>
|
||||||
|
</link>
|
||||||
|
<active value="true"/>
|
||||||
|
</Patient>
|
||||||
|
</resource>
|
||||||
|
<transaction>
|
||||||
|
<method value="PUT"/>
|
||||||
|
<url value="Patient/temp6789"/>
|
||||||
|
</transaction>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
<resource>
|
||||||
|
<Organization>
|
||||||
|
<id value="GHH"/>
|
||||||
|
</Organization>
|
||||||
|
</resource>
|
||||||
|
<transaction>
|
||||||
|
<method value="PUT"/>
|
||||||
|
<url value="Organization/GHH"/>
|
||||||
|
</transaction>
|
||||||
|
</entry>
|
||||||
|
</Bundle>
|
|
@ -2,22 +2,25 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Note: HAPI projects use the Sonatype OSS parent project to
|
Note: HAPI projects use the "hapi-fhir" POM as their base to provide
|
||||||
facilitate deployment to the global Maven repos.
|
easy management.
|
||||||
|
|
||||||
You do not need to use this in your own projects, so the
|
You do not need to use this in your own projects, so the
|
||||||
"parent" tag and it's contents below may be removed if you
|
"parent" tag and it's contents below may be removed if you
|
||||||
are using this file as a basis for your own project.
|
are using this file as a basis for your own project.
|
||||||
-->
|
-->
|
||||||
|
<!--
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.sonatype.oss</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>oss-parent</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
-->
|
||||||
|
|
||||||
<groupId>ca.uhn.hapi.example</groupId>
|
<groupId>ca.uhn.hapi.example</groupId>
|
||||||
<artifactId>hapi-fhir-jpaserver-example</artifactId>
|
<artifactId>hapi-fhir-jpaserver-example</artifactId>
|
||||||
<version>0.9-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<name>HAPI FHIR JPA Server - Example</name>
|
<name>HAPI FHIR JPA Server - Example</name>
|
||||||
|
@ -228,7 +231,7 @@
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-deploy-plugin</artifactId>
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<skip>false</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,11 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
|
||||||
|
|
||||||
import org.springframework.web.context.ContextLoaderListener;
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
||||||
|
@ -23,7 +22,7 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
|
||||||
public class JpaServerDemo extends RestfulServer {
|
public class JpaServerDemo extends RestfulServer {
|
||||||
|
|
||||||
|
@ -123,12 +122,12 @@ public class JpaServerDemo extends RestfulServer {
|
||||||
setPagingProvider(new FifoMemoryPagingProvider(10));
|
setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do some fancy logging to create a nice access log that has details about each incoming request.
|
* Load interceptors for the server from Spring (these are defined in hapi-fhir-server-config.xml
|
||||||
*/
|
*/
|
||||||
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
|
||||||
loggingInterceptor.setLoggerName("fhir.access");
|
for (IServerInterceptor interceptor : interceptorBeans) {
|
||||||
loggingInterceptor.setMessageFormat("Path[${servletPath}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
|
this.registerInterceptor(interceptor);
|
||||||
this.registerInterceptor(loggingInterceptor);
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,22 @@
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||||
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
|
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||||
</bean>
|
</bean>
|
||||||
<tx:annotation-driven transaction-manager="myTxManager" />
|
<tx:annotation-driven transaction-manager="myTxManager" />
|
||||||
|
|
||||||
|
<util:list id="myServerInterceptors">
|
||||||
|
<ref bean="myLoggingInterceptor"/>
|
||||||
|
</util:list>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Do some fancy logging to create a nice access log that has details
|
||||||
|
about each incoming request.
|
||||||
|
-->
|
||||||
|
<bean id="myLoggingInterceptor" class="ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor">
|
||||||
|
<property name="loggerName" value="fhirtest.access"/>
|
||||||
|
<property name="messageFormat"
|
||||||
|
value="Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
|
@ -32,7 +32,7 @@
|
||||||
database (e.g. Postgres). Consult the Hibernate documentation to see a list of
|
database (e.g. Postgres). Consult the Hibernate documentation to see a list of
|
||||||
available dialects.
|
available dialects.
|
||||||
-->
|
-->
|
||||||
<bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||||
<property name="persistenceXmlLocation" value="classpath:META-INF/fhirtest_persistence.xml" />
|
<property name="persistenceXmlLocation" value="classpath:META-INF/fhirtest_persistence.xml" />
|
||||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||||
|
|
|
@ -7,17 +7,16 @@ import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.web.context.ContextLoaderListener;
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu1;
|
||||||
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
|
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
|
||||||
|
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
|
@ -25,7 +24,7 @@ import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||||
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
|
||||||
public class TestRestfulServer extends RestfulServer {
|
public class TestRestfulServer extends RestfulServer {
|
||||||
|
|
||||||
|
@ -164,13 +163,12 @@ public class TestRestfulServer extends RestfulServer {
|
||||||
setPagingProvider(new FifoMemoryPagingProvider(10));
|
setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do some fancy logging to create a nice access log that has details
|
* Load interceptors for the server from Spring (these are defined in hapi-fhir-server-config.xml
|
||||||
* about each incoming request.
|
|
||||||
*/
|
*/
|
||||||
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
List<IServerInterceptor> interceptorBeans = myAppCtx.getBean("myServerInterceptors", List.class);
|
||||||
loggingInterceptor.setLoggerName("fhirtest.access");
|
for (IServerInterceptor interceptor : interceptorBeans) {
|
||||||
loggingInterceptor.setMessageFormat("Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
|
this.registerInterceptor(interceptor);
|
||||||
this.registerInterceptor(loggingInterceptor);
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,22 @@
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||||
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
|
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||||
</bean>
|
</bean>
|
||||||
<tx:annotation-driven transaction-manager="myTxManager" />
|
<tx:annotation-driven transaction-manager="myTxManager" />
|
||||||
|
|
||||||
|
<util:list id="myServerInterceptors">
|
||||||
|
<ref bean="myLoggingInterceptor"/>
|
||||||
|
</util:list>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Do some fancy logging to create a nice access log that has details
|
||||||
|
about each incoming request.
|
||||||
|
-->
|
||||||
|
<bean id="myLoggingInterceptor" class="ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor">
|
||||||
|
<property name="loggerName" value="fhirtest.access"/>
|
||||||
|
<property name="messageFormat"
|
||||||
|
value="Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
|
@ -56,7 +56,7 @@
|
||||||
</bean>
|
</bean>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<bean depends-on="dbServer" id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
<bean depends-on="dbServer" id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||||
<property name="persistenceXmlLocation" value="classpath:META-INF/fhirtest_persistence.xml" />
|
<property name="persistenceXmlLocation" value="classpath:META-INF/fhirtest_persistence.xml" />
|
||||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
<bean class="ca.uhn.fhir.to.TesterConfig">
|
<bean class="ca.uhn.fhir.to.TesterConfig">
|
||||||
<property name="servers">
|
<property name="servers">
|
||||||
<list>
|
<list>
|
||||||
<value>home , DSTU1 , UHN/HAPI Server (DSTU1 FHIR) , http://fhirtest.uhn.ca/baseDstu1</value>
|
|
||||||
<value>home_dev , DSTU2 , UHN/HAPI Server (DSTU2 FHIR) , http://fhirtest.uhn.ca/baseDstu2</value>
|
<value>home_dev , DSTU2 , UHN/HAPI Server (DSTU2 FHIR) , http://fhirtest.uhn.ca/baseDstu2</value>
|
||||||
<value>hi , DSTU1 , Health Intersections (DSTU1 FHIR) , http://fhir.healthintersections.com.au/open</value>
|
<value>home , DSTU1 , UHN/HAPI Server (DSTU1 FHIR) , http://fhirtest.uhn.ca/baseDstu1</value>
|
||||||
<value>hidev , DSTU2 , Health Intersections (DSTU2 FHIR) , http://fhir-dev.healthintersections.com.au/open</value>
|
<value>hidev , DSTU2 , Health Intersections (DSTU2 FHIR) , http://fhir-dev.healthintersections.com.au/open</value>
|
||||||
<value>furore , DSTU1 , Spark - Furore , http://spark.furore.com/fhir</value>
|
<value>hi , DSTU1 , Health Intersections (DSTU1 FHIR) , http://fhir.healthintersections.com.au/open</value>
|
||||||
|
<value>furored2 , DSTU2 , Spark - Furore (DSTU2 FHIR) , http://spark-dstu2.furore.com/fhir</value>
|
||||||
|
<value>furore , DSTU1 , Spark - Furore (DSTU1 FHIR) , http://spark.furore.com/fhir</value>
|
||||||
<value>blaze , DSTU1 , Blaze (Orion Health) , https://fhir.orionhealth.com/blaze/fhir</value>
|
<value>blaze , DSTU1 , Blaze (Orion Health) , https://fhir.orionhealth.com/blaze/fhir</value>
|
||||||
<value>oridashi , DSTU1 , Oridashi , http://demo.oridashi.com.au:8190</value>
|
<value>oridashi , DSTU1 , Oridashi , http://demo.oridashi.com.au:8190</value>
|
||||||
<!-- <value>fhirbase , DSTU1 , FHIRPlace (Health Samurai) , http://try-fhirplace.hospital-systems.com/ </value> -->
|
<!-- <value>fhirbase , DSTU1 , FHIRPlace (Health Samurai) , http://try-fhirplace.hospital-systems.com/ </value> -->
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class UhnFhirTestApp {
|
||||||
client.create(p1);
|
client.create(p1);
|
||||||
|
|
||||||
List<IResource> resources = ctx.newJsonParser().parseBundle(IOUtils.toString(UhnFhirTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources();
|
List<IResource> resources = ctx.newJsonParser().parseBundle(IOUtils.toString(UhnFhirTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources();
|
||||||
client.transaction(resources);
|
client.transaction().withResources(resources).execute();
|
||||||
|
|
||||||
// for (int i = 0; i < 1000; i++) {
|
// for (int i = 0; i < 1000; i++) {
|
||||||
//
|
//
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<!-- <property name="url" value="jdbc:derby:directory:myUnitTestDB;create=true" /> -->
|
<!-- <property name="url" value="jdbc:derby:directory:myUnitTestDB;create=true" /> -->
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||||
<property name="persistenceXmlLocation" value="classpath:fhir_jpatest_persistence.xml" />
|
<property name="persistenceXmlLocation" value="classpath:fhir_jpatest_persistence.xml" />
|
||||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
<bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||||
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
|
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||||
</bean>
|
</bean>
|
||||||
<tx:annotation-driven transaction-manager="myTxManager" />
|
<tx:annotation-driven transaction-manager="myTxManager" />
|
||||||
|
|
||||||
|
|
|
@ -601,6 +601,7 @@ public class JsonParserTest {
|
||||||
public void testEncodeBundleCategory() {
|
public void testEncodeBundleCategory() {
|
||||||
|
|
||||||
Bundle b = new Bundle();
|
Bundle b = new Bundle();
|
||||||
|
|
||||||
BundleEntry e = b.addEntry();
|
BundleEntry e = b.addEntry();
|
||||||
e.setResource(new Patient());
|
e.setResource(new Patient());
|
||||||
b.addCategory("scheme", "term", "label");
|
b.addCategory("scheme", "term", "label");
|
||||||
|
@ -609,6 +610,7 @@ public class JsonParserTest {
|
||||||
ourLog.info(val);
|
ourLog.info(val);
|
||||||
|
|
||||||
assertThat(val, StringContains.containsString("\"category\":[{\"term\":\"term\",\"label\":\"label\",\"scheme\":\"scheme\"}]"));
|
assertThat(val, StringContains.containsString("\"category\":[{\"term\":\"term\",\"label\":\"label\",\"scheme\":\"scheme\"}]"));
|
||||||
|
assertThat(val, not(containsString("text")));
|
||||||
|
|
||||||
b = new FhirContext().newJsonParser().parseBundle(val);
|
b = new FhirContext().newJsonParser().parseBundle(val);
|
||||||
assertEquals(1, b.getEntries().size());
|
assertEquals(1, b.getEntries().size());
|
||||||
|
@ -620,6 +622,7 @@ public class JsonParserTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeBundleEntryCategory() {
|
public void testEncodeBundleEntryCategory() {
|
||||||
|
|
||||||
|
@ -1219,7 +1222,6 @@ public class JsonParserTest {
|
||||||
Bundle b = new Bundle();
|
Bundle b = new Bundle();
|
||||||
|
|
||||||
InstantDt pub = InstantDt.withCurrentTime();
|
InstantDt pub = InstantDt.withCurrentTime();
|
||||||
b.setPublished(pub);
|
|
||||||
Thread.sleep(2);
|
Thread.sleep(2);
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
@ -1245,7 +1247,6 @@ public class JsonParserTest {
|
||||||
ourLog.info(bundleString);
|
ourLog.info(bundleString);
|
||||||
|
|
||||||
List<String> strings = new ArrayList<String>();
|
List<String> strings = new ArrayList<String>();
|
||||||
strings.addAll(Arrays.asList("\"published\":\"" + pub.getValueAsString() + "\""));
|
|
||||||
strings.addAll(Arrays.asList("\"id\":\"1\""));
|
strings.addAll(Arrays.asList("\"id\":\"1\""));
|
||||||
strings.addAll(Arrays.asList("this is the summary"));
|
strings.addAll(Arrays.asList("this is the summary"));
|
||||||
strings.addAll(Arrays.asList("\"id\":\"2\"", "\"rel\":\"alternate\"", "\"href\":\"http://foo/bar\""));
|
strings.addAll(Arrays.asList("\"id\":\"2\"", "\"rel\":\"alternate\"", "\"href\":\"http://foo/bar\""));
|
||||||
|
|
|
@ -314,7 +314,6 @@ public class XmlParserTest {
|
||||||
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
|
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
|
||||||
|
|
||||||
InstantDt pub = InstantDt.withCurrentTime();
|
InstantDt pub = InstantDt.withCurrentTime();
|
||||||
b.setPublished(pub);
|
|
||||||
Thread.sleep(2);
|
Thread.sleep(2);
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
@ -340,7 +339,6 @@ public class XmlParserTest {
|
||||||
ourLog.info(bundleString);
|
ourLog.info(bundleString);
|
||||||
|
|
||||||
List<String> strings = new ArrayList<String>();
|
List<String> strings = new ArrayList<String>();
|
||||||
strings.addAll(Arrays.asList("<published>", pub.getValueAsString(), "</published>"));
|
|
||||||
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
|
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
|
||||||
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
|
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
|
||||||
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
|
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
|
||||||
|
@ -380,7 +378,6 @@ public class XmlParserTest {
|
||||||
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
|
b.getCategories().addTag("http://hl7.org/fhir/tag", "http://hl7.org/fhir/tag/message", "Message");
|
||||||
|
|
||||||
InstantDt pub = InstantDt.withCurrentTime();
|
InstantDt pub = InstantDt.withCurrentTime();
|
||||||
b.setPublished(pub);
|
|
||||||
Thread.sleep(2);
|
Thread.sleep(2);
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
@ -406,7 +403,6 @@ public class XmlParserTest {
|
||||||
ourLog.info(bundleString);
|
ourLog.info(bundleString);
|
||||||
|
|
||||||
List<String> strings = new ArrayList<String>();
|
List<String> strings = new ArrayList<String>();
|
||||||
strings.addAll(Arrays.asList("<published>", pub.getValueAsString(), "</published>"));
|
|
||||||
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
|
strings.add("<category term=\"http://hl7.org/fhir/tag/message\" label=\"Message\" scheme=\"http://hl7.org/fhir/tag\"/>");
|
||||||
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
|
strings.addAll(Arrays.asList("<entry>", "<id>1</id>", "</Patient>", "<summary type=\"xhtml\">", "<div", "</entry>"));
|
||||||
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
|
strings.addAll(Arrays.asList("<entry>", "<id>2</id>", "<link rel=\"alternate\" href=\"http://foo/bar\"/>", "<link rel=\"search\" href=\"http://foo/bar/search\"/>", "</entry>"));
|
||||||
|
|
|
@ -102,7 +102,6 @@ public class ClientTest {
|
||||||
"<title/>\n" +
|
"<title/>\n" +
|
||||||
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
|
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
|
||||||
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
|
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
|
||||||
"<published>2014-03-11T16:35:07-04:00</published>\n" +
|
|
||||||
"<author>\n" +
|
"<author>\n" +
|
||||||
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
|
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
|
||||||
"</author>\n" +
|
"</author>\n" +
|
||||||
|
@ -301,7 +300,6 @@ public class ClientTest {
|
||||||
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
|
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
|
||||||
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
|
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
|
||||||
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
|
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
|
||||||
+ "<published>2014-04-13T18:24:50-04:00</published>"
|
|
||||||
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
|
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
|
||||||
+ "<entry><title>Patient 222</title><id>222</id>"
|
+ "<entry><title>Patient 222</title><id>222</id>"
|
||||||
+ "<updated>"+date1.getValueAsString()+"</updated>"
|
+ "<updated>"+date1.getValueAsString()+"</updated>"
|
||||||
|
@ -374,7 +372,6 @@ public class ClientTest {
|
||||||
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
|
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
|
||||||
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
|
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
|
||||||
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
|
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
|
||||||
+ "<published>2014-04-13T18:24:50-04:00</published>"
|
|
||||||
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
|
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
|
||||||
+ "<entry><title>Patient 222</title><id>222</id>"
|
+ "<entry><title>Patient 222</title><id>222</id>"
|
||||||
+ "<updated>"+date1.getValueAsString()+"</updated>"
|
+ "<updated>"+date1.getValueAsString()+"</updated>"
|
||||||
|
@ -446,7 +443,6 @@ public class ClientTest {
|
||||||
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
|
String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id>"
|
||||||
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
|
+ "<link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/>"
|
||||||
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
|
+ "<link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>"
|
||||||
+ "<published>2014-04-13T18:24:50-04:00</published>"
|
|
||||||
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
|
+ "<author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author>"
|
||||||
+ "<entry><title>Patient 222</title><id>222</id>"
|
+ "<entry><title>Patient 222</title><id>222</id>"
|
||||||
+ "<updated>"+date1.getValueAsString()+"</updated>"
|
+ "<updated>"+date1.getValueAsString()+"</updated>"
|
||||||
|
@ -511,7 +507,7 @@ public class ClientTest {
|
||||||
public void testHistoryWithParams() throws Exception {
|
public void testHistoryWithParams() throws Exception {
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
final String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/><link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults><published>2014-04-13T18:24:50-04:00</published><author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:20.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/1\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"OlderFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:30.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/2\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"NewerFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry></feed>";
|
final String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\"><title/><id>6c1d93be-027f-468d-9d47-f826cd15cf42</id><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history\"/><link rel=\"fhir-base\" href=\"http://localhost:51698\"/><os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults><author><name>ca.uhn.fhir.rest.method.HistoryMethodBinding</name></author><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:20.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/1\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"OlderFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry><entry><title>Patient 222</title><id>222</id><updated>1969-12-31T19:00:30.000-05:00</updated><published>1969-12-31T19:00:10.000-05:00</published><link rel=\"self\" href=\"http://localhost:51698/Patient/222/_history/2\"/><content type=\"text/xml\"><Patient xmlns=\"http://hl7.org/fhir\"><identifier><use value=\"official\"/><system value=\"urn:hapitest:mrns\"/><value value=\"00001\"/></identifier><name><family value=\"NewerFamily\"/><given value=\"PatientOne\"/></name><gender><text value=\"M\"/></gender></Patient></content></entry></feed>";
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
|
|
@ -85,7 +85,6 @@ public class GenericClientTest {
|
||||||
"<title/>\n" +
|
"<title/>\n" +
|
||||||
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
|
"<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" +
|
||||||
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
|
"<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" +
|
||||||
"<published>2014-03-11T16:35:07-04:00</published>\n" +
|
|
||||||
"<author>\n" +
|
"<author>\n" +
|
||||||
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
|
"<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" +
|
||||||
"</author>\n" +
|
"</author>\n" +
|
||||||
|
|
|
@ -114,7 +114,6 @@ public class IncludedResourceStitchingClientTest {
|
||||||
" <link rel=\"self\" href=\"http://localhost:49782/Patient?_query=declaredExtInclude&_pretty=true\"/>\n" +
|
" <link rel=\"self\" href=\"http://localhost:49782/Patient?_query=declaredExtInclude&_pretty=true\"/>\n" +
|
||||||
" <link rel=\"fhir-base\" href=\"http://localhost:49782\"/>\n" +
|
" <link rel=\"fhir-base\" href=\"http://localhost:49782\"/>\n" +
|
||||||
" <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" +
|
" <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" +
|
||||||
" <published>2014-08-12T10:22:19.097-04:00</published>\n" +
|
|
||||||
" <author>\n" +
|
" <author>\n" +
|
||||||
" <name>HAPI FHIR Server</name>\n" +
|
" <name>HAPI FHIR Server</name>\n" +
|
||||||
" </author>\n" +
|
" </author>\n" +
|
||||||
|
@ -192,7 +191,6 @@ public class IncludedResourceStitchingClientTest {
|
||||||
" <link rel=\"self\" href=\"http://localhost:49627/Patient?_query=extInclude&_pretty=true\"/>\n" +
|
" <link rel=\"self\" href=\"http://localhost:49627/Patient?_query=extInclude&_pretty=true\"/>\n" +
|
||||||
" <link rel=\"fhir-base\" href=\"http://localhost:49627\"/>\n" +
|
" <link rel=\"fhir-base\" href=\"http://localhost:49627\"/>\n" +
|
||||||
" <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" +
|
" <os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">2</os:totalResults>\n" +
|
||||||
" <published>2014-08-05T15:22:08.512-04:00</published>\n" +
|
|
||||||
" <author>\n" +
|
" <author>\n" +
|
||||||
" <name>HAPI FHIR Server</name>\n" +
|
" <name>HAPI FHIR Server</name>\n" +
|
||||||
" </author>\n" +
|
" </author>\n" +
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -20,6 +20,7 @@ import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Medication;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Practitioner;
|
import ca.uhn.fhir.model.dstu.resource.Practitioner;
|
||||||
|
@ -86,6 +87,23 @@ public class Dstu1BundleFactoryTest {
|
||||||
myBundleFactory = new Dstu1BundleFactory(ourCtx);
|
myBundleFactory = new Dstu1BundleFactory(ourCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMedicationHasIngredients_include_shouldIncludeThem() throws Exception {
|
||||||
|
Medication medication = new Medication();
|
||||||
|
medication.setName("Main Medication");
|
||||||
|
medication.setId("Medication/1");
|
||||||
|
Medication ingredientMedication = new Medication();
|
||||||
|
ingredientMedication.setName("Ingredient");
|
||||||
|
ingredientMedication.setId("Medication/2");
|
||||||
|
Medication.ProductIngredient ingredient = new Medication.ProductIngredient();
|
||||||
|
ingredient.setItem(new ResourceReferenceDt(ingredientMedication));
|
||||||
|
medication.getProduct().getIngredient().add(ingredient);
|
||||||
|
|
||||||
|
myResourceList = Arrays.asList(new IBaseResource[]{medication});
|
||||||
|
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("Medication.product.ingredient.item"));
|
||||||
|
assertEquals(2, bundle.getEntries().size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception {
|
public void whenIncludeIsAsterisk_bundle_shouldContainAllReferencedResources() throws Exception {
|
||||||
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*"));
|
Bundle bundle = makeBundle(BundleInclusionRule.BASED_ON_INCLUDES, includes("*"));
|
||||||
|
|
|
@ -1,17 +1,79 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.ClientProtocolException;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.RandomServerPortProvider;
|
||||||
|
|
||||||
public class IncomingRequestAddressStrategyTest {
|
public class IncomingRequestAddressStrategyTest {
|
||||||
|
|
||||||
|
private static CloseableHttpClient ourClient;
|
||||||
|
private static String ourLastBase;
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IncomingRequestAddressStrategyTest.class);
|
||||||
|
private static IncomingRequestAddressStrategy ourStrategy;
|
||||||
|
|
||||||
|
private Server myServer;
|
||||||
|
|
||||||
|
public void after() throws Exception {
|
||||||
|
if (myServer != null) {
|
||||||
|
myServer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
ourLastBase = null;
|
||||||
|
ourStrategy = new IncomingRequestAddressStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void httpGet(String url) throws IOException, ClientProtocolException {
|
||||||
|
ourLastBase = null;
|
||||||
|
|
||||||
|
HttpGet httpPost = new HttpGet(url);
|
||||||
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
ourLog.info(responseContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startServer(int port, String contextPath, String servletPath) throws Exception {
|
||||||
|
myServer = new Server(port);
|
||||||
|
|
||||||
|
org.eclipse.jetty.servlet.ServletContextHandler proxyHandler = new org.eclipse.jetty.servlet.ServletContextHandler();
|
||||||
|
proxyHandler.setContextPath(contextPath);
|
||||||
|
|
||||||
|
ServletHolder handler = new ServletHolder();
|
||||||
|
handler.setServlet(new MyServlet());
|
||||||
|
proxyHandler.addServlet(handler, servletPath);
|
||||||
|
|
||||||
|
myServer.setHandler(proxyHandler);
|
||||||
|
myServer.start();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an incoming request from an instance of Tomcat on AWS, provided by
|
* This is an incoming request from an instance of Tomcat on AWS, provided by Simon Ling of Systems Made Simple
|
||||||
* Simon Ling of Systems Made Simple
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAwsUrl() {
|
public void testAwsUrl() {
|
||||||
|
@ -27,4 +89,148 @@ public class IncomingRequestAddressStrategyTest {
|
||||||
assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual);
|
assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnderJettyWithContextPathServletRoot() throws Exception {
|
||||||
|
int port = RandomServerPortProvider.findFreePort();
|
||||||
|
|
||||||
|
String contextPath = "/ctx";
|
||||||
|
String servletPath = "/*";
|
||||||
|
|
||||||
|
startServer(port, contextPath, servletPath);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/Patient?_pretty=true");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/Patient/123/_history/222");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port);
|
||||||
|
assertEquals(null, ourLastBase);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnderJettyWithContextPathServletRootContextOnly() throws Exception {
|
||||||
|
int port = RandomServerPortProvider.findFreePort();
|
||||||
|
|
||||||
|
String contextPath = "/ctx";
|
||||||
|
String servletPath = "/";
|
||||||
|
|
||||||
|
startServer(port, contextPath, servletPath);
|
||||||
|
ourStrategy.setServletPath("");
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/Patient?_pretty=true");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/Patient/123/_history/222");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port);
|
||||||
|
assertEquals(null, ourLastBase);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnderJettyWithContextPathServletRoot2() throws Exception {
|
||||||
|
int port = RandomServerPortProvider.findFreePort();
|
||||||
|
|
||||||
|
String contextPath = "/ctx";
|
||||||
|
String servletPath = "/foo/bar/*"; // not /* but still this should work
|
||||||
|
|
||||||
|
startServer(port, contextPath, servletPath);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/foo/bar/Patient?_pretty=true");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/foo/bar");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/foo/bar/");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/foo/bar/Patient/123/_history/222");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/foo/bar", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port);
|
||||||
|
assertEquals(null, ourLastBase);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnderJettyWithContextPathServletPath() throws Exception {
|
||||||
|
int port = RandomServerPortProvider.findFreePort();
|
||||||
|
|
||||||
|
String contextPath = "/ctx";
|
||||||
|
String servletPath = "/servlet/*";
|
||||||
|
|
||||||
|
startServer(port, contextPath, servletPath);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port);
|
||||||
|
assertEquals(null, ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/servlet/");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/servlet", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/servlet/Patient?_pretty=true");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/servlet", ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/ctx/servlet/Patient/123/_history/222");
|
||||||
|
assertEquals("http://localhost:" + port + "/ctx/servlet", ourLastBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnderJettyWithContextRootServletRoot() throws Exception {
|
||||||
|
int port = RandomServerPortProvider.findFreePort();
|
||||||
|
|
||||||
|
String contextPath = "/";
|
||||||
|
String servletPath = "/*";
|
||||||
|
|
||||||
|
startServer(port, contextPath, servletPath);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port);
|
||||||
|
assertEquals("http://localhost:" + port + contextPath, ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/Patient?_pretty=true");
|
||||||
|
assertEquals("http://localhost:" + port + contextPath, ourLastBase);
|
||||||
|
|
||||||
|
httpGet("http://localhost:" + port + "/Patient/123/_history/222");
|
||||||
|
assertEquals("http://localhost:" + port + contextPath, ourLastBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||||
|
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||||
|
builder.setConnectionManager(connectionManager);
|
||||||
|
ourClient = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
||||||
|
|
||||||
|
// ourLog.info("Ctx: {}", theReq.)
|
||||||
|
|
||||||
|
ourLastBase = ourStrategy.determineServerBase(getServletContext(), theReq);
|
||||||
|
theResp.setContentType("text/plain");
|
||||||
|
theResp.getWriter().append("Success");
|
||||||
|
theResp.getWriter().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,14 @@ import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
@ -38,10 +40,13 @@ import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Search;
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||||
|
@ -233,6 +238,75 @@ public class SearchTest {
|
||||||
assertEquals("IDAAA (identifier123)", bundle.getEntries().get(0).getTitle().getValue());
|
assertEquals("IDAAA (identifier123)", bundle.getEntries().get(0).getTitle().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #164
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchByPostWithParamsInBodyAndUrl() throws Exception {
|
||||||
|
HttpPost filePost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search?name=Central");
|
||||||
|
|
||||||
|
// add parameters to the post method
|
||||||
|
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
|
||||||
|
parameters.add(new BasicNameValuePair("_id", "aaa"));
|
||||||
|
|
||||||
|
UrlEncodedFormEntity sendentity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||||
|
filePost.setEntity(sendentity);
|
||||||
|
|
||||||
|
HttpResponse status = ourClient.execute(filePost);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
ourLog.info(responseContent);
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||||
|
assertEquals(1, bundle.getEntries().size());
|
||||||
|
|
||||||
|
Patient p = bundle.getResources(Patient.class).get(0);
|
||||||
|
assertEquals("idaaa", p.getName().get(0).getFamilyAsSingleString());
|
||||||
|
assertEquals("nameCentral", p.getName().get(1).getFamilyAsSingleString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #164
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchByPostWithInvalidPostUrl() throws Exception {
|
||||||
|
HttpPost filePost = new HttpPost("http://localhost:" + ourPort + "/Patient?name=Central"); // should end with _search
|
||||||
|
|
||||||
|
// add parameters to the post method
|
||||||
|
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
|
||||||
|
parameters.add(new BasicNameValuePair("_id", "aaa"));
|
||||||
|
|
||||||
|
UrlEncodedFormEntity sendentity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||||
|
filePost.setEntity(sendentity);
|
||||||
|
|
||||||
|
HttpResponse status = ourClient.execute(filePost);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
ourLog.info(responseContent);
|
||||||
|
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||||
|
assertThat(responseContent, containsString("<details value=\"Incorrect Content-Type header value of "application/x-www-form-urlencoded; charset=UTF-8" was provided in the request. This is required for "CREATE" operation\"/>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #164
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchByPostWithMissingContentType() throws Exception {
|
||||||
|
HttpPost filePost = new HttpPost("http://localhost:" + ourPort + "/Patient?name=Central"); // should end with _search
|
||||||
|
|
||||||
|
HttpEntity sendentity = new ByteArrayEntity(new byte[] {1,2,3,4} );
|
||||||
|
filePost.setEntity(sendentity);
|
||||||
|
|
||||||
|
HttpResponse status = ourClient.execute(filePost);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
ourLog.info(responseContent);
|
||||||
|
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||||
|
assertThat(responseContent, containsString("<details value=\"No Content-Type header was provided in the request. This is required for "CREATE" operation\"/>"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchCompartment() throws Exception {
|
public void testSearchCompartment() throws Exception {
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/fooCompartment");
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/fooCompartment");
|
||||||
|
@ -354,6 +428,14 @@ public class SearchTest {
|
||||||
*/
|
*/
|
||||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only needed for #164
|
||||||
|
*/
|
||||||
|
@Create
|
||||||
|
public MethodOutcome create(@ResourceParam Patient thePatient) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
@Search(compartmentName = "fooCompartment")
|
@Search(compartmentName = "fooCompartment")
|
||||||
public List<Patient> compartment(@IdParam IdDt theId) {
|
public List<Patient> compartment(@IdParam IdDt theId) {
|
||||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
@ -383,7 +465,7 @@ public class SearchTest {
|
||||||
|
|
||||||
|
|
||||||
@Search
|
@Search
|
||||||
public List<Patient> findPatient(@RequiredParam(name = "_id") StringParam theParam) {
|
public List<Patient> findPatient(@RequiredParam(name = "_id") StringParam theParam, @OptionalParam(name="name") StringParam theName) {
|
||||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||||
|
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -391,6 +473,7 @@ public class SearchTest {
|
||||||
patient.addIdentifier("system", "identifier123");
|
patient.addIdentifier("system", "identifier123");
|
||||||
if (theParam != null) {
|
if (theParam != null) {
|
||||||
patient.addName().addFamily("id" + theParam.getValue());
|
patient.addName().addFamily("id" + theParam.getValue());
|
||||||
|
patient.addName().addFamily("name" + theName.getValue());
|
||||||
}
|
}
|
||||||
retVal.add(patient);
|
retVal.add(patient);
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides server ports
|
||||||
|
*/
|
||||||
|
public class RandomServerPortProvider {
|
||||||
|
|
||||||
|
private static List<Integer> ourPorts = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
public static int findFreePort() {
|
||||||
|
ServerSocket server;
|
||||||
|
try {
|
||||||
|
server = new ServerSocket(0);
|
||||||
|
int port = server.getLocalPort();
|
||||||
|
ourPorts.add(port);
|
||||||
|
server.close();
|
||||||
|
Thread.sleep(500);
|
||||||
|
return port;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Integer> list() {
|
||||||
|
return ourPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<link rel="self" href="http://localhost:8888/fhir/context/Patient?_pretty=true&_include=Patient.managingOrganization&_pretty=true"/>
|
<link rel="self" href="http://localhost:8888/fhir/context/Patient?_pretty=true&_include=Patient.managingOrganization&_pretty=true"/>
|
||||||
<link rel="fhir-base" href="http://localhost:8888/fhir/context"/>
|
<link rel="fhir-base" href="http://localhost:8888/fhir/context"/>
|
||||||
<os:totalResults xmlns:os="http://a9.com/-/spec/opensearch/1.1/">2</os:totalResults>
|
<os:totalResults xmlns:os="http://a9.com/-/spec/opensearch/1.1/">2</os:totalResults>
|
||||||
<published>2014-06-22T21:37:05-04:00</published>
|
|
||||||
<author>
|
<author>
|
||||||
<name>HAPI FHIR Server</name>
|
<name>HAPI FHIR Server</name>
|
||||||
</author>
|
</author>
|
||||||
|
|
|
@ -276,7 +276,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeBundleFromResourceList(String theAuthor, List<IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
public void initializeBundleFromResourceList(String theAuthor, List<? extends IBaseResource> theResources, String theServerBase, String theCompleteUrl, int theTotalResults, BundleTypeEnum theBundleType) {
|
||||||
myBundle = new Bundle();
|
myBundle = new Bundle();
|
||||||
|
|
||||||
myBundle.setId(UUID.randomUUID().toString());
|
myBundle.setId(UUID.randomUUID().toString());
|
||||||
|
@ -312,7 +312,7 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
myBundle.getTotalElement().setValue(theTotalResults);
|
myBundle.getTotalElement().setValue(theTotalResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addResourcesForSearch(List<IBaseResource> theResult) {
|
private void addResourcesForSearch(List<? extends IBaseResource> theResult) {
|
||||||
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
|
List<IBaseResource> includedResources = new ArrayList<IBaseResource>();
|
||||||
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
|
Set<IIdType> addedResourceIds = new HashSet<IIdType>();
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,21 @@ import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||||
|
|
||||||
public class BaseDateTimeDtTest {
|
public class BaseDateTimeDtTest {
|
||||||
private SimpleDateFormat myDateInstantParser;
|
private SimpleDateFormat myDateInstantParser;
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseDateTimeDtTest.class);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
myDateInstantParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
myDateInstantParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToHumanDisplay() {
|
||||||
|
DateTimeDt dt = new DateTimeDt("2012-01-05T12:00:00-08:00");
|
||||||
|
String human = dt.toHumanDisplay();
|
||||||
|
ourLog.info(human);
|
||||||
|
assertEquals("Jan 5, 2012 12:00:00 PM", human);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
|
* See HAPI #101 - https://github.com/jamesagnew/hapi-fhir/issues/101
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static org.junit.Assert.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import net.sf.json.JSON;
|
import net.sf.json.JSON;
|
||||||
import net.sf.json.JSONSerializer;
|
import net.sf.json.JSONSerializer;
|
||||||
|
@ -13,12 +14,14 @@ import net.sf.json.JsonConfig;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
import org.hamcrest.core.StringContains;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
import ca.uhn.fhir.model.api.BundleEntry;
|
||||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
@ -28,12 +31,15 @@ import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Binary;
|
import ca.uhn.fhir.model.dstu2.resource.Binary;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
|
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireAnswers;
|
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireAnswers;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.ObservationReliabilityEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.ObservationReliabilityEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum;
|
||||||
|
@ -80,6 +86,36 @@ public class JsonParserDstu2Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #163
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParseResourceType() {
|
||||||
|
IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||||
|
|
||||||
|
// Patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
String patientId = UUID.randomUUID().toString();
|
||||||
|
patient.setId(new IdDt("Patient", patientId));
|
||||||
|
patient.addName().addGiven("John").addFamily("Smith");
|
||||||
|
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||||
|
patient.setBirthDate(new DateDt("1987-04-16"));
|
||||||
|
|
||||||
|
// Bundle
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle bundle = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||||
|
bundle.setType(BundleTypeEnum.COLLECTION);
|
||||||
|
bundle.addEntry().setResource(patient);
|
||||||
|
|
||||||
|
String bundleText = jsonParser.encodeResourceToString(bundle);
|
||||||
|
ourLog.info(bundleText);
|
||||||
|
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle reincarnatedBundle = jsonParser.parseResource (ca.uhn.fhir.model.dstu2.resource.Bundle.class, bundleText);
|
||||||
|
Patient reincarnatedPatient = reincarnatedBundle.getAllPopulatedChildElementsOfType(Patient.class).get(0);
|
||||||
|
|
||||||
|
assertEquals("Patient", patient.getId().getResourceType());
|
||||||
|
assertEquals("Patient", reincarnatedPatient.getId().getResourceType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See #144 and #146
|
* See #144 and #146
|
||||||
*/
|
*/
|
||||||
|
@ -103,6 +139,46 @@ public class JsonParserDstu2Test {
|
||||||
Assert.assertThat(message, containsString("contained"));
|
Assert.assertThat(message, containsString("contained"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeBundleOldBundleNoText() {
|
||||||
|
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
|
||||||
|
BundleEntry e = b.addEntry();
|
||||||
|
e.setResource(new Patient());
|
||||||
|
b.addCategory("scheme", "term", "label");
|
||||||
|
|
||||||
|
String val = new FhirContext().newJsonParser().setPrettyPrint(false).encodeBundleToString(b);
|
||||||
|
ourLog.info(val);
|
||||||
|
|
||||||
|
assertThat(val, not(containsString("text")));
|
||||||
|
|
||||||
|
b = new FhirContext().newJsonParser().parseBundle(val);
|
||||||
|
assertEquals(1, b.getEntries().size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeBundleNewBundleNoText() {
|
||||||
|
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle b = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||||
|
b.getText().setDiv("");
|
||||||
|
b.getText().getStatus().setValueAsString("");
|
||||||
|
;
|
||||||
|
|
||||||
|
Entry e = b.addEntry();
|
||||||
|
e.setResource(new Patient());
|
||||||
|
|
||||||
|
String val = new FhirContext().newJsonParser().setPrettyPrint(false).encodeResourceToString(b);
|
||||||
|
ourLog.info(val);
|
||||||
|
assertThat(val, not(containsString("text")));
|
||||||
|
|
||||||
|
val = new FhirContext().newXmlParser().setPrettyPrint(false).encodeResourceToString(b);
|
||||||
|
ourLog.info(val);
|
||||||
|
assertThat(val, not(containsString("text")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See #144 and #146
|
* See #144 and #146
|
||||||
*/
|
*/
|
||||||
|
@ -516,7 +592,6 @@ public class JsonParserDstu2Test {
|
||||||
assertThat(reencoded, containsString("contained"));
|
assertThat(reencoded, containsString("contained"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseAndEncodeBundle() throws Exception {
|
public void testParseAndEncodeBundle() throws Exception {
|
||||||
String content = IOUtils.toString(JsonParserDstu2Test.class.getResourceAsStream("/bundle-example.json"));
|
String content = IOUtils.toString(JsonParserDstu2Test.class.getResourceAsStream("/bundle-example.json"));
|
||||||
|
@ -583,7 +658,6 @@ public class JsonParserDstu2Test {
|
||||||
assertEquals("Medication/example", p.getMedication().getReference().getValue());
|
assertEquals("Medication/example", p.getMedication().getReference().getValue());
|
||||||
assertSame(p.getMedication().getResource(), m);
|
assertSame(p.getMedication().getResource(), m);
|
||||||
|
|
||||||
|
|
||||||
String reencoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(parsed);
|
String reencoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(parsed);
|
||||||
ourLog.info(reencoded);
|
ourLog.info(reencoded);
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,8 @@ import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.DocumentReferenceStatusEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.DocumentReferenceStatusEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||||
import ca.uhn.fhir.model.primitive.DateDt;
|
import ca.uhn.fhir.model.primitive.DateDt;
|
||||||
|
@ -471,6 +473,38 @@ public class XmlParserDstu2Test {
|
||||||
assertEquals(htmlNoNs, p.getText().getDiv().getValueAsString());
|
assertEquals(htmlNoNs, p.getText().getDiv().getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #163
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParseResourceType() {
|
||||||
|
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||||
|
|
||||||
|
// Patient
|
||||||
|
Patient patient = new Patient();
|
||||||
|
String patientId = UUID.randomUUID().toString();
|
||||||
|
patient.setId(new IdDt("Patient", patientId));
|
||||||
|
patient.addName().addGiven("John").addFamily("Smith");
|
||||||
|
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||||
|
patient.setBirthDate(new DateDt("1987-04-16"));
|
||||||
|
|
||||||
|
// Bundle
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle bundle = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||||
|
bundle.setType(BundleTypeEnum.COLLECTION);
|
||||||
|
bundle.addEntry().setResource(patient);
|
||||||
|
|
||||||
|
String bundleText = xmlParser.encodeResourceToString(bundle);
|
||||||
|
ourLog.info(bundleText);
|
||||||
|
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle reincarnatedBundle = xmlParser.parseResource (ca.uhn.fhir.model.dstu2.resource.Bundle.class, bundleText);
|
||||||
|
Patient reincarnatedPatient = reincarnatedBundle.getAllPopulatedChildElementsOfType(Patient.class).get(0);
|
||||||
|
|
||||||
|
assertEquals("Patient", patient.getId().getResourceType());
|
||||||
|
assertEquals("Patient", reincarnatedPatient.getId().getResourceType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thanks to Alexander Kley!
|
* Thanks to Alexander Kley!
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.io.StringReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import org.apache.commons.io.input.ReaderInputStream;
|
import org.apache.commons.io.input.ReaderInputStream;
|
||||||
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.ProtocolVersion;
|
import org.apache.http.ProtocolVersion;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
|
@ -31,6 +32,7 @@ import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
import ca.uhn.fhir.model.primitive.UriDt;
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||||
|
import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
|
||||||
public class ClientServerValidationTestDstu2 {
|
public class ClientServerValidationTestDstu2 {
|
||||||
|
@ -70,11 +72,12 @@ public class ClientServerValidationTestDstu2 {
|
||||||
} else {
|
} else {
|
||||||
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
||||||
}
|
}
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
|
||||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||||
|
|
||||||
// don't load the conformance until the first time the client is actually used
|
// don't load the conformance until the first time the client is actually used
|
||||||
|
@ -107,11 +110,12 @@ public class ClientServerValidationTestDstu2 {
|
||||||
} else {
|
} else {
|
||||||
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(new Patient())), Charset.forName("UTF-8"));
|
||||||
}
|
}
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
|
||||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||||
|
|
||||||
// don't load the conformance until the first time the client is actually used
|
// don't load the conformance until the first time the client is actually used
|
||||||
|
@ -139,7 +143,7 @@ public class ClientServerValidationTestDstu2 {
|
||||||
|
|
||||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
|
||||||
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
|
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
try {
|
try {
|
||||||
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/123"));
|
||||||
fail();
|
fail();
|
||||||
|
@ -151,4 +155,95 @@ public class ClientServerValidationTestDstu2 {
|
||||||
assertThat(out, containsString(want));
|
assertThat(out, containsString(want));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClientUsesInterceptors() throws Exception {
|
||||||
|
Conformance conf = new Conformance();
|
||||||
|
conf.setFhirVersion("0.5.0");
|
||||||
|
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||||
|
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
|
||||||
|
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||||
|
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||||
|
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||||
|
if (myFirstResponse) {
|
||||||
|
myFirstResponse = false;
|
||||||
|
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||||
|
} else {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.addName().addFamily().setValue("FAM");
|
||||||
|
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
|
||||||
|
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
|
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||||
|
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
|
||||||
|
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
|
||||||
|
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
|
||||||
|
|
||||||
|
assertEquals(2, capt.getAllValues().size());
|
||||||
|
|
||||||
|
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
|
||||||
|
assertNotNull(auth);
|
||||||
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
|
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
|
||||||
|
assertNotNull(auth);
|
||||||
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForceConformanceCheck() throws Exception {
|
||||||
|
Conformance conf = new Conformance();
|
||||||
|
conf.setFhirVersion("0.5.0");
|
||||||
|
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
|
||||||
|
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
|
||||||
|
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||||
|
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||||
|
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||||
|
if (myFirstResponse) {
|
||||||
|
myFirstResponse = false;
|
||||||
|
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
|
||||||
|
} else {
|
||||||
|
Patient resource = new Patient();
|
||||||
|
resource.addName().addFamily().setValue("FAM");
|
||||||
|
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
|
||||||
|
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||||
|
|
||||||
|
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
|
||||||
|
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
|
||||||
|
|
||||||
|
client.forceConformanceCheck();
|
||||||
|
|
||||||
|
assertEquals(1, capt.getAllValues().size());
|
||||||
|
|
||||||
|
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
|
||||||
|
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
|
||||||
|
|
||||||
|
assertEquals(2, capt.getAllValues().size());
|
||||||
|
|
||||||
|
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
|
||||||
|
assertNotNull(auth);
|
||||||
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
|
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
|
||||||
|
assertNotNull(auth);
|
||||||
|
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -36,6 +37,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
@ -616,6 +618,64 @@ public class GenericClientDstu2Test {
|
||||||
// assertEquals("PATIENT2", p2.getName().get(0).getFamily().get(0).getValue());
|
// assertEquals("PATIENT2", p2.getName().get(0).getFamily().get(0).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionWithString() throws Exception {
|
||||||
|
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle req = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||||
|
req.addEntry().setResource(new Patient());
|
||||||
|
req.addEntry().setResource(new Observation());
|
||||||
|
String reqStringJson = ourCtx.newJsonParser().encodeResourceToString(req);
|
||||||
|
String reqStringXml = ourCtx.newXmlParser().encodeResourceToString(req);
|
||||||
|
|
||||||
|
ca.uhn.fhir.model.dstu2.resource.Bundle resp = new ca.uhn.fhir.model.dstu2.resource.Bundle();
|
||||||
|
resp.addEntry().getTransactionResponse().setLocation("Patient/1/_history/1");
|
||||||
|
resp.addEntry().getTransactionResponse().setLocation("Patient/2/_history/2");
|
||||||
|
final String respStringJson = ourCtx.newJsonParser().encodeResourceToString(resp);
|
||||||
|
|
||||||
|
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_JSON + "; charset=UTF-8"));
|
||||||
|
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||||
|
return new ReaderInputStream(new StringReader(respStringJson), Charset.forName("UTF-8"));
|
||||||
|
}});
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
String response = client.transaction()
|
||||||
|
.withBundle(reqStringJson)
|
||||||
|
.execute();
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
assertEquals("http://example.com/fhir/", capt.getValue().getURI().toString());
|
||||||
|
assertEquals(respStringJson, response);
|
||||||
|
String requestString = IOUtils.toString(((HttpEntityEnclosingRequest) capt.getValue()).getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(((HttpEntityEnclosingRequest) capt.getValue()).getEntity().getContent());
|
||||||
|
assertEquals(reqStringJson, requestString);
|
||||||
|
assertEquals("application/json+fhir; charset=UTF-8", capt.getValue().getFirstHeader("Content-Type").getValue());
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
response = client.transaction()
|
||||||
|
.withBundle(reqStringJson)
|
||||||
|
.encodedXml()
|
||||||
|
.execute();
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
assertEquals("http://example.com/fhir/?_format=xml", capt.getValue().getURI().toString());
|
||||||
|
assertEquals(respStringJson, response);
|
||||||
|
requestString = IOUtils.toString(((HttpEntityEnclosingRequest) capt.getValue()).getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(((HttpEntityEnclosingRequest) capt.getValue()).getEntity().getContent());
|
||||||
|
assertEquals(reqStringXml, requestString);
|
||||||
|
assertEquals("application/xml+fhir; charset=UTF-8", capt.getValue().getFirstHeader("Content-Type").getValue());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithTransactionResource() throws Exception {
|
public void testTransactionWithTransactionResource() throws Exception {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -45,12 +47,31 @@ public class SearchDstu2Test {
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
ourLog.info(responseContent);
|
ourLog.info(responseContent);
|
||||||
|
|
||||||
|
assertThat(responseContent, not(containsString("text")));
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
Patient patient = (Patient) ourCtx.newXmlParser().parseResource(Bundle.class, responseContent).getEntry().get(0).getResource();
|
Patient patient = (Patient) ourCtx.newXmlParser().parseResource(Bundle.class, responseContent).getEntry().get(0).getResource();
|
||||||
String ref = patient.getManagingOrganization().getReference().getValue();
|
String ref = patient.getManagingOrganization().getReference().getValue();
|
||||||
assertEquals("Organization/555", ref);
|
assertEquals("Organization/555", ref);
|
||||||
|
assertNull(status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodeConvertsReferencesToRelativeJson() throws Exception {
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchWithRef&_format=json");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
ourLog.info(responseContent);
|
||||||
|
|
||||||
|
assertThat(responseContent, not(containsString("text")));
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
Patient patient = (Patient) ourCtx.newJsonParser().parseResource(Bundle.class, responseContent).getEntry().get(0).getResource();
|
||||||
|
String ref = patient.getManagingOrganization().getReference().getValue();
|
||||||
|
assertEquals("Organization/555", ref);
|
||||||
|
assertNull(status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION));
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClass() throws Exception {
|
public static void afterClass() throws Exception {
|
||||||
|
@ -66,7 +87,6 @@ public class SearchDstu2Test {
|
||||||
|
|
||||||
ServletHandler proxyHandler = new ServletHandler();
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
RestfulServer servlet = new RestfulServer();
|
RestfulServer servlet = new RestfulServer();
|
||||||
servlet.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
|
||||||
|
|
||||||
servlet.setResourceProviders(patientProvider);
|
servlet.setResourceProviders(patientProvider);
|
||||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>0.9-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-base</artifactId>
|
<artifactId>hapi-fhir-base</artifactId>
|
||||||
<version>0.9-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf</groupId>
|
<groupId>org.thymeleaf</groupId>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>${servlet_api_version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
|
@ -1 +1,128 @@
|
||||||
|
/target/
|
||||||
|
|
||||||
|
# Created by https://www.gitignore.io
|
||||||
|
|
||||||
|
### Java ###
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
|
||||||
|
### Maven ###
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
|
||||||
|
|
||||||
|
### Vim ###
|
||||||
|
[._]*.s[a-w][a-z]
|
||||||
|
[._]s[a-w][a-z]
|
||||||
|
*.un~
|
||||||
|
Session.vim
|
||||||
|
.netrwhist
|
||||||
|
*~
|
||||||
|
|
||||||
|
|
||||||
|
### Intellij ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
## Directory-based project format:
|
||||||
|
.idea/
|
||||||
|
# if you remove the above rule, at least ignore the following:
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
# .idea/workspace.xml
|
||||||
|
# .idea/tasks.xml
|
||||||
|
# .idea/dictionaries
|
||||||
|
|
||||||
|
# Sensitive or high-churn files:
|
||||||
|
# .idea/dataSources.ids
|
||||||
|
# .idea/dataSources.xml
|
||||||
|
# .idea/sqlDataSources.xml
|
||||||
|
# .idea/dynamic.xml
|
||||||
|
# .idea/uiDesigner.xml
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
# .idea/gradle.xml
|
||||||
|
# .idea/libraries
|
||||||
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
# .idea/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
*.pydevproject
|
||||||
|
.metadata
|
||||||
|
.gradle
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
|
||||||
|
# Eclipse Core
|
||||||
|
.project
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# JDT-specific (Eclipse Java Development Tools)
|
||||||
|
.classpath
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
# sbteclipse plugin
|
||||||
|
.target
|
||||||
|
|
||||||
|
# TeXlipse plugin
|
||||||
|
.texlipse
|
||||||
|
|
||||||
/build/
|
/build/
|
||||||
|
|
|
@ -1203,7 +1203,7 @@ public class Controller {
|
||||||
|
|
||||||
private String parseNarrative(HomeRequest theRequest, EncodingEnum theCtEnum, String theResultBody) {
|
private String parseNarrative(HomeRequest theRequest, EncodingEnum theCtEnum, String theResultBody) {
|
||||||
try {
|
try {
|
||||||
IResource resource = theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody);
|
IResource resource = (IResource) theCtEnum.newParser(getContext(theRequest)).parseResource(theResultBody);
|
||||||
String retVal = resource.getText().getDiv().getValueAsString();
|
String retVal = resource.getText().getDiv().getValueAsString();
|
||||||
return StringUtils.defaultString(retVal);
|
return StringUtils.defaultString(retVal);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -9,15 +9,21 @@ import org.apache.commons.lang3.Validate;
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.util.ITestingUiClientFactory;
|
||||||
|
|
||||||
public class TesterConfig {
|
public class TesterConfig {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TesterConfig.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TesterConfig.class);
|
||||||
|
|
||||||
public static final String SYSPROP_FORCE_SERVERS = "ca.uhn.fhir.to.TesterConfig_SYSPROP_FORCE_SERVERS";
|
public static final String SYSPROP_FORCE_SERVERS = "ca.uhn.fhir.to.TesterConfig_SYSPROP_FORCE_SERVERS";
|
||||||
|
|
||||||
private LinkedHashMap<String, String> myIdToServerName = new LinkedHashMap<String, String>();
|
private ITestingUiClientFactory myClientFactory;
|
||||||
private LinkedHashMap<String, FhirVersionEnum> myIdToFhirVersion = new LinkedHashMap<String, FhirVersionEnum>();
|
private LinkedHashMap<String, FhirVersionEnum> myIdToFhirVersion = new LinkedHashMap<String, FhirVersionEnum>();
|
||||||
private LinkedHashMap<String, String> myIdToServerBase = new LinkedHashMap<String, String>();
|
private LinkedHashMap<String, String> myIdToServerBase = new LinkedHashMap<String, String>();
|
||||||
|
private LinkedHashMap<String, String> myIdToServerName = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
public ITestingUiClientFactory getClientFactory() {
|
||||||
|
return myClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getDebugTemplatesMode() {
|
public boolean getDebugTemplatesMode() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -35,6 +41,10 @@ public class TesterConfig {
|
||||||
return myIdToServerName;
|
return myIdToServerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setClientFactory(ITestingUiClientFactory theClientFactory) {
|
||||||
|
myClientFactory = theClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Required
|
@Required
|
||||||
public void setServers(List<String> theServers) {
|
public void setServers(List<String> theServers) {
|
||||||
List<String> servers = theServers;
|
List<String> servers = theServers;
|
||||||
|
|
|
@ -13,6 +13,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.client.GenericClient;
|
import ca.uhn.fhir.rest.client.GenericClient;
|
||||||
import ca.uhn.fhir.rest.client.IClientInterceptor;
|
import ca.uhn.fhir.rest.client.IClientInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.IncomingRequestAddressStrategy;
|
import ca.uhn.fhir.rest.server.IncomingRequestAddressStrategy;
|
||||||
import ca.uhn.fhir.to.Controller;
|
import ca.uhn.fhir.to.Controller;
|
||||||
|
@ -49,7 +50,9 @@ public class HomeRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retVal.contains("${serverBase}")) {
|
if (retVal.contains("${serverBase}")) {
|
||||||
String base = new IncomingRequestAddressStrategy().determineServerBase(theRequest.getServletContext(), theRequest);
|
IncomingRequestAddressStrategy strategy = new IncomingRequestAddressStrategy();
|
||||||
|
strategy.setServletPath("");
|
||||||
|
String base = strategy.determineServerBase(theRequest.getServletContext(), theRequest);
|
||||||
if (base.endsWith("/")) {
|
if (base.endsWith("/")) {
|
||||||
base = base.substring(0, base.length() - 1);
|
base = base.substring(0, base.length() - 1);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +111,8 @@ public class HomeRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericClient newClient(HttpServletRequest theRequest, FhirContext theContext, TesterConfig theConfig, Controller.CaptureInterceptor theInterceptor) {
|
public GenericClient newClient(HttpServletRequest theRequest, FhirContext theContext, TesterConfig theConfig, Controller.CaptureInterceptor theInterceptor) {
|
||||||
|
theContext.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.NEVER);
|
||||||
|
|
||||||
GenericClient retVal = (GenericClient) theContext.newRestfulGenericClient(getServerBase(theRequest, theConfig));
|
GenericClient retVal = (GenericClient) theContext.newRestfulGenericClient(getServerBase(theRequest, theConfig));
|
||||||
retVal.setKeepResponses(true);
|
retVal.setKeepResponses(true);
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,8 @@
|
||||||
$('#server-history-datetime').datetimepicker({
|
$('#server-history-datetime').datetimepicker({
|
||||||
sideBySide: true,
|
sideBySide: true,
|
||||||
use24hours: true,
|
use24hours: true,
|
||||||
showToday: true
|
showToday: true,
|
||||||
|
keepInvalid: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#server-history-btn').click(
|
$('#server-history-btn').click(
|
||||||
|
|
|
@ -326,7 +326,8 @@
|
||||||
$('#resource-history-datetime').datetimepicker({
|
$('#resource-history-datetime').datetimepicker({
|
||||||
sideBySide: true,
|
sideBySide: true,
|
||||||
use24hours: true,
|
use24hours: true,
|
||||||
showToday: true
|
showToday: true,
|
||||||
|
keepInvalid: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('#resource-history-btn').click(
|
$('#resource-history-btn').click(
|
||||||
|
@ -432,7 +433,7 @@
|
||||||
if (id != null) btn.append($('<input />', { type: 'hidden', name: 'resource-create-id', value: id }));
|
if (id != null) btn.append($('<input />', { type: 'hidden', name: 'resource-create-id', value: id }));
|
||||||
var body = $('#resource-create-body').val();
|
var body = $('#resource-create-body').val();
|
||||||
btn.append($('<input />', { type: 'hidden', name: 'resource-create-body', value: body }));
|
btn.append($('<input />', { type: 'hidden', name: 'resource-create-body', value: body }));
|
||||||
$("#outerForm").attr("action", "create").submit();
|
$("#outerForm").attr("action", "create").attr("method", "POST").submit();
|
||||||
});
|
});
|
||||||
$( document ).ready(function() {
|
$( document ).ready(function() {
|
||||||
if ($('#resource-create-id').val() != "") {
|
if ($('#resource-create-id').val() != "") {
|
||||||
|
@ -498,7 +499,7 @@
|
||||||
if (id != null) btn.append($('<input />', { type: 'hidden', name: 'resource-create-id', value: id }));
|
if (id != null) btn.append($('<input />', { type: 'hidden', name: 'resource-create-id', value: id }));
|
||||||
var body = $('#resource-update-body').val();
|
var body = $('#resource-update-body').val();
|
||||||
btn.append($('<input />', { type: 'hidden', name: 'resource-create-body', value: body }));
|
btn.append($('<input />', { type: 'hidden', name: 'resource-create-body', value: body }));
|
||||||
$("#outerForm").attr("action", "update").submit();
|
$("#outerForm").attr("action", "update").attr("method", "POST").submit();
|
||||||
});
|
});
|
||||||
$( document ).ready(function() {
|
$( document ).ready(function() {
|
||||||
if ($('#resource-update-id').val() != "") {
|
if ($('#resource-update-id').val() != "") {
|
||||||
|
@ -549,7 +550,7 @@
|
||||||
btn.button('loading');
|
btn.button('loading');
|
||||||
var body = $('#resource-validate-body').val();
|
var body = $('#resource-validate-body').val();
|
||||||
btn.append($('<input />', { type: 'hidden', name: 'resource-validate-body', value: body }));
|
btn.append($('<input />', { type: 'hidden', name: 'resource-validate-body', value: body }));
|
||||||
$("#outerForm").attr("action", "validate").submit();
|
$("#outerForm").attr("action", "validate").attr("method", "POST").submit();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -145,6 +145,7 @@ PRE.resultBodyPre {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
/*white-space: normal;*/
|
/*white-space: normal;*/
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class OverlayTestApp {
|
||||||
client.create(p1);
|
client.create(p1);
|
||||||
|
|
||||||
List<IResource> resources = restServerDstu1.getFhirContext().newJsonParser().parseBundle(IOUtils.toString(OverlayTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources();
|
List<IResource> resources = restServerDstu1.getFhirContext().newJsonParser().parseBundle(IOUtils.toString(OverlayTestApp.class.getResourceAsStream("/test-server-seed-bundle.json"))).toListOfResources();
|
||||||
client.transaction(resources);
|
client.transaction().withResources(resources).execute();
|
||||||
|
|
||||||
client.create(p1);
|
client.create(p1);
|
||||||
client.create(p1);
|
client.create(p1);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue