This commit is contained in:
Tahura Chaudhry 2014-11-19 14:22:35 -05:00
commit c95af615f1
25 changed files with 1032 additions and 276 deletions

View File

@ -117,7 +117,13 @@ public class Bundle extends BaseBundle /* implements IElement */{
entry.getTitle().setValue(def.getName() + " " + StringUtils.defaultString(theResource.getId().getValue(), "(no ID)"));
}
if (theResource.getId() != null && StringUtils.isNotBlank(theResource.getId().getValue())) {
if (theResource.getId() != null) {
if (theResource.getId().isAbsolute()) {
entry.getLinkSelf().setValue(theResource.getId().getValue());
entry.getId().setValue(theResource.getId().toVersionless().getValue());
} else if (StringUtils.isNotBlank(theResource.getId().getValue())) {
StringBuilder b = new StringBuilder();
b.append(theServerBase);
@ -168,6 +174,7 @@ public class Bundle extends BaseBundle /* implements IElement */{
}
}
}
InstantDt published = ResourceMetadataKeyEnum.PUBLISHED.get(theResource);
if (published == null) {

View File

@ -22,11 +22,23 @@ package ca.uhn.fhir.model.api;
import java.util.Map;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu.composite.ContainedDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.IdDt;
/**
* This interface is the parent interface for all FHIR Resource definition
* classes. Classes implementing this interface should be annotated
* with the {@link ResourceDef @ResourceDef} annotation.
*
* <p>
* Note that this class is a part of HAPI's model API, used to define
* structure classes. Users will often interact with this interface, but
* should not need to implement it directly.
* <p>
*/
public interface IResource extends ICompositeElement {
/**
@ -113,8 +125,11 @@ public interface IResource extends ICompositeElement {
void setResourceMetadata(Map<ResourceMetadataKeyEnum<?>, Object> theMap);
/**
* Returns a String representing the name of this Resource
* @return the name of this Resource
* Returns a String representing the name of this Resource. This return
* value is not used for anything by HAPI itself, but is provided as a
* convenience to developers using the API.
*
* @return the name of this resource, e.g. "Patient", or "Observation"
*/
String getResourceName();

View File

@ -138,14 +138,22 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
/**
* Gets the precision for this datatype using field values from {@link Calendar}, such as {@link Calendar#MONTH}. Default is {@link Calendar#DAY_OF_MONTH}
* Gets the precision for this datatype (using the default for the given type if not set)
*
* @see #setPrecision(int)
* @see #setPrecision(TemporalPrecisionEnum)
*/
public TemporalPrecisionEnum getPrecision() {
if (myPrecision == null) {
return getDefaultPrecisionForDatatype();
}
return myPrecision;
}
/**
* Returns the default precision for the given datatype
*/
protected abstract TemporalPrecisionEnum getDefaultPrecisionForDatatype();
/**
* Returns the TimeZone associated with this dateTime's value. May return
* <code>null</code> if no timezone was supplied.
@ -337,11 +345,24 @@ public abstract class BaseDateTimeDt extends BasePrimitive<Date> {
}
@Override
public void setValue(Date theValue) throws DataFormatException {
public void setValue(Date theValue) {
clearTimeZone();
super.setValue(theValue);
}
/**
* Sets the value of this date/time using the specified level of precision
*
* @param theValue The date value
* @param thePrecision The precision
* @throws DataFormatException
*/
public void setValue(Date theValue, TemporalPrecisionEnum thePrecision) throws DataFormatException {
clearTimeZone();
super.setValue(theValue);
myPrecision = thePrecision;
}
@Override
public void setValueAsString(String theValue) throws DataFormatException {
clearTimeZone();

View File

@ -47,6 +47,7 @@ public class DateDt extends BaseDateTimeDt {
@SimpleSetter(suffix="WithDayPrecision")
public DateDt(@SimpleSetter.Parameter(name = "theDate") Date theDate) {
setValue(theDate);
setPrecision(DEFAULT_PRECISION);
}
/**
@ -75,4 +76,14 @@ public class DateDt extends BaseDateTimeDt {
}
}
/**
* Returns the default precision for this datatype
*
* @see #DEFAULT_PRECISION
*/
@Override
protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
return DEFAULT_PRECISION;
}
}

View File

@ -98,4 +98,15 @@ public class DateTimeDt extends BaseDateTimeDt {
return new DateTimeDt(new Date(), TemporalPrecisionEnum.SECOND);
}
/**
* Returns the default precision for this datatype
*
* @see #DEFAULT_PRECISION
*/
@Override
protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
return DEFAULT_PRECISION;
}
}

View File

@ -160,4 +160,15 @@ public class InstantDt extends BaseDateTimeDt {
return new InstantDt(new Date(), TemporalPrecisionEnum.MILLI);
}
/**
* Returns the default precision for this datatype
*
* @see #DEFAULT_PRECISION
*/
@Override
protected TemporalPrecisionEnum getDefaultPrecisionForDatatype() {
return DEFAULT_PRECISION;
}
}

View File

@ -511,6 +511,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
return resp;
}
protected EncodingEnum getParamEncoding() {
return myParamEncoding;
}
protected IResource parseResourceBody(String theResourceBody) {
EncodingEnum encoding = null;
for (int i = 0; i < theResourceBody.length() && encoding == null; i++) {
@ -571,6 +575,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
myId = getPreferredId(myResource, myId);
// If an explicit encoding is chosen, we will re-serialize to ensure the right encoding
if (getParamEncoding() != null) {
myResourceBody = null;
}
BaseHttpClientInvocation invocation = MethodUtil.createCreateInvocation(myResource, myResourceBody, myId, myContext);
RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource);
@ -1102,6 +1111,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
throw new InvalidRequestException("No ID supplied for resource to update, can not invoke server");
}
// If an explicit encoding is chosen, we will re-serialize to ensure the right encoding
if (getParamEncoding() != null) {
myResourceBody = null;
}
BaseHttpClientInvocation invocation = MethodUtil.createUpdateInvocation(myResource, myResourceBody, myId, myContext);
RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource);

View File

@ -31,4 +31,9 @@ public interface ITransaction {
ITransactionTyped<Bundle> withBundle(Bundle theResources);
// *****
// TODO: add withString version
// If we add a withString version, make sure to auto-detect content type!
// *****
}

View File

@ -44,6 +44,7 @@ import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -165,6 +166,10 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
EncodingEnum encoding = null;
encoding = theEncoding;
if (myContents != null) {
encoding = MethodUtil.detectEncoding(myContents);
}
if (encoding == EncodingEnum.JSON) {
parser = myContext.newJsonParser();
} else {
@ -174,6 +179,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
AbstractHttpEntity entity;
if (myParams != null) {
contentType= null;
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
for (Entry<String, List<String>> nextParam : myParams.entrySet()) {
List<String> value = nextParam.getValue();
@ -215,7 +221,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
HttpRequestBase retVal = createRequest(url, entity);
super.addHeadersToRequest(retVal);
// retVal.addHeader(Constants.HEADER_CONTENT_TYPE, con);
if (contentType != null) {
retVal.addHeader(Constants.HEADER_CONTENT_TYPE, contentType);
}
return retVal;
}

View File

@ -115,6 +115,7 @@ public class MethodUtil {
}
addTagsToPostOrPut(theResource, retVal);
// addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody);
return retVal;
}
@ -260,9 +261,23 @@ public class MethodUtil {
}
addTagsToPostOrPut(theResource, retVal);
// addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody);
return retVal;
}
public static EncodingEnum detectEncoding(String theBody) {
for (int i = 0; i < theBody.length(); i++) {
switch (theBody.charAt(i)) {
case '<':
return EncodingEnum.XML;
case '{':
return EncodingEnum.JSON;
}
}
return EncodingEnum.XML;
}
public static HttpGetClientInvocation createConformanceInvocation() {
return new HttpGetClientInvocation("metadata");
}

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Collection;
@ -79,6 +80,7 @@ import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
import ca.uhn.fhir.model.primitive.BaseDateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.parser.IParser;
@ -306,21 +308,22 @@ public abstract class BaseFhirDao implements IDao {
ArrayList<ResourceLink> retVal = new ArrayList<ResourceLink>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
FhirTerser t = getContext().newTerser();
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
if (nextSpDef.getParamType() != SearchParamTypeEnum.REFERENCE) {
continue;
}
String nextPath = nextSpDef.getPath();
String nextPathsUnsplit = nextSpDef.getPath();
if (isBlank(nextPathsUnsplit)) {
continue;
}
boolean multiType = false;
if (nextPath.endsWith("[x]")) {
if (nextPathsUnsplit.endsWith("[x]")) {
multiType = true;
}
List<Object> values = t.getValues(theResource, nextPath);
for (Object nextObject : values) {
for (Object nextObject : extractValues(nextPathsUnsplit, theResource)) {
if (nextObject == null) {
continue;
}
@ -338,7 +341,7 @@ public abstract class BaseFhirDao implements IDao {
String typeString = nextValue.getReference().getResourceType();
if (isBlank(typeString)) {
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPath + "] - Does not contain resource type - " + nextValue.getReference().getValue());
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue());
}
Class<? extends IResource> type = getContext().getResourceDefinition(typeString).getImplementingClass();
String id = nextValue.getReference().getIdPart();
@ -355,14 +358,14 @@ public abstract class BaseFhirDao implements IDao {
valueOf = translateForcedIdToPid(nextValue.getReference());
} catch (Exception e) {
String resName = getContext().getResourceDefinition(type).getName();
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPath + " (this is an invalid ID, must be numeric on this server)");
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit + " (this is an invalid ID, must be numeric on this server)");
}
ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf);
if (target == null) {
String resName = getContext().getResourceDefinition(type).getName();
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPath);
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
}
nextEntity = new ResourceLink(nextPath, theEntity, target);
nextEntity = new ResourceLink(nextPathsUnsplit, theEntity, target);
} else {
if (!multiType) {
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
@ -381,25 +384,42 @@ public abstract class BaseFhirDao implements IDao {
return retVal;
}
private List<Object> extractValues(String thePaths, IResource theResource) {
List<Object> values = new ArrayList<Object>();
String[] nextPathsSplit = thePaths.split("\\|");
FhirTerser t = getContext().newTerser();
for (String nextPath : nextPathsSplit) {
String nextPathTrimmed = nextPath.trim();
try {
values.addAll(t.getValues(theResource, nextPathTrimmed));
} catch (Exception e) {
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", nextPathTrimmed, def.getName(), e.toString());
}
}
return values;
}
protected List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamDate> retVal = new ArrayList<ResourceIndexedSearchParamDate>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
FhirTerser t = getContext().newTerser();
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
if (nextSpDef.getParamType() != SearchParamTypeEnum.DATE) {
continue;
}
String nextPath = nextSpDef.getPath();
if (isBlank(nextPath)) {
continue;
}
boolean multiType = false;
if (nextPath.endsWith("[x]")) {
multiType = true;
}
List<Object> values = t.getValues(theResource, nextPath);
for (Object nextObject : values) {
for (Object nextObject : extractValues(nextPath, theResource)) {
if (nextObject == null) {
continue;
}
@ -440,15 +460,17 @@ public abstract class BaseFhirDao implements IDao {
ArrayList<ResourceIndexedSearchParamNumber> retVal = new ArrayList<ResourceIndexedSearchParamNumber>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
FhirTerser t = getContext().newTerser();
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
if (nextSpDef.getParamType() != SearchParamTypeEnum.NUMBER) {
continue;
}
String nextPath = nextSpDef.getPath();
List<Object> values = t.getValues(theResource, nextPath);
for (Object nextObject : values) {
if (isBlank(nextPath)) {
continue;
}
for (Object nextObject : extractValues(nextPath, theResource)) {
if (nextObject == null || ((IDatatype) nextObject).isEmpty()) {
continue;
}
@ -500,6 +522,15 @@ public abstract class BaseFhirDao implements IDao {
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(resourceName, nextValue.getValue().getValue());
nextEntity.setResource(theEntity);
retVal.add(nextEntity);
} else if (nextObject instanceof IntegerDt) {
IntegerDt nextValue = (IntegerDt) nextObject;
if (nextValue.getValue()==null) {
continue;
}
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(resourceName, new BigDecimal(nextValue.getValue()));
nextEntity.setResource(theEntity);
retVal.add(nextEntity);
} else {
if (!multiType) {
throw new ConfigurationException("Search param " + resourceName + " is of unexpected datatype: " + nextObject.getClass());
@ -519,15 +550,17 @@ public abstract class BaseFhirDao implements IDao {
ArrayList<ResourceIndexedSearchParamQuantity> retVal = new ArrayList<ResourceIndexedSearchParamQuantity>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
FhirTerser t = getContext().newTerser();
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
if (nextSpDef.getParamType() != SearchParamTypeEnum.QUANTITY) {
continue;
}
String nextPath = nextSpDef.getPath();
List<Object> values = t.getValues(theResource, nextPath);
for (Object nextObject : values) {
if (isBlank(nextPath)) {
continue;
}
for (Object nextObject : extractValues(nextPath, theResource)) {
if (nextObject == null || ((IDatatype) nextObject).isEmpty()) {
continue;
}
@ -567,19 +600,18 @@ public abstract class BaseFhirDao implements IDao {
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
FhirTerser t = getContext().newTerser();
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
if (nextSpDef.getParamType() != SearchParamTypeEnum.STRING) {
continue;
}
if (nextSpDef.getPath().isEmpty()) {
continue; // TODO: implement phoenetic, and any others that have
// no path
}
String nextPath = nextSpDef.getPath();
List<Object> values = t.getValues(theResource, nextPath);
for (Object nextObject : values) {
if (isBlank(nextPath)) {
// TODO: implement phoenetic, and any others that have no path
continue;
}
for (Object nextObject : extractValues(nextPath, theResource)) {
if (nextObject == null || ((IDatatype) nextObject).isEmpty()) {
continue;
}
@ -656,14 +688,13 @@ public abstract class BaseFhirDao implements IDao {
ArrayList<BaseResourceIndexedSearchParam> retVal = new ArrayList<BaseResourceIndexedSearchParam>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
FhirTerser t = getContext().newTerser();
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
if (nextSpDef.getParamType() != SearchParamTypeEnum.TOKEN) {
continue;
}
String nextPath = nextSpDef.getPath();
if (nextPath.isEmpty()) {
if (isBlank(nextPath)) {
continue;
}
@ -672,10 +703,10 @@ public abstract class BaseFhirDao implements IDao {
multiType = true;
}
List<Object> values = t.getValues(theResource, nextPath);
List<String> systems = new ArrayList<String>();
List<String> codes = new ArrayList<String>();
for (Object nextObject : values) {
for (Object nextObject : extractValues(nextPath, theResource)) {
if (nextObject instanceof IdentifierDt) {
IdentifierDt nextValue = (IdentifierDt) nextObject;
if (nextValue.isEmpty()) {

View File

@ -138,8 +138,12 @@
<packageBase>ca.uhn.test.jpasrv</packageBase>
<baseResourceNames>
<baseResourceName>device</baseResourceName>
<baseResourceName>documentmanifest</baseResourceName>
<baseResourceName>documentreference</baseResourceName>
<baseResourceName>encounter</baseResourceName>
<baseResourceName>diagnosticorder</baseResourceName>
<baseResourceName>diagnosticreport</baseResourceName>
<baseResourceName>imagingstudy</baseResourceName>
<baseResourceName>location</baseResourceName>
<baseResourceName>observation</baseResourceName>
<baseResourceName>organization</baseResourceName>

View File

@ -24,6 +24,9 @@
<bean id="myDiagnosticReportDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.DiagnosticReport"/>
</bean>
<bean id="myImagingStudyDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.ImagingStudy"/>
</bean>
<bean id="myLocationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Location"/>
</bean>
@ -43,6 +46,17 @@
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Encounter"/>
</bean>
<bean id="myDiagnosticOrderDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.DiagnosticOrder"/>
</bean>
<bean id="myDocumentManifestDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.DocumentManifest"/>
</bean>
<bean id="myDocumentReferenceDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.DocumentReference"/>
</bean>
<bean id="myPersistenceDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true">
<property name="url" value="jdbc:derby:memory:myUnitTestDB;create=true" />
<!-- <property name="url" value="jdbc:derby:directory:myUnitTestDB;create=true" /> -->

View File

@ -5,6 +5,7 @@ import static org.junit.Assert.*;
import java.util.Date;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
@ -22,7 +23,11 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.composite.PeriodDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.DiagnosticOrder;
import ca.uhn.fhir.model.dstu.resource.DocumentManifest;
import ca.uhn.fhir.model.dstu.resource.DocumentReference;
import ca.uhn.fhir.model.dstu.resource.Encounter;
import ca.uhn.fhir.model.dstu.resource.ImagingStudy;
import ca.uhn.fhir.model.dstu.resource.Location;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Organization;
@ -41,7 +46,11 @@ import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.test.jpasrv.DiagnosticOrderResourceProvider;
import ca.uhn.test.jpasrv.DocumentManifestResourceProvider;
import ca.uhn.test.jpasrv.DocumentReferenceResourceProvider;
import ca.uhn.test.jpasrv.EncounterResourceProvider;
import ca.uhn.test.jpasrv.ImagingStudyResourceProvider;
import ca.uhn.test.jpasrv.LocationResourceProvider;
import ca.uhn.test.jpasrv.ObservationResourceProvider;
import ca.uhn.test.jpasrv.OrganizationResourceProvider;
@ -49,56 +58,106 @@ import ca.uhn.test.jpasrv.PatientResourceProvider;
public class CompleteResourceProviderTest {
private static IFhirResourceDao<Observation> observationDao;
private static ClassPathXmlApplicationContext ourAppCtx;
private static IGenericClient ourClient;
private static FhirContext ourCtx;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CompleteResourceProviderTest.class);
private static IFhirResourceDao<Observation> ourObservationDao;
private static IFhirResourceDao<Patient> ourPatientDao;
private static IFhirResourceDao<Questionnaire> ourQuestionnaireDao;
private static Server ourServer;
private static IFhirResourceDao<Patient> patientDao;
// private static JpaConformanceProvider ourConfProvider;
// @Test
// public void test01UploadTestResources() throws Exception {
//
// IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:8888/fhir/context");
//
// File[] files = new File("src/test/resources/resources").listFiles(new PatternFilenameFilter(".*patient.*"));
// for (File file : files) {
// ourLog.info("Uploading: {}", file);
// Patient patient = ourCtx.newXmlParser().parseResource(Patient.class, new FileReader(file));
// client.create(patient);
// }
//
// files = new File("src/test/resources/resources").listFiles(new PatternFilenameFilter(".*questionnaire.*"));
// for (File file : files) {
// ourLog.info("Uploading: {}", file);
// Questionnaire patient = ourCtx.newXmlParser().parseResource(Questionnaire.class, new FileReader(file));
// client.create(patient);
// }
//
// }
private static IFhirResourceDao<Questionnaire> questionnaireDao;
/**
* See issue #52
*/
@Test
public void testUpdateWithClientSuppliedIdWhichDoesntExist() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExist");
public void testImagingStudyResources() throws Exception {
IGenericClient client = ourClient;
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExist");
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExist").execute();
assertEquals(true, outcome.getCreated().booleanValue());
IdDt p1Id = outcome.getId();
int initialSize = client.search().forResource(ImagingStudy.class).execute().size();
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExist/_history"));
String resBody = IOUtils.toString(CompleteResourceProviderTest.class.getResource("/imagingstudy.json"));
client.create().resource(resBody).execute();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExist")).encodedJson().prettyPrint().execute();
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
int newSize = client.search().forResource(ImagingStudy.class).execute().size();
assertEquals(1, newSize - initialSize);
}
/**
* See issue #52
*/
@Test
public void testDocumentManifestResources() throws Exception {
IGenericClient client = ourClient;
int initialSize = client.search().forResource(DocumentManifest.class).execute().size();
String resBody = IOUtils.toString(CompleteResourceProviderTest.class.getResource("/documentmanifest.json"));
client.create().resource(resBody).execute();
int newSize = client.search().forResource(DocumentManifest.class).execute().size();
assertEquals(1, newSize - initialSize);
}
/**
* See issue #52
*/
@Test
public void testDocumentReferenceResources() throws Exception {
IGenericClient client = ourClient;
int initialSize = client.search().forResource(DocumentReference.class).execute().size();
String resBody = IOUtils.toString(CompleteResourceProviderTest.class.getResource("/documentreference.json"));
client.create().resource(resBody).execute();
int newSize = client.search().forResource(DocumentReference.class).execute().size();
assertEquals(1, newSize - initialSize);
}
/**
* See issue #52
*/
@Test
public void testDiagnosticOrderResources() throws Exception {
IGenericClient client = ourClient;
int initialSize = client.search().forResource(DiagnosticOrder.class).execute().size();
DiagnosticOrder res = new DiagnosticOrder();
res.addIdentifier("urn:foo", "123");
client.create().resource(res).execute();
int newSize = client.search().forResource(DiagnosticOrder.class).execute().size();
assertEquals(1, newSize - initialSize);
}
private void delete(String theResourceType, String theParamName, String theParamValue) {
Bundle resources = ourClient.search().forResource(theResourceType).where(new StringClientParam(theParamName).matches().value(theParamValue)).execute();
for (IResource next : resources.toListOfResources()) {
ourLog.info("Deleting resource: {}", next.getId());
ourClient.delete().resource(next).execute();
}
}
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) {
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
for (IResource next : resources.toListOfResources()) {
ourLog.info("Deleting resource: {}", next.getId());
ourClient.delete().resource(next).execute();
}
}
@Test
@ -130,134 +189,6 @@ public class CompleteResourceProviderTest {
assertNotNull(history.getEntries().get(0).getResource());
}
@Test
public void testTryToCreateResourceWithReferenceThatDoesntExist() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01");
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testTryToCreateResourceWithReferenceThatDoesntExist01");
p1.addName().addFamily("testTryToCreateResourceWithReferenceThatDoesntExistFamily01").addGiven("testTryToCreateResourceWithReferenceThatDoesntExistGiven01");
p1.setManagingOrganization(new ResourceReferenceDt("Organization/1323123232349875324987529835"));
try {
ourClient.create(p1).getId();
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Organization/1323123232349875324987529835"));
}
}
@Test
public void testSaveAndRetrieveExistingNarrative() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01");
Patient p1 = new Patient();
p1.getText().setStatus(NarrativeStatusEnum.GENERATED);
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
IdDt newId = ourClient.create(p1).getId();
Patient actual = ourClient.read(Patient.class, newId);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@Test
public void testSaveAndRetrieveWithoutNarrative() {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
IdDt newId = ourClient.create(p1).getId();
Patient actual = ourClient.read(Patient.class, newId);
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
}
@Test
public void testSaveAndRetrieveWithContained() {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained01");
Organization o1 = new Organization();
o1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained02");
p1.getManagingOrganization().setResource(o1);
IdDt newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
assertEquals(1, actual.getContained().getContainedResources().size());
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
Bundle b = ourClient.search().forResource("Patient").where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system","testSaveAndRetrieveWithContained01")).execute();
assertEquals(1, b.size());
}
@Test
public void testSearchByIdentifier() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01");
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier02");
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
IdDt p1Id = ourClient.create(p1).getId();
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
p2.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven02");
ourClient.create(p2).getId();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testSearchByIdentifier01")).encodedJson().prettyPrint().execute();
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
}
@Test
public void testSearchByIdentifierWithoutSystem() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "", "testSearchByIdentifierWithoutSystem01");
Patient p1 = new Patient();
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
IdDt p1Id = ourClient.create(p1).getId();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
}
@Test
public void testUpdateRejectsInvalidTypes() throws InterruptedException {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateRejectsInvalidTypes");
Patient p1 = new Patient();
p1.addIdentifier("urn:system", "testUpdateRejectsInvalidTypes");
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
IdDt p1id = ourClient.create().resource(p1).execute().getId();
Organization p2 = new Organization();
p2.getName().setValue("testUpdateRejectsInvalidTypes");
try {
ourClient.update().resource(p2).withId("Organization/" + p1id.getIdPart()).execute();
fail();
} catch (UnprocessableEntityException e) {
// good
}
try {
ourClient.update().resource(p2).withId("Patient/" + p1id.getIdPart()).execute();
fail();
} catch (UnprocessableEntityException e) {
// good
}
}
@Test
public void testDeepChaining() {
delete("Location", Location.SP_NAME, "testDeepChainingL1");
@ -297,20 +228,86 @@ public class CompleteResourceProviderTest {
}
private void delete(String theResourceType, String theParamName, String theParamValue) {
Bundle resources = ourClient.search().forResource(theResourceType).where(new StringClientParam(theParamName).matches().value(theParamValue)).execute();
for (IResource next : resources.toListOfResources()) {
ourLog.info("Deleting resource: {}", next.getId());
ourClient.delete().resource(next).execute();
}
@Test
public void testSaveAndRetrieveExistingNarrative() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSaveAndRetrieveExistingNarrative01");
Patient p1 = new Patient();
p1.getText().setStatus(NarrativeStatusEnum.GENERATED);
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
IdDt newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) {
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
for (IResource next : resources.toListOfResources()) {
ourLog.info("Deleting resource: {}", next.getId());
ourClient.delete().resource(next).execute();
@Test
public void testSaveAndRetrieveWithContained() {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained01");
Organization o1 = new Organization();
o1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveWithContained02");
p1.getManagingOrganization().setResource(o1);
IdDt newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
assertEquals(1, actual.getContained().getContainedResources().size());
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
Bundle b = ourClient.search().forResource("Patient").where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testSaveAndRetrieveWithContained01")).execute();
assertEquals(1, b.size());
}
@Test
public void testSaveAndRetrieveWithoutNarrative() {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
IdDt newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
}
@Test
public void testSearchByIdentifier() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier01");
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testSearchByIdentifier02");
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
p2.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven02");
ourClient.create().resource(p2).execute().getId();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testSearchByIdentifier01")).encodedJson().prettyPrint().execute();
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
}
@Test
public void testSearchByIdentifierWithoutSystem() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "", "testSearchByIdentifierWithoutSystem01");
Patient p1 = new Patient();
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
.execute();
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
}
@Test
@ -320,19 +317,19 @@ public class CompleteResourceProviderTest {
Organization o1 = new Organization();
o1.setName("testSearchByResourceChainName01");
IdDt o1id = ourClient.create(o1).getId();
IdDt o1id = ourClient.create().resource(o1).execute().getId();
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
IdDt p1Id = ourClient.create(p1).getId();
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
//@formatter:off
Bundle actual = ourClient.search()
.forResource(Patient.class)
.where(Patient.PROVIDER.hasId(o1id.getIdPart()))
.encodedJson().andLogRequestAndResponse(true).prettyPrint().execute();
.encodedJson().prettyPrint().execute();
//@formatter:on
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
@ -341,13 +338,77 @@ public class CompleteResourceProviderTest {
actual = ourClient.search()
.forResource(Patient.class)
.where(Patient.PROVIDER.hasId(o1id.getValue()))
.encodedJson().andLogRequestAndResponse(true).prettyPrint().execute();
.encodedJson().prettyPrint().execute();
//@formatter:on
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
}
@Test
public void testTryToCreateResourceWithReferenceThatDoesntExist() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testTryToCreateResourceWithReferenceThatDoesntExist01");
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testTryToCreateResourceWithReferenceThatDoesntExist01");
p1.addName().addFamily("testTryToCreateResourceWithReferenceThatDoesntExistFamily01").addGiven("testTryToCreateResourceWithReferenceThatDoesntExistGiven01");
p1.setManagingOrganization(new ResourceReferenceDt("Organization/1323123232349875324987529835"));
try {
ourClient.create().resource(p1).execute().getId();
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Organization/1323123232349875324987529835"));
}
}
@Test
public void testUpdateRejectsInvalidTypes() throws InterruptedException {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateRejectsInvalidTypes");
Patient p1 = new Patient();
p1.addIdentifier("urn:system", "testUpdateRejectsInvalidTypes");
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
IdDt p1id = ourClient.create().resource(p1).execute().getId();
Organization p2 = new Organization();
p2.getName().setValue("testUpdateRejectsInvalidTypes");
try {
ourClient.update().resource(p2).withId("Organization/" + p1id.getIdPart()).execute();
fail();
} catch (UnprocessableEntityException e) {
// good
}
try {
ourClient.update().resource(p2).withId("Patient/" + p1id.getIdPart()).execute();
fail();
} catch (UnprocessableEntityException e) {
// good
}
}
@Test
public void testUpdateWithClientSuppliedIdWhichDoesntExist() {
deleteToken("Patient", Patient.SP_IDENTIFIER, "urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExist");
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExist");
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExist").execute();
assertEquals(true, outcome.getCreated().booleanValue());
IdDt p1Id = outcome.getId();
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExist/_history"));
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", "testUpdateWithClientSuppliedIdWhichDoesntExist")).encodedJson()
.prettyPrint().execute();
assertEquals(1, actual.size());
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
@ -364,17 +425,17 @@ public class CompleteResourceProviderTest {
if (true) {
ourAppCtx = new ClassPathXmlApplicationContext("fhir-spring-test-config.xml");
patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDao", IFhirResourceDao.class);
ourPatientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDao", IFhirResourceDao.class);
PatientResourceProvider patientRp = new PatientResourceProvider();
patientRp.setDao(patientDao);
patientRp.setDao(ourPatientDao);
questionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDao", IFhirResourceDao.class);
ourQuestionnaireDao = (IFhirResourceDao<Questionnaire>) ourAppCtx.getBean("myQuestionnaireDao", IFhirResourceDao.class);
QuestionnaireResourceProvider questionnaireRp = new QuestionnaireResourceProvider();
questionnaireRp.setDao(questionnaireDao);
questionnaireRp.setDao(ourQuestionnaireDao);
observationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDao", IFhirResourceDao.class);
ourObservationDao = (IFhirResourceDao<Observation>) ourAppCtx.getBean("myObservationDao", IFhirResourceDao.class);
ObservationResourceProvider observationRp = new ObservationResourceProvider();
observationRp.setDao(observationDao);
observationRp.setDao(ourObservationDao);
IFhirResourceDao<Location> locationDao = (IFhirResourceDao<Location>) ourAppCtx.getBean("myLocationDao", IFhirResourceDao.class);
LocationResourceProvider locationRp = new LocationResourceProvider();
@ -388,7 +449,23 @@ public class CompleteResourceProviderTest {
OrganizationResourceProvider organizationRp = new OrganizationResourceProvider();
organizationRp.setDao(organizationDao);
restServer.setResourceProviders(encounterRp, locationRp, patientRp, questionnaireRp, observationRp, organizationRp);
IFhirResourceDao<ImagingStudy> imagingStudyDao = (IFhirResourceDao<ImagingStudy>) ourAppCtx.getBean("myImagingStudyDao", IFhirResourceDao.class);
ImagingStudyResourceProvider imagingStudyRp = new ImagingStudyResourceProvider();
imagingStudyRp.setDao(imagingStudyDao);
IFhirResourceDao<DiagnosticOrder> diagnosticOrderDao =ourAppCtx.getBean("myDiagnosticOrderDao", IFhirResourceDao.class);
DiagnosticOrderResourceProvider diagnosticOrderRp = new DiagnosticOrderResourceProvider();
diagnosticOrderRp.setDao(diagnosticOrderDao);
IFhirResourceDao<DocumentManifest> documentManifestDao =ourAppCtx.getBean("myDocumentManifestDao", IFhirResourceDao.class);
DocumentManifestResourceProvider documentManifestRp = new DocumentManifestResourceProvider();
documentManifestRp.setDao(documentManifestDao);
IFhirResourceDao<DocumentReference> documentReferenceDao =ourAppCtx.getBean("myDocumentReferenceDao", IFhirResourceDao.class);
DocumentReferenceResourceProvider documentReferenceRp = new DocumentReferenceResourceProvider();
documentReferenceRp.setDao(documentReferenceDao);
restServer.setResourceProviders(diagnosticOrderRp, documentManifestRp, documentReferenceRp, encounterRp, locationRp, patientRp, questionnaireRp, observationRp, organizationRp, imagingStudyRp);
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
IFhirSystemDao systemDao = (IFhirSystemDao) ourAppCtx.getBean("mySystemDao", IFhirSystemDao.class);
@ -414,7 +491,7 @@ public class CompleteResourceProviderTest {
}
ourCtx = restServer.getFhirContext();
// ourCtx.getRestfulClientFactory().setProxy("localhost", 8888);
// ourCtx.getRestfulClientFactory().setProxy("localhost", 8888);
ourClient = ourCtx.newRestfulGenericClient(serverBase);
// ourClient = ourCtx.newRestfulGenericClient("http://fhir.healthintersections.com.au/open");

View File

@ -0,0 +1,60 @@
{
"resourceType" : "DocumentManifest",
"text" : {
"status" : "generated",
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\">Text</div>"
},
"contained" : [
{
"resourceType" : "Practitioner",
"id" : "a1",
"name" : {
"family" : [
"Dopplemeyer"
],
"given" : [
"Sherry"
]
},
"telecom" : [
{
"system" : "email",
"value" : "john.doe@healthcare.example.org"
}
],
"organization" : {
"display" : "Cleveland Clinic"
},
"role" : [
{
"text" : "Primary Surgon"
}
],
"specialty" : [
{
"text" : "Orthopedic"
}
]
}
],
"masterIdentifier" : {
"system" : "http://example.org/documents",
"value" : "23425234234-2346"
},
"subject" : [
],
"type" : {
"text" : "History and Physical"
},
"author" : [
{
"reference" : "#a1"
}
],
"created" : "2004-12-25T23:50:50",
"source" : "urn:oid:1.3.6.1.4.1.21367.2009.1.2.1",
"status" : "current",
"description" : "Physical",
"content" : [
]
}

View File

@ -0,0 +1,140 @@
{
"resourceType" : "DocumentReference",
"text" : {
"status" : "generated",
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\">&#xA; <p>&#xA; <b>Generated Narrative</b>&#xA; </p>&#xA; <p>&#xA; <b>masterIdentifier</b>: urn:oid:1.3.6.1.4.1.21367.2005.3.7&#xA; </p>&#xA; <p>&#xA; <b>subject</b>: &#xA; <a href=\"Patient/xcda\">MRN = 12345 (usual); Henry Levin ; Male; birthDate: 24-Sep 1932; active</a>&#xA; </p>&#xA; <p>&#xA; <b>type</b>: &#xA; <span title=\"Codes: {http://loinc.org 34108-1}\">Outpatient Note</span>&#xA; </p>&#xA; <p>&#xA; <b>author</b>: Sherry Dopplemeyer ; Primary Surgon; Orthopedic, Gerald Smitty ; Attending; Orthopedic&#xA; </p>&#xA; <p>&#xA; <b>created</b>: 24-Dec 2005 9:35&#xA; </p>&#xA; <p>&#xA; <b>indexed</b>: 24-Dec 2005 9:43&#xA; </p>&#xA; <p>&#xA; <b>status</b>: current&#xA; </p>&#xA; <p>&#xA; <b>description</b>: Physical&#xA; </p>&#xA; <p>&#xA; <b>confidentiality</b>: &#xA; <span title=\"Codes: {http://ihe.net/xds/connectathon/confidentialityCodes 1.3.6.1.4.1.21367.2006.7.101}\">Clinical-Staff</span>&#xA; </p>&#xA; <p>&#xA; <b>primaryLanguage</b>: en-US&#xA; </p>&#xA; <p>&#xA; <b>mimeType</b>: application/hl7-v3+xml&#xA; </p>&#xA; <p>&#xA; <b>size</b>: 3654&#xA; </p>&#xA; <p>&#xA; <b>hash</b>: da39a3ee5e6b4b0d3255bfef95601890afd80709&#xA; </p>&#xA; <p>&#xA; <b>location</b>: &#xA; <a href=\"http://example.org/xds/mhd/Binary/@07a6483f-732b-461e-86b6-edb665c45510\">http://example.org/xds/mhd/Binary/@07a6483f-732b-461e-86b6-edb665c45510</a>&#xA; </p>&#xA; <h3>Contexts</h3>&#xA; <table class=\"grid\">&#xA; <tr>&#xA; <td>&#xA; <b>Event</b>&#xA; </td>&#xA; <td>&#xA; <b>Period</b>&#xA; </td>&#xA; <td>&#xA; <b>FacilityType</b>&#xA; </td>&#xA; </tr>&#xA; <tr>&#xA; <td>&#xA; <span title=\"Codes: {http://ihe.net/xds/connectathon/eventCodes T-D8200}\">Arm</span>&#xA; </td>&#xA; <td>23-Dec 2004 8:0 --&gt; 23-Dec 2004 8:1</td>&#xA; <td>&#xA; <span title=\"Codes: {http://www.ihe.net/xds/connectathon/healthcareFacilityTypeCodes Outpatient}\">Outpatient</span>&#xA; </td>&#xA; </tr>&#xA; </table>&#xA; </div>"
},
"contained" : [
{
"resourceType" : "Practitioner",
"id" : "a1",
"name" : {
"family" : [
"Dopplemeyer"
],
"given" : [
"Sherry"
]
},
"telecom" : [
{
"system" : "email",
"value" : "john.doe@healthcare.example.org"
}
],
"organization" : {
"display" : "Cleveland Clinic"
},
"role" : [
{
"text" : "Primary Surgon"
}
],
"specialty" : [
{
"text" : "Orthopedic"
}
]
},
{
"resourceType" : "Practitioner",
"id" : "a2",
"name" : {
"family" : [
"Smitty"
],
"given" : [
"Gerald"
]
},
"telecom" : [
{
"system" : "email",
"value" : "john.doe@healthcare.example.org"
}
],
"organization" : {
"display" : "Cleveland Clinic"
},
"role" : [
{
"text" : "Attending"
}
],
"specialty" : [
{
"text" : "Orthopedic"
}
]
}
],
"masterIdentifier" : {
"system" : "urn:ietf:rfc:3986",
"value" : "urn:oid:1.3.6.1.4.1.21367.2005.3.7"
},
"subject" : {
},
"type" : {
"coding" : [
{
"system" : "http://loinc.org",
"code" : "34108-1",
"display" : "Outpatient Note"
}
]
},
"author" : [
{
"reference" : "#a1"
},
{
"reference" : "#a2"
}
],
"created" : "2005-12-24T09:35:00+11:00",
"indexed" : "2005-12-24T09:43:41+11:00",
"status" : "current",
"description" : "Physical",
"confidentiality" : [
{
"coding" : [
{
"system" : "http://ihe.net/xds/connectathon/confidentialityCodes",
"code" : "1.3.6.1.4.1.21367.2006.7.101",
"display" : "Clinical-Staff"
}
]
}
],
"primaryLanguage" : "en-US",
"mimeType" : "application/hl7-v3+xml",
"size" : 3654,
"hash" : "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"location" : "http://example.org/xds/mhd/Binary/@07a6483f-732b-461e-86b6-edb665c45510",
"context" : {
"event" : [
{
"coding" : [
{
"system" : "http://ihe.net/xds/connectathon/eventCodes",
"code" : "T-D8200",
"display" : "Arm"
}
]
}
],
"period" : {
"start" : "2004-12-23T08:00:00",
"end" : "2004-12-23T08:01:00"
},
"facilityType" : {
"coding" : [
{
"system" : "http://www.ihe.net/xds/connectathon/healthcareFacilityTypeCodes",
"code" : "Outpatient",
"display" : "Outpatient"
}
]
}
}
}

View File

@ -0,0 +1,2 @@
{
"resourceType" : "ImagingStudy","text" : {"status" : "generated","div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\">Image 1 from Series 3: CT Images on Patient MINT (MINT1234) taken at 1-Jan 2011 01:20 AM</div>"},"dateTime" : "2011-01-01T11:01:20","uid" : "urn:oid:2.16.124.113543.6003.1154777499.30246.19789.3503430045","numberOfSeries" : 1,"numberOfInstances" : 1,"series" : [{"number" : 3,"modality" : "CT","uid" : "urn:oid:2.16.124.113543.6003.2588828330.45298.17418.2723805630","description" : "CT Surview 180","numberOfInstances" : 1,"instance" : [{"number" : 1,"uid" : "urn:oid:2.16.124.113543.6003.189642796.63084.16748.2599092903","sopclass" : "urn:oid:1.2.840.10008.5.1.4.1.1.2","url" : "http://localhost/fhir/Binary/@1.2.840.11361907579238403408700.3.0.14.19970327150033"}]}]}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="jst.utility" version="1.0"/>
<installed facet="java" version="1.7"/>
<installed facet="java" version="1.6"/>
</faceted-project>

View File

@ -28,7 +28,7 @@
<scope>provided</scope>
</dependency>
<!-- Testing -->
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@ -303,6 +303,17 @@
</plugin>
</plugins>
</pluginManagement>
<resources>
<resource>
<directory>${baseDir}/src/main/resources</directory>
</resource>
<resource>
<directory>${baseDir}/target/generated-sources/tinder</directory>
</resource>
<resource>
<directory>${baseDir}/target/generated-resources/tinder</directory>
</resource>
</resources>
</build>
</project>

View File

@ -4,6 +4,7 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.io.IOException;
import java.io.StringReader;
import java.net.URLEncoder;
import java.nio.charset.Charset;
@ -23,6 +24,7 @@ import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine;
import org.apache.http.util.EncodingUtils;
import org.hamcrest.core.StringContains;
import org.junit.Before;
import org.junit.BeforeClass;
@ -177,11 +179,16 @@ public class GenericClientTest {
assertEquals("44", outcome.getId().getIdPart());
assertEquals("22", outcome.getId().getVersionIdPart());
int count = 0;
assertEquals("http://example.com/fhir/Patient", capt.getValue().getURI().toString());
assertEquals("POST", capt.getValue().getMethod());
Header catH = capt.getValue().getFirstHeader("Category");
assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH);
assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue());
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
count++;
/*
* Try fluent options
@ -189,13 +196,116 @@ public class GenericClientTest {
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8")));
client.create().resource(p1).withId("123").execute();
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toString());
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
count++;
String resourceText = "<Patient xmlns=\"http://hl7.org/fhir\"> </Patient>";
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8")));
client.create().resource(resourceText).withId("123").execute();
assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(2).getURI().toString());
assertEquals(resourceText, IOUtils.toString(((HttpPost) capt.getAllValues().get(2)).getEntity().getContent()));
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
count++;
}
@Test
public void testCreateWithStringAutoDetectsEncoding() throws Exception {
Patient p1 = new Patient();
p1.addIdentifier("foo:bar", "12345");
p1.addName().addFamily("Smith").addGiven("John");
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), 201, "OK"));
when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") });
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8")));
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
int count = 0;
client.create().resource(myCtx.newXmlParser().encodeResourceToString(p1)).execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("value=\"John\""));
count++;
client.create().resource(myCtx.newJsonParser().encodeResourceToString(p1)).execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.JSON.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("[\"John\"]"));
count++;
/*
* e.g. Now try with reversed encoding (provide a string that's in JSON and ask the client to use XML)
*/
client.create().resource(myCtx.newXmlParser().encodeResourceToString(p1)).encodedJson().execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.JSON.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("[\"John\"]"));
count++;
client.create().resource(myCtx.newJsonParser().encodeResourceToString(p1)).encodedXml().execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("value=\"John\""));
count++;
}
private String extractBody(ArgumentCaptor<HttpUriRequest> capt, int count) throws IOException {
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(count)).getEntity().getContent());
return body;
}
@Test
public void testUpdateWithStringAutoDetectsEncoding() throws Exception {
Patient p1 = new Patient();
p1.addIdentifier("foo:bar", "12345");
p1.addName().addFamily("Smith").addGiven("John");
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), 201, "OK"));
when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") });
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8")));
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
int count = 0;
client.update().resource(myCtx.newXmlParser().encodeResourceToString(p1)).withId("1").execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("value=\"John\""));
count++;
client.update().resource(myCtx.newJsonParser().encodeResourceToString(p1)).withId("1").execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.JSON.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("[\"John\"]"));
count++;
/*
* e.g. Now try with reversed encoding (provide a string that's in JSON and ask the client to use XML)
*/
client.update().resource(myCtx.newXmlParser().encodeResourceToString(p1)).withId("1").encodedJson().execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.JSON.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("[\"John\"]"));
count++;
client.update().resource(myCtx.newJsonParser().encodeResourceToString(p1)).withId("1").encodedXml().execute();
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
assertThat(extractBody(capt, count), containsString("value=\"John\""));
count++;
}
@Test
@ -504,7 +614,6 @@ public class GenericClientTest {
}
@Test
public void testSearchWithAbsoluteUrl() throws Exception {
@ -518,7 +627,9 @@ public class GenericClientTest {
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
Bundle response = client.search(new UriDt("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json"));
Bundle response = client
.search(new UriDt(
"http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json"));
assertEquals(
"http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json",
@ -527,7 +638,6 @@ public class GenericClientTest {
assertEquals(1, response.size());
}
@Test
public void testSearchWithAbsoluteUrlAndType() throws Exception {
@ -541,7 +651,10 @@ public class GenericClientTest {
IGenericClient client = myCtx.newRestfulGenericClient("http://example.com/fhir");
Bundle response = client.search(Patient.class, new UriDt("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json"));
Bundle response = client
.search(Patient.class,
new UriDt(
"http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json"));
assertEquals(
"http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json",
@ -975,7 +1088,12 @@ public class GenericClientTest {
p1.setId("44");
client.update().resource(p1).execute();
int count = 0;
assertEquals(1, capt.getAllValues().size());
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
count++;
MethodOutcome outcome = client.update().resource(p1).execute();
assertEquals("44", outcome.getId().getIdPart());
@ -988,6 +1106,8 @@ public class GenericClientTest {
Header catH = capt.getValue().getFirstHeader("Category");
assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH);
assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue());
assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length);
assertEquals(EncodingEnum.XML.getResourceContentType(), capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue());
/*
* Try fluent options

View File

@ -25,9 +25,11 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.resource.Organization;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.primitive.IdDt;
@ -223,6 +225,27 @@ public class ServerFeaturesTest {
}
@Test
public void testSearchReturnWithAbsoluteIdSpecified() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/?_query=findPatientsWithAbsoluteIdSpecified");
httpGet.addHeader("Accept", Constants.CT_FHIR_XML + "; pretty=true");
CloseableHttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = servlet.getFhirContext().newXmlParser().parseBundle(responseContent);
assertEquals(2,bundle.size());
assertEquals("http://absolute.com/Patient/123", bundle.getEntries().get(0).getId().getValue());
assertEquals("http://absolute.com/Patient/123/_history/22", bundle.getEntries().get(0).getLinkSelf().getValue());
assertEquals("http://foo.com/Organization/222",bundle.getEntries().get(1).getId().getValue());
assertEquals("http://foo.com/Organization/222/_history/333",bundle.getEntries().get(1).getLinkSelf().getValue());
}
@Test
public void testSearchWithWildcardRetVal() throws Exception {
@ -345,6 +368,20 @@ public class ServerFeaturesTest {
return Collections.singletonList(p);
}
@Search(queryName = "findPatientsWithAbsoluteIdSpecified")
public List<Patient> findPatientsWithAbsoluteIdSpecified() {
Patient p = new Patient();
p.addIdentifier().setSystem("foo");
p.setId("http://absolute.com/Patient/123/_history/22");
Organization o = new Organization();
o.setId("http://foo.com/Organization/222/_history/333");
p.getManagingOrganization().setResource(o);
return Collections.singletonList(p);
}
@Override
public Class<Patient> getResourceType() {
return Patient.class;

View File

@ -0,0 +1,3 @@
.classpath
.project
/target/

View File

@ -0,0 +1,91 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--
HAPI projects use the Sonatype OSS parent project.
You do not need to use this in your own projects.
-->
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<groupId>ca.uhn.hapi.example</groupId>
<artifactId>hapi-fhir-example-skeleton-project</artifactId>
<version>0.8-SNAPSHOT</version>
<packaging>jar</packaging>
<name>HAPI FHIR Example - Skeleton Project</name>
<repositories>
<repository>
<id>oss-snapshots</id>
<snapshots>
<enabled>true</enabled>
</snapshots>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<!-- This dependency includes the core HAPI-FHIR classes -->
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.8-SNAPSHOT</version>
</dependency>
<!-- At least one "structures" JAR must also be included -->
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId>
<version>0.8-SNAPSHOT</version>
</dependency>
<!--
HAPI-FHIR uses Logback for logging support. The logback library is included
automatically by Maven as a part of the hapi-fhir-base dependency, but you
also need to include a logging library. Logback is used here, but log4j
would also be fine.
-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--
Tell Maven which Java source version you want to use
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!--
This plugin is just a part of the HAPI internal build process, you do not
need to incude it in your own projects
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,24 @@
package ca.uhn.fhir.example;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.resource.Patient;
@SuppressWarnings("unused")
public class Example01_CreateAPatient {
public static void main(String[] theArgs) {
Patient pat = new Patient();
IdentifierDt identifier = pat.addIdentifier();
identifier.setSystem("http://acme.org/MRNs").setValue("7000135");
HumanNameDt name = pat.addName();
name.addFamily("Simpson").addGiven("Homer").addGiven("J");
pat.getBirthDate().set
}
}

View File

@ -102,6 +102,30 @@
invalid dates, e.g. "2001-15-01". Thanks to Joe Athman for reporting and
helping to come up with a fix!
</action>
<action type="add">
When using Generic Client, if performing a
<![CDATA[create]]> or <![CDATA[update]]> operation using a String as the resource body,
the client will auto-detect the FHIR encoding style and send an appropriate Content-Type header.
</action>
<action type="fix" issue="52">
JPA module (and public HAPI-FHIR test server) were unable to process resource types
where at least one search parameter has no path specified. These now correctly save
(although the server does not yet process these params, and it should). Thanks to
GitHub user shvoidlee for reporting and help with analysis!
</action>
<action type="fix">
Generic/Fluent Client "create" and "update" method requests were not setting a content type header
</action>
<action type="add" issue="53" dev="petromykhailysyn">
DateDt left precision value as null in the constructor
<![CDATA[DateDt(Date)]]>.
</action>
<action type="fix">
RESTful server now doesn't overwrite resource IDs if they are absolute. In other words, if
a server's Resource Provider returns a resource with ID "Patient/123" it will be translated to
"[base url]/Patient/123" but if the RP returns ID "http://foo/Patient/123" the ID will be
returned exactly as is. Thanks to Bill de Beaubien for the suggestion!
</action>
</release>
<release version="0.7" date="2014-Oct-23">
<action type="add" issue="30">