Merge branch 'master' of https://github.com/jamesagnew/hapi-fhir
This commit is contained in:
commit
ae010a4309
|
@ -224,13 +224,17 @@
|
|||
</pluginManagement>
|
||||
|
||||
<plugins>
|
||||
<!-- Tell Maven which Java source version you want to use -->
|
||||
|
||||
<!--
|
||||
The CQF-Ruler project has some OWASP dependency security failures which we don't want
|
||||
to cause the whole build to fail. TODO: investigate these
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<failBuildOnCVSS>99</failBuildOnCVSS>
|
||||
<failOnError>false</failOnError>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<url>http://jamesagnew.github.io/hapi-fhir/</url>
|
||||
|
||||
|
@ -150,6 +150,21 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Import-Package>
|
||||
<!--required when using servers-->
|
||||
ca.uhn.fhir.rest.api.server;resolution:=optional,
|
||||
ca.uhn.fhir.model.api;resolution:=optional,
|
||||
*
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
|
|
|
@ -20,9 +20,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
* 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.
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-client</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Client Framework</name>
|
||||
|
||||
|
@ -69,6 +69,18 @@
|
|||
<argLine>@{argLine} -Dfile.encoding=UTF-8 -Xmx712m</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-converter</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
@ -134,5 +134,21 @@
|
|||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Import-Package>
|
||||
ca.uhn.fhir.rest.server*;resolution:=optional,
|
||||
javax.servlet.http;resolution:=optional,
|
||||
*
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -60,6 +60,9 @@ public class DaoConfig {
|
|||
* update setter javadoc if default changes
|
||||
*/
|
||||
private boolean myAllowExternalReferences = false;
|
||||
/**
|
||||
* update setter javadoc if default changes
|
||||
*/
|
||||
private boolean myAllowContainsSearches = true;
|
||||
|
||||
/**
|
||||
|
@ -137,6 +140,7 @@ public class DaoConfig {
|
|||
myTreatReferencesAsLogical.add(theTreatReferencesAsLogical);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the highest number that a client is permitted to use in a
|
||||
* <code>Cache-Control: nostore, max-results=NNN</code>
|
||||
|
@ -376,9 +380,9 @@ public class DaoConfig {
|
|||
* of higher importance than raw write performance
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that this setting also has an impact on sorting (i.e. using the
|
||||
* <code>_sort</code> parameter on searches): If the server is configured
|
||||
* to not index missing field.
|
||||
* Note that this setting also has an impact on sorting (i.e. using the
|
||||
* <code>_sort</code> parameter on searches): If the server is configured
|
||||
* to not index missing field.
|
||||
* </p>
|
||||
*/
|
||||
public void setIndexMissingFields(IndexEnabledEnum theIndexMissingFields) {
|
||||
|
@ -650,6 +654,26 @@ public class DaoConfig {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled, the server will support the use of :contains searches,
|
||||
* which are helpful but can have adverse effects on performance.
|
||||
*
|
||||
* Default is <code>true</code>
|
||||
*/
|
||||
public boolean isAllowContainsSearches() {
|
||||
return myAllowContainsSearches;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled, the server will support the use of :contains searches,
|
||||
* which are helpful but can have adverse effects on performance.
|
||||
*
|
||||
* Default is <code>true</code>
|
||||
*/
|
||||
public void setAllowContainsSearches(boolean theAllowContainsSearches) {
|
||||
this.myAllowContainsSearches = theAllowContainsSearches;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to <code>true</code> (default is <code>false</code>) the server will allow
|
||||
* resources to have references to external servers. For example if this server is
|
||||
|
@ -1099,16 +1123,6 @@ public class DaoConfig {
|
|||
|
||||
}
|
||||
|
||||
public boolean allowContainsSearches() {
|
||||
|
||||
return myAllowContainsSearches;
|
||||
}
|
||||
|
||||
public void setAllowContainsSearches(boolean myAllowContainsSearches) {
|
||||
|
||||
this.myAllowContainsSearches = myAllowContainsSearches;
|
||||
}
|
||||
|
||||
public enum IndexEnabledEnum {
|
||||
ENABLED,
|
||||
DISABLED
|
||||
|
|
|
@ -20,29 +20,32 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
|
||||
public interface ISearchBuilder {
|
||||
|
||||
Iterator<Long> createQuery(SearchParameterMap theParams, String theSearchUuid);
|
||||
|
||||
void setType(Class<? extends IBaseResource> theResourceType, String theResourceName);
|
||||
|
||||
void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation, EntityManager theEntityManager,
|
||||
FhirContext theContext, IDao theDao);
|
||||
FhirContext theContext, IDao theDao);
|
||||
|
||||
Set<Long> loadReverseIncludes(IDao theCallingDao, FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode,
|
||||
DateRangeParam theLastUpdated);
|
||||
DateRangeParam theLastUpdated);
|
||||
|
||||
/**
|
||||
* How many results may be fetched at once
|
||||
*/
|
||||
void setFetchSize(int theFetchSize);
|
||||
|
||||
void setType(Class<? extends IBaseResource> theResourceType, String theResourceName);
|
||||
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@ import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
|
|||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||
import ca.uhn.fhir.jpa.util.BaseIterator;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
||||
|
@ -45,7 +43,9 @@ import ca.uhn.fhir.rest.api.SortSpec;
|
|||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
|
@ -59,6 +59,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.internal.SessionImpl;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hl7.fhir.dstu3.model.BaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
|
@ -104,6 +107,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
private ISearchParamRegistry mySearchParamRegistry;
|
||||
private String mySearchUuid;
|
||||
private IHapiTerminologySvc myTerminologySvc;
|
||||
private int myFetchSize;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -1091,10 +1095,10 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
} else if (theParameter instanceof StringParam) {
|
||||
StringParam id = (StringParam) theParameter;
|
||||
rawSearchTerm = id.getValue();
|
||||
if ((id.isContains()) &&
|
||||
(!myCallingDao.getConfig().allowContainsSearches()))
|
||||
{
|
||||
throw new MethodNotAllowedException(":contains modifier is disabled on this server");
|
||||
if (id.isContains()) {
|
||||
if (!myCallingDao.getConfig().isAllowContainsSearches()) {
|
||||
throw new MethodNotAllowedException(":contains modifier is disabled on this server");
|
||||
}
|
||||
}
|
||||
} else if (theParameter instanceof IPrimitiveDatatype<?>) {
|
||||
IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) theParameter;
|
||||
|
@ -1109,18 +1113,11 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
}
|
||||
|
||||
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
|
||||
if (myCallingDao.getConfig().allowContainsSearches()) {
|
||||
if (theParameter instanceof StringParam) {
|
||||
if (((StringParam) theParameter).isContains()) {
|
||||
likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
|
||||
} else {
|
||||
likeExpression = createLeftMatchLikeExpression(likeExpression);
|
||||
}
|
||||
} else {
|
||||
likeExpression = createLeftMatchLikeExpression(likeExpression);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (theParameter instanceof StringParam &&
|
||||
((StringParam) theParameter).isContains() &&
|
||||
myCallingDao.getConfig().isAllowContainsSearches()) {
|
||||
likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
|
||||
} else {
|
||||
likeExpression = createLeftMatchLikeExpression(likeExpression);
|
||||
}
|
||||
|
||||
|
@ -1933,6 +1930,11 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchSize(int theFetchSize) {
|
||||
myFetchSize = theFetchSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Class<? extends IBaseResource> theResourceType, String theResourceName) {
|
||||
myResourceType = theResourceType;
|
||||
|
@ -2020,14 +2022,14 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
return lastUpdatedPredicates;
|
||||
}
|
||||
|
||||
private static String createLeftMatchLikeExpression(String likeExpression) {
|
||||
return likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
||||
private static String createLeftAndRightMatchLikeExpression(String likeExpression) {
|
||||
return "%" + likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
||||
private static String createLeftMatchLikeExpression(String likeExpression) {
|
||||
return likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
||||
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From<?, ? extends ResourceLink> theFrom,
|
||||
String theResourceType) {
|
||||
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(theResourceType);
|
||||
|
@ -2188,6 +2190,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
final TypedQuery<Long> query = createQuery(mySort, maximumResults);
|
||||
|
||||
Query<Long> hibernateQuery = (Query<Long>) query;
|
||||
hibernateQuery.setFetchSize(myFetchSize);
|
||||
ScrollableResults scroll = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
|
||||
myResultsIterator = new ScrollableResultsIterator(scroll);
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
Class<? extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass();
|
||||
final ISearchBuilder sb = theCallingDao.newSearchBuilder();
|
||||
sb.setType(resourceTypeClass, theResourceType);
|
||||
sb.setFetchSize(mySyncSize);
|
||||
|
||||
final Integer loadSynchronousUpTo;
|
||||
if (theCacheControlDirective != null && theCacheControlDirective.isNoStore()) {
|
||||
|
@ -233,7 +234,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
public SimpleBundleProvider doInTransaction(TransactionStatus theStatus) {
|
||||
|
||||
// Load the results synchronously
|
||||
final List<Long> pids = new ArrayList<Long>();
|
||||
final List<Long> pids = new ArrayList<>();
|
||||
|
||||
Iterator<Long> resultIter = sb.createQuery(theParams, searchUuid);
|
||||
while (resultIter.hasNext()) {
|
||||
|
@ -458,8 +459,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
private final SearchParameterMap myParams;
|
||||
private final String myResourceType;
|
||||
private final Search mySearch;
|
||||
private final ArrayList<Long> mySyncedPids = new ArrayList<Long>();
|
||||
private final ArrayList<Long> myUnsyncedPids = new ArrayList<Long>();
|
||||
private final ArrayList<Long> mySyncedPids = new ArrayList<>();
|
||||
private final ArrayList<Long> myUnsyncedPids = new ArrayList<>();
|
||||
private boolean myAbortRequested;
|
||||
private int myCountSaved = 0;
|
||||
private String mySearchUuid;
|
||||
|
@ -503,7 +504,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
* It is called automatically by the thread pool.
|
||||
*/
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
public Void call() {
|
||||
StopWatch sw = new StopWatch();
|
||||
|
||||
try {
|
||||
|
@ -631,10 +632,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
boolean keepWaiting;
|
||||
do {
|
||||
synchronized (mySyncedPids) {
|
||||
keepWaiting = false;
|
||||
if (mySyncedPids.size() < theToIndex && mySearch.getStatus() == SearchStatusEnum.LOADING) {
|
||||
keepWaiting = true;
|
||||
}
|
||||
keepWaiting = mySyncedPids.size() < theToIndex && mySearch.getStatus() == SearchStatusEnum.LOADING;
|
||||
}
|
||||
if (keepWaiting) {
|
||||
ourLog.info("Waiting, as we only have {} results", mySyncedPids.size());
|
||||
|
|
|
@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.api.Constants;
|
|||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -54,6 +55,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
public void afterResetSearchSize() {
|
||||
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
|
||||
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
|
||||
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -1404,43 +1406,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #819
|
||||
*/
|
||||
@Test
|
||||
public void testSearchTokenWithNotModifier() {
|
||||
String male, female;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.addName().setFamily("Tester").addGiven("Joe");
|
||||
patient.setGender(AdministrativeGender.MALE);
|
||||
male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().setFamily("Tester").addGiven("Jane");
|
||||
patient.setGender(AdministrativeGender.FEMALE);
|
||||
female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
List<String> patients;
|
||||
SearchParameterMap params;
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male"));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(male));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male").setModifier(TokenParamModifier.NOT));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(female));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchNumberParam() {
|
||||
ImmunizationRecommendation e1 = new ImmunizationRecommendation();
|
||||
|
@ -2122,6 +2087,43 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #819
|
||||
*/
|
||||
@Test
|
||||
public void testSearchTokenWithNotModifier() {
|
||||
String male, female;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.addName().setFamily("Tester").addGiven("Joe");
|
||||
patient.setGender(AdministrativeGender.MALE);
|
||||
male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().setFamily("Tester").addGiven("Jane");
|
||||
patient.setGender(AdministrativeGender.FEMALE);
|
||||
female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
List<String> patients;
|
||||
SearchParameterMap params;
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male"));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(male));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male").setModifier(TokenParamModifier.NOT));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(female));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchTokenWrongParam() {
|
||||
Patient p1 = new Patient();
|
||||
|
@ -2257,6 +2259,67 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithContains() {
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.addName().setFamily("ABCDEFGHIJK");
|
||||
String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
Patient pt2 = new Patient();
|
||||
pt2.addName().setFamily("FGHIJK");
|
||||
String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
Patient pt3 = new Patient();
|
||||
pt3.addName().setFamily("ZZZZZ");
|
||||
myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
|
||||
List<String> ids;
|
||||
SearchParameterMap map;
|
||||
IBundleProvider results;
|
||||
|
||||
// Contains = true
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(true));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, containsInAnyOrder(pt1id, pt2id));
|
||||
|
||||
// Contains = false
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(false));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, containsInAnyOrder(pt2id));
|
||||
|
||||
// No contains
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK"));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, containsInAnyOrder(pt2id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithContainsDisabled() {
|
||||
myDaoConfig.setAllowContainsSearches(false);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(true));
|
||||
|
||||
try {
|
||||
myPatientDao.search(map);
|
||||
fail();
|
||||
} catch (MethodNotAllowedException e) {
|
||||
assertEquals(":contains modifier is disabled on this server", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithDate() {
|
||||
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
|
||||
|
|
|
@ -68,6 +68,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
|
|||
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseDstu2");
|
||||
retVal.setCountSearchResultsUpTo(TestR4Config.COUNT_SEARCH_RESULTS_UP_TO);
|
||||
retVal.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
|
||||
retVal.setFetchSizeDefaultMaximum(10000);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
|||
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseDstu3");
|
||||
retVal.setCountSearchResultsUpTo(TestR4Config.COUNT_SEARCH_RESULTS_UP_TO);
|
||||
retVal.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
|
||||
retVal.setFetchSizeDefaultMaximum(10000);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
|
|||
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseR4");
|
||||
retVal.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
|
||||
retVal.setCountSearchResultsUpTo(TestR4Config.COUNT_SEARCH_RESULTS_UP_TO);
|
||||
retVal.setFetchSizeDefaultMaximum(10000);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-structures-dstu2.1</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR Structures - DSTU2.1 (2016May)</name>
|
||||
|
||||
|
@ -273,6 +273,22 @@
|
|||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
<Import-Package>
|
||||
javax.servlet*;resolution:=optional,
|
||||
*
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.dstu2016may.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.dstu2016may.model.*;
|
||||
import org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent;
|
||||
|
@ -68,8 +69,8 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
Map<String, CodeSystem> codeSystems = myCodeSystems;
|
||||
Map<String, ValueSet> valueSets = myValueSets;
|
||||
if (codeSystems == null) {
|
||||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
codeSystems = new HashMap<>();
|
||||
valueSets = new HashMap<>();
|
||||
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/model/valueset/v2-tables.xml");
|
||||
|
@ -155,27 +156,33 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
InputStreamReader reader = null;
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR Structures - DSTU2 (FHIR v1.0.0)</name>
|
||||
|
||||
|
@ -361,6 +361,22 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
<Import-Package>
|
||||
javax.servlet*;resolution:=optional,
|
||||
*
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR Structures - DSTU3</name>
|
||||
|
||||
|
@ -28,6 +28,18 @@
|
|||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
|
@ -272,5 +284,4 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR Structures - HL7.org DSTU2</name>
|
||||
|
||||
|
@ -272,6 +272,22 @@
|
|||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
<Import-Package>
|
||||
javax.servlet*;resolution:=optional,
|
||||
*
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<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">
|
||||
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>
|
||||
|
||||
<parent>
|
||||
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR Structures - FHIR R4</name>
|
||||
|
||||
|
@ -29,16 +29,16 @@
|
|||
<!--
|
||||
Optional dependencies from RI codebase
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>es.nitaur.markdown</groupId>
|
||||
<artifactId>txtmark</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>ST4</artifactId>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<artifactId>xpp3</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--
|
||||
Test dependencies on other optional parts of HAPI
|
||||
-->
|
||||
|
@ -262,6 +262,18 @@
|
|||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.r4.hapi.ctx;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -141,27 +142,33 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
InputStreamReader reader = null;
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-utilities</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Utilities</name>
|
||||
|
||||
|
@ -122,6 +122,11 @@
|
|||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2.1</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Validation Resources DSTU2.1 (2016May)</name>
|
||||
|
||||
|
@ -20,6 +20,20 @@
|
|||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Validation Resources (DSTU2)</name>
|
||||
|
||||
|
@ -20,6 +20,20 @@
|
|||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Validation Resources (DSTU3)</name>
|
||||
|
||||
|
@ -34,6 +34,20 @@
|
|||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Validation Resources (FHIR R4)</name>
|
||||
|
||||
|
@ -34,6 +34,20 @@
|
|||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-validation</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>HAPI FHIR - Validation</name>
|
||||
|
||||
|
@ -246,6 +246,18 @@
|
|||
<fork>true</fork>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Fragment-Host>
|
||||
ca.uhn.hapi.fhir.hapi-fhir-base
|
||||
</Fragment-Host>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.hl7.fhir.dstu3.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
||||
|
@ -24,243 +24,249 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
|
||||
public class DefaultProfileValidationSupport implements IValidationSupport {
|
||||
|
||||
private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/";
|
||||
private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/";
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class);
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class);
|
||||
|
||||
private Map<String, CodeSystem> myCodeSystems;
|
||||
private Map<String, StructureDefinition> myStructureDefinitions;
|
||||
private Map<String, ValueSet> myValueSets;
|
||||
private Map<String, CodeSystem> myCodeSystems;
|
||||
private Map<String, StructureDefinition> myStructureDefinitions;
|
||||
private Map<String, ValueSet> myValueSets;
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
||||
ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
||||
ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
|
||||
|
||||
Set<String> wantCodes = new HashSet<String>();
|
||||
for (ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||
wantCodes.add(next.getCode());
|
||||
}
|
||||
Set<String> wantCodes = new HashSet<>();
|
||||
for (ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||
wantCodes.add(next.getCode());
|
||||
}
|
||||
|
||||
CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
|
||||
for (ConceptDefinitionComponent next : system.getConcept()) {
|
||||
if (wantCodes.isEmpty() || wantCodes.contains(next.getCode())) {
|
||||
retVal.addContains().setSystem(theInclude.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
|
||||
}
|
||||
}
|
||||
CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
|
||||
for (ConceptDefinitionComponent next : system.getConcept()) {
|
||||
if (wantCodes.isEmpty() || wantCodes.contains(next.getCode())) {
|
||||
retVal.addContains().setSystem(theInclude.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IBaseResource> fetchAllConformanceResources(FhirContext theContext) {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<>();
|
||||
retVal.addAll(myCodeSystems.values());
|
||||
retVal.addAll(myStructureDefinitions.values());
|
||||
retVal.addAll(myValueSets.values());
|
||||
return retVal;
|
||||
}
|
||||
@Override
|
||||
public List<IBaseResource> fetchAllConformanceResources(FhirContext theContext) {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<>();
|
||||
retVal.addAll(myCodeSystems.values());
|
||||
retVal.addAll(myStructureDefinitions.values());
|
||||
retVal.addAll(myValueSets.values());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
return new ArrayList<StructureDefinition>(provideStructureDefinitionMap(theContext).values());
|
||||
}
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
return new ArrayList<StructureDefinition>(provideStructureDefinitionMap(theContext).values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
|
||||
}
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
|
||||
}
|
||||
|
||||
private DomainResource fetchCodeSystemOrValueSet(FhirContext theContext, String theSystem, boolean codeSystem) {
|
||||
synchronized (this) {
|
||||
Map<String, CodeSystem> codeSystems = myCodeSystems;
|
||||
Map<String, ValueSet> valueSets = myValueSets;
|
||||
if (codeSystems == null || valueSets == null) {
|
||||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
private DomainResource fetchCodeSystemOrValueSet(FhirContext theContext, String theSystem, boolean codeSystem) {
|
||||
synchronized (this) {
|
||||
Map<String, CodeSystem> codeSystems = myCodeSystems;
|
||||
Map<String, ValueSet> valueSets = myValueSets;
|
||||
if (codeSystems == null || valueSets == null) {
|
||||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v3-codesystems.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v3-codesystems.xml");
|
||||
|
||||
myCodeSystems = codeSystems;
|
||||
myValueSets = valueSets;
|
||||
}
|
||||
myCodeSystems = codeSystems;
|
||||
myValueSets = valueSets;
|
||||
}
|
||||
|
||||
if (codeSystem) {
|
||||
return codeSystems.get(theSystem);
|
||||
} else {
|
||||
return valueSets.get(theSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (codeSystem) {
|
||||
return codeSystems.get(theSystem);
|
||||
} else {
|
||||
return valueSets.get(theSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
Validate.notBlank(theUri, "theUri must not be null or blank");
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
Validate.notBlank(theUri, "theUri must not be null or blank");
|
||||
|
||||
if (theClass.equals(StructureDefinition.class)) {
|
||||
return (T) fetchStructureDefinition(theContext, theUri);
|
||||
}
|
||||
if (theClass.equals(StructureDefinition.class)) {
|
||||
return (T) fetchStructureDefinition(theContext, theUri);
|
||||
}
|
||||
|
||||
if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
|
||||
return (T) fetchValueSet(theContext, theUri);
|
||||
}
|
||||
if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
|
||||
return (T) fetchValueSet(theContext, theUri);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) {
|
||||
String url = theUrl;
|
||||
if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
// no change
|
||||
} else if (url.indexOf('/') == -1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION + url;
|
||||
} else if (StringUtils.countMatches(url, '/') == 1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url;
|
||||
}
|
||||
Map<String, StructureDefinition> map = provideStructureDefinitionMap(theContext);
|
||||
StructureDefinition retVal = map.get(url);
|
||||
@Override
|
||||
public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) {
|
||||
String url = theUrl;
|
||||
if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
// no change
|
||||
} else if (url.indexOf('/') == -1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION + url;
|
||||
} else if (StringUtils.countMatches(url, '/') == 1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url;
|
||||
}
|
||||
Map<String, StructureDefinition> map = provideStructureDefinitionMap(theContext);
|
||||
StructureDefinition retVal = map.get(url);
|
||||
|
||||
if (retVal == null && url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
String tryUrl = URL_PREFIX_STRUCTURE_DEFINITION + StringUtils.capitalize(url.substring(URL_PREFIX_STRUCTURE_DEFINITION.length()));
|
||||
retVal = map.get(tryUrl);
|
||||
}
|
||||
if (retVal == null && url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
String tryUrl = URL_PREFIX_STRUCTURE_DEFINITION + StringUtils.capitalize(url.substring(URL_PREFIX_STRUCTURE_DEFINITION.length()));
|
||||
retVal = map.get(tryUrl);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
|
||||
return (ValueSet) fetchCodeSystemOrValueSet(theContext, theSystem, false);
|
||||
}
|
||||
ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
|
||||
return (ValueSet) fetchCodeSystemOrValueSet(theContext, theSystem, false);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
myCodeSystems = null;
|
||||
myStructureDefinitions = null;
|
||||
}
|
||||
public void flush() {
|
||||
myCodeSystems = null;
|
||||
myStructureDefinitions = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theSystem);
|
||||
return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
|
||||
}
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theSystem);
|
||||
return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
|
||||
}
|
||||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
InputStreamReader reader = null;
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadStructureDefinitions(FhirContext theContext, Map<String, StructureDefinition> theCodeSystems, String theClasspath) {
|
||||
ourLog.info("Loading structure definitions from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
private void loadStructureDefinitions(FhirContext theContext, Map<String, StructureDefinition> theCodeSystems, String theClasspath) {
|
||||
ourLog.info("Loading structure definitions from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof StructureDefinition) {
|
||||
StructureDefinition nextSd = (StructureDefinition) next.getResource();
|
||||
nextSd.getText().setDivAsString("");
|
||||
String system = nextSd.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextSd);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof StructureDefinition) {
|
||||
StructureDefinition nextSd = (StructureDefinition) next.getResource();
|
||||
nextSd.getText().setDivAsString("");
|
||||
String system = nextSd.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextSd);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, StructureDefinition> provideStructureDefinitionMap(FhirContext theContext) {
|
||||
Map<String, StructureDefinition> structureDefinitions = myStructureDefinitions;
|
||||
if (structureDefinitions == null) {
|
||||
structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
private Map<String, StructureDefinition> provideStructureDefinitionMap(FhirContext theContext) {
|
||||
Map<String, StructureDefinition> structureDefinitions = myStructureDefinitions;
|
||||
if (structureDefinitions == null) {
|
||||
structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-resources.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-types.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-others.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-resources.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-types.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-others.xml");
|
||||
|
||||
myStructureDefinitions = structureDefinitions;
|
||||
}
|
||||
return structureDefinitions;
|
||||
}
|
||||
myStructureDefinitions = structureDefinitions;
|
||||
}
|
||||
return structureDefinitions;
|
||||
}
|
||||
|
||||
private CodeValidationResult testIfConceptIsInList(String theCode, List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive) {
|
||||
String code = theCode;
|
||||
if (theCaseSensitive == false) {
|
||||
code = code.toUpperCase();
|
||||
}
|
||||
private CodeValidationResult testIfConceptIsInList(String theCode, List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive) {
|
||||
String code = theCode;
|
||||
if (theCaseSensitive == false) {
|
||||
code = code.toUpperCase();
|
||||
}
|
||||
|
||||
return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
|
||||
}
|
||||
return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
|
||||
}
|
||||
|
||||
private CodeValidationResult testIfConceptIsInListInner(List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive, String code) {
|
||||
CodeValidationResult retVal = null;
|
||||
for (ConceptDefinitionComponent next : conceptList) {
|
||||
String nextCandidate = next.getCode();
|
||||
if (theCaseSensitive == false) {
|
||||
nextCandidate = nextCandidate.toUpperCase();
|
||||
}
|
||||
if (nextCandidate.equals(code)) {
|
||||
retVal = new CodeValidationResult(next);
|
||||
break;
|
||||
}
|
||||
private CodeValidationResult testIfConceptIsInListInner(List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive, String code) {
|
||||
CodeValidationResult retVal = null;
|
||||
for (ConceptDefinitionComponent next : conceptList) {
|
||||
String nextCandidate = next.getCode();
|
||||
if (theCaseSensitive == false) {
|
||||
nextCandidate = nextCandidate.toUpperCase();
|
||||
}
|
||||
if (nextCandidate.equals(code)) {
|
||||
retVal = new CodeValidationResult(next);
|
||||
break;
|
||||
}
|
||||
|
||||
// recurse
|
||||
retVal = testIfConceptIsInList(code, next.getConcept(), theCaseSensitive);
|
||||
if (retVal != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// recurse
|
||||
retVal = testIfConceptIsInList(code, next.getConcept(), theCaseSensitive);
|
||||
if (retVal != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
|
||||
if (cs != null) {
|
||||
boolean caseSensitive = true;
|
||||
if (cs.hasCaseSensitive()) {
|
||||
caseSensitive = cs.getCaseSensitive();
|
||||
}
|
||||
@Override
|
||||
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
|
||||
if (cs != null) {
|
||||
boolean caseSensitive = true;
|
||||
if (cs.hasCaseSensitive()) {
|
||||
caseSensitive = cs.getCaseSensitive();
|
||||
}
|
||||
|
||||
CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
|
||||
CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
|
||||
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
|
||||
}
|
||||
return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.instance.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.Bundle;
|
||||
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.instance.model.CodeType;
|
||||
|
@ -44,9 +45,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
if (valueSets == null) {
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml");
|
||||
loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
|
||||
loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v2-tables.xml");
|
||||
loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml");
|
||||
|
||||
myCodeSystems = valueSets;
|
||||
}
|
||||
|
@ -108,26 +109,34 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, ValueSet> codeSystems, String file) {
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(file);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader;
|
||||
try {
|
||||
reader = new InputStreamReader(valuesetText, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Shouldn't happen!
|
||||
throw new InternalErrorException("UTF-8 encoding not supported on this platform", e);
|
||||
}
|
||||
private void loadValueSets(FhirContext theContext, Map<String, ValueSet> theValueSets, String theFile) {
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theFile);
|
||||
try {
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = null;
|
||||
try {
|
||||
reader = new InputStreamReader(valuesetText, "UTF-8");
|
||||
|
||||
FhirContext ctx = FhirInstanceValidator.getHl7OrgDstu2Ctx(theContext);
|
||||
Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
String system = nextValueSet.getCodeSystem().getSystem();
|
||||
if (isNotBlank(system)) {
|
||||
codeSystems.put(system, nextValueSet);
|
||||
FhirContext ctx = FhirInstanceValidator.getHl7OrgDstu2Ctx(theContext);
|
||||
Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
String system = nextValueSet.getCodeSystem().getSystem();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Shouldn't happen!
|
||||
throw new InternalErrorException("UTF-8 encoding not supported on this platform", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(valuesetText);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +145,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
ValueSet vs = fetchCodeSystem(theContext, theCodeSystem);
|
||||
if (vs != null) {
|
||||
for (ValueSet.ConceptDefinitionComponent nextConcept : vs.getCodeSystem().getConcept()) {
|
||||
if (nextConcept.getCode().equals(theCode)){
|
||||
if (nextConcept.getCode().equals(theCode)) {
|
||||
ValueSet.ConceptDefinitionComponent component = new ValueSet.ConceptDefinitionComponent(new CodeType(theCode));
|
||||
return new CodeValidationResult(component);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>ca.uhn.hapi.fhir.karaf</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>HAPI FHIR - Apache Karaf :: Features</name>
|
||||
|
||||
<properties>
|
||||
<features.file>features.xml</features.file>
|
||||
<pax-logging-version>1.8.6</pax-logging-version>
|
||||
<felix-framework-version>3.2.2</felix-framework-version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2.1</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2.1</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-converter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- The validate plugin will export these provided dependencies bundles export packages first -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.core</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.logging</groupId>
|
||||
<artifactId>pax-logging-api</artifactId>
|
||||
<version>${pax-logging-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.logging</groupId>
|
||||
<artifactId>pax-logging-service</artifactId>
|
||||
<version>${pax-logging-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>org.apache.felix.framework</artifactId>
|
||||
<version>${felix-framework-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>org.apache.felix.configadmin</artifactId>
|
||||
<version>1.8.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.aries.blueprint</groupId>
|
||||
<artifactId>org.apache.aries.blueprint.api</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.aries.blueprint</groupId>
|
||||
<artifactId>org.apache.aries.blueprint.core</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.shell</groupId>
|
||||
<artifactId>org.apache.karaf.shell.core</artifactId>
|
||||
<version>${apache_karaf_version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.features</groupId>
|
||||
<artifactId>framework</artifactId>
|
||||
<version>${apache_karaf_version}</version>
|
||||
<type>kar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>filter</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>resources</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-artifacts</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>attach-artifact</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifacts>
|
||||
<artifact>
|
||||
<file>target/classes/features.xml</file>
|
||||
<type>xml</type>
|
||||
<classifier>features</classifier>
|
||||
</artifact>
|
||||
</artifacts>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.karaf.tooling</groupId>
|
||||
<artifactId>karaf-maven-plugin</artifactId>
|
||||
<version>${apache_karaf_version}</version>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>file://${project.build.directory}/classes/${features.file}</descriptor>
|
||||
<descriptor>mvn:org.apache.karaf.features/enterprise/${apache_karaf_version}/xml/features</descriptor>
|
||||
</descriptors>
|
||||
<distribution>org.apache.karaf.features:framework</distribution>
|
||||
<javase>1.8</javase>
|
||||
<framework>
|
||||
<feature>framework</feature>
|
||||
</framework>
|
||||
<features>
|
||||
<feature>hapi-fhir*</feature>
|
||||
</features>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!--
|
||||
|
||||
HAPI FHIR - Apache Karaf Features
|
||||
|
||||
Copyright (C) 2014 - 2018 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.
|
||||
|
||||
-->
|
||||
<features name='hapi-fhir-${project.version}' xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
|
||||
|
||||
<feature name='hapi-fhir' version='${project.version}' start-level='50'>
|
||||
<feature prerequisite="true">wrap</feature>
|
||||
<bundle dependency='true'>mvn:com.google.code.gson/gson/${gson_version}</bundle>
|
||||
<bundle dependency='true'>mvn:org.apache.commons/commons-lang3/${commons_lang3_version}</bundle>
|
||||
<bundle dependency='true'>mvn:commons-codec/commons-codec/${commons_codec_version}</bundle>
|
||||
<bundle dependency='true'>mvn:commons-io/commons-io/${commons_io_version}</bundle>
|
||||
<bundle dependency='true'>mvn:com.google.guava/guava/${guava_version}</bundle>
|
||||
<bundle dependency='true'>wrap:mvn:com.google.errorprone/error_prone_annotations/${error_prone_annotations_version}</bundle>
|
||||
<bundle dependency='true'>mvn:org.codehaus.woodstox/stax2-api/${stax2_api_version}</bundle>
|
||||
<bundle dependency='true'>mvn:org.codehaus.woodstox/woodstox-core-asl/${woodstox_core_asl_version}</bundle>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-base/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-client' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<bundle dependency='true'>mvn:org.apache.httpcomponents/httpcore-osgi/${httpcore_version}</bundle>
|
||||
<bundle dependency='true'>mvn:org.apache.httpcomponents/httpclient-osgi/${httpclient_version}</bundle>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-client/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-utilities' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<bundle dependency='true'>mvn:com.google.code.gson/gson/${gson_version}</bundle>
|
||||
<bundle dependency='true'>mvn:commons-codec/commons-codec/${commons_codec_version}</bundle>
|
||||
<bundle dependency='true'>mvn:commons-io/commons-io/${commons_io_version}</bundle>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-utilities/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-dstu2' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-dstu2/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-hl7org-dstu2' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-utilities</feature>
|
||||
<bundle dependency='true'>
|
||||
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.saxon/${servicemix_saxon_version}
|
||||
</bundle>
|
||||
<bundle dependency='true'>
|
||||
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/${servicemix_xmlresolver_version}
|
||||
</bundle>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-hl7org-dstu2/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-dstu2.1' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-utilities</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-dstu2.1/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-dstu3' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-utilities</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-dstu3/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-r4' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-utilities</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-r4/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-ph-schematron' version='${project.version}' start-level='50'>
|
||||
<bundle dependency='true'>
|
||||
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.saxon/${servicemix_saxon_version}
|
||||
</bundle>
|
||||
<bundle dependency='true'>
|
||||
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/${servicemix_xmlresolver_version}
|
||||
</bundle>
|
||||
<bundle dependency='true'>mvn:com.google.code.findbugs/jsr305/${jsr305_version}</bundle>
|
||||
<bundle>mvn:com.phloc/phloc-schematron/${phloc_schematron_version}</bundle>
|
||||
<bundle>mvn:com.phloc/phloc-commons/${phloc_commons_version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-validation' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-utilities</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-ph-schematron</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-converter/${project.version}</bundle>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-validation/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-validation-dstu2' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir-validation</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-dstu2</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu2/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-validation-hl7org-dstu2' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir-validation</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-hl7org-dstu2</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu2/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-validation-dstu2.1' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir-validation</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-dstu2.1</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu2.1/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-validation-dstu3' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir-validation</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-dstu3</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-r4</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu3/${project.version}</bundle>
|
||||
</feature>
|
||||
|
||||
<feature name='hapi-fhir-validation-r4' version='${project.version}' start-level='50'>
|
||||
<feature version='${project.version}'>hapi-fhir-validation</feature>
|
||||
<feature version='${project.version}'>hapi-fhir-r4</feature>
|
||||
<bundle>mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-r4/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
|
@ -0,0 +1,181 @@
|
|||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-karaf-integration-tests</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>HAPI-FHIR Apache Karaf Integration Tests</name>
|
||||
|
||||
<description>
|
||||
Integration tests for the HAPI-FHIR Apache Karaf features
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<pax.exam.version>4.9.1</pax.exam.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2.1</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2.1</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- karaf test -->
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-container-karaf</artifactId>
|
||||
<version>${pax.exam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
<artifactId>pax-exam-junit4</artifactId>
|
||||
<version>${pax.exam.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xmlunit</groupId>
|
||||
<artifactId>xmlunit-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf</groupId>
|
||||
<artifactId>apache-karaf</artifactId>
|
||||
<version>${apache_karaf_version}</version>
|
||||
<scope>test</scope>
|
||||
<type>tar.gz</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.shell</groupId>
|
||||
<artifactId>org.apache.karaf.shell.console</artifactId>
|
||||
<version>${apache_karaf_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir.karaf</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>features</classifier>
|
||||
<type>xml</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.features</groupId>
|
||||
<artifactId>enterprise</artifactId>
|
||||
<version>${apache_karaf_version}</version>
|
||||
<classifier>features</classifier>
|
||||
<type>xml</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.servicemix.bundles</groupId>
|
||||
<artifactId>org.apache.servicemix.bundles.hamcrest</artifactId>
|
||||
<version>1.3_1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.servicemix.tooling</groupId>
|
||||
<artifactId>depends-maven-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-depends-file</id>
|
||||
<goals>
|
||||
<goal>generate-depends-file</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
<reuseForks>false</reuseForks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,142 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf;
|
||||
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.karaf.options.LogLevelOption;
|
||||
import org.ops4j.pax.exam.options.DefaultCompositeOption;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.ops4j.pax.exam.CoreOptions.maven;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
|
||||
|
||||
public enum PaxExamOptions {
|
||||
KARAF(
|
||||
karafDistributionConfiguration()
|
||||
.frameworkUrl(
|
||||
maven()
|
||||
.groupId("org.apache.karaf")
|
||||
.artifactId("apache-karaf")
|
||||
.versionAsInProject()
|
||||
.type("zip"))
|
||||
.name("Apache Karaf")
|
||||
.useDeployFolder(false)
|
||||
.unpackDirectory(new File("target/paxexam/unpack/")),
|
||||
keepRuntimeFolder(),
|
||||
configureConsole().ignoreLocalConsole(),
|
||||
logLevel(LogLevelOption.LogLevel.INFO)
|
||||
),
|
||||
WRAP(
|
||||
features(
|
||||
maven()
|
||||
.groupId("org.apache.karaf.features")
|
||||
.artifactId("enterprise")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"wrap")
|
||||
),
|
||||
HAPI_FHIR_CLIENT(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-client")
|
||||
),
|
||||
HAPI_FHIR_HL7ORG_DSTU2(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-hl7org-dstu2")
|
||||
),
|
||||
HAPI_FHIR_DSTU2_1(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-dstu2.1")
|
||||
),
|
||||
HAPI_FHIR_DSTU3(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-dstu3")
|
||||
),
|
||||
HAPI_FHIR_R4(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-r4")
|
||||
),
|
||||
HAPI_FHIR_VALIDATION_DSTU2(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-validation-dstu2")
|
||||
),
|
||||
HAPI_FHIR_VALIDATION_HL7ORG_DSTU2(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-validation-hl7org-dstu2")
|
||||
),
|
||||
HAPI_FHIR_VALIDATION_DSTU3(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-validation-dstu3")
|
||||
),
|
||||
HAPI_FHIR_VALIDATION_R4(
|
||||
features(
|
||||
maven()
|
||||
.groupId("ca.uhn.hapi.fhir.karaf")
|
||||
.artifactId("hapi-fhir")
|
||||
.type("xml")
|
||||
.classifier("features")
|
||||
.versionAsInProject(),
|
||||
"hapi-fhir-validation-r4")
|
||||
);
|
||||
|
||||
private final Option[] options;
|
||||
|
||||
PaxExamOptions(Option... options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public Option option() {
|
||||
return new DefaultCompositeOption(options);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_CLIENT;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_DSTU3;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
@Ignore(value = "Relies on external service being up and running")
|
||||
public class FhirClientTest {
|
||||
|
||||
private FhirContext fhirContext = FhirContext.forDstu3();
|
||||
private IGenericClient client = fhirContext.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu3");
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirClientTest.class);
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
HAPI_FHIR_CLIENT.option(),
|
||||
HAPI_FHIR_DSTU3.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
WRAP.option(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPatient() throws Exception {
|
||||
Patient patient = new Patient();
|
||||
patient.setId("PATIENTID");
|
||||
patient.getMeta().addProfile("http://BAR");
|
||||
patient.addName().addGiven("GIVEN");
|
||||
MethodOutcome execute = client.create().resource(patient).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
ourLog.info(execute.toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,331 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Condition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ConditionVerificationStatusEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.NarrativeStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.SchemaBaseValidator;
|
||||
import ca.uhn.fhir.validation.ValidationFailureException;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_DSTU2;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
public class Dstu2ResourceValidatorDstu2Test {
|
||||
|
||||
private FhirContext ourCtx = FhirContext.forDstu2();
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Dstu2ResourceValidatorDstu2Test.class);
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
WRAP.option(),
|
||||
HAPI_FHIR_VALIDATION_DSTU2.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
|
||||
private FhirValidator createFhirValidator() {
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateAgainstStandardSchema(true);
|
||||
val.setValidateAgainstStandardSchematron(true);
|
||||
return val;
|
||||
}
|
||||
|
||||
private String logOperationOutcome(ValidationResult result) {
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
|
||||
ourLog.info(encoded);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #50
|
||||
*/
|
||||
@Test()
|
||||
public void testOutOfBoundsDate() {
|
||||
Patient p = new Patient();
|
||||
p.setBirthDate(new DateDt("2000-12-31"));
|
||||
|
||||
// Put in an invalid date
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
parser.setParserErrorHandler(new StrictErrorHandler());
|
||||
|
||||
String encoded = parser.setPrettyPrint(true).encodeResourceToString(p).replace("2000-12-31", "2000-15-31");
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, StringContains.containsString("2000-15-31"));
|
||||
|
||||
ValidationResult result = ourCtx.newValidator().validateWithResult(encoded);
|
||||
String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(resultString);
|
||||
|
||||
assertEquals(2, ((OperationOutcome)result.toOperationOutcome()).getIssue().size());
|
||||
assertThat(resultString, StringContains.containsString("cvc-pattern-valid"));
|
||||
|
||||
try {
|
||||
parser.parseResource(encoded);
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Invalid attribute value \"2000-15-31\": Invalid date/time format: \"2000-15-31\"", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchemaBundleValidatorIsSuccessful() throws IOException {
|
||||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("bundle-example.json"), StandardCharsets.UTF_8);
|
||||
Bundle b = ourCtx.newJsonParser().parseResource(Bundle.class, res);
|
||||
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b));
|
||||
|
||||
FhirValidator val = createFhirValidator();
|
||||
|
||||
ValidationResult result = val.validateWithResult(b);
|
||||
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
|
||||
assertTrue(result.toString(), result.isSuccessful());
|
||||
assertNotNull(operationOutcome);
|
||||
assertEquals(1, operationOutcome.getIssue().size());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testSchemaResourceValidator() throws IOException {
|
||||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.json"));
|
||||
Patient p = ourCtx.newJsonParser().parseResource(Patient.class, res);
|
||||
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p));
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateAgainstStandardSchema(true);
|
||||
val.setValidateAgainstStandardSchematron(false);
|
||||
|
||||
val.validate(p);
|
||||
|
||||
p.getAnimal().getBreed().setText("The Breed");
|
||||
try {
|
||||
val.validate(p);
|
||||
fail();
|
||||
} catch (ValidationFailureException e) {
|
||||
OperationOutcome operationOutcome = (OperationOutcome) e.getOperationOutcome();
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
|
||||
assertEquals(1, operationOutcome.getIssue().size());
|
||||
assertThat(operationOutcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the elements that appear in all resources (meta, language, extension, etc)
|
||||
* all appear in the correct order
|
||||
*/
|
||||
@Test
|
||||
public void testValidateResourceWithResourceElements() {
|
||||
TestPatientFor327 patient = new TestPatientFor327();
|
||||
patient.setBirthDate(new Date(), TemporalPrecisionEnum.DAY);
|
||||
patient.setId("123");
|
||||
patient.getText().setDiv("<div>FOO</div>");
|
||||
patient.getText().setStatus(NarrativeStatusEnum.GENERATED);
|
||||
patient.getLanguage().setValue("en");
|
||||
patient.addUndeclaredExtension(true, "http://foo").setValue(new StringDt("MOD"));
|
||||
ResourceMetadataKeyEnum.UPDATED.put(patient, new InstantDt(new Date()));
|
||||
|
||||
List<ResourceReferenceDt> conditions = new ArrayList<ResourceReferenceDt>();
|
||||
Condition condition = new Condition();
|
||||
condition.getPatient().setReference("Patient/123");
|
||||
condition.addBodySite().setText("BODY SITE");
|
||||
condition.getCode().setText("CODE");
|
||||
condition.setVerificationStatus(ConditionVerificationStatusEnum.CONFIRMED);
|
||||
conditions.add(new ResourceReferenceDt(condition));
|
||||
patient.setCondition(conditions);
|
||||
patient.addIdentifier().setSystem("http://foo").setValue("123");
|
||||
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
ourLog.info(encoded);
|
||||
|
||||
FhirValidator val = createFhirValidator();
|
||||
ValidationResult result = val.validateWithResult(encoded);
|
||||
|
||||
String messageString = logOperationOutcome(result);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
|
||||
assertThat(messageString, containsString("No issues"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See
|
||||
* https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium=
|
||||
* email&utm_source=footer
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithExtensionsJson() {
|
||||
PatientProfileDstu2 myPatient = new PatientProfileDstu2();
|
||||
myPatient.setColorPrimary(new CodeableConceptDt("http://example.com#animalColor", "furry-grey"));
|
||||
myPatient.setColorSecondary(new CodeableConceptDt("http://example.com#animalColor", "furry-white"));
|
||||
myPatient.setOwningOrganization(new ResourceReferenceDt("Organization/2.25.79433498044103547197447759549862032393"));
|
||||
myPatient.addName().addFamily("FamilyName");
|
||||
myPatient.addUndeclaredExtension(new ExtensionDt().setUrl("http://foo.com/example").setValue(new StringDt("String Extension")));
|
||||
|
||||
IParser p = FhirContext.forDstu2().newJsonParser().setPrettyPrint(true);
|
||||
String messageString = p.encodeResourceToString(myPatient);
|
||||
ourLog.info(messageString);
|
||||
|
||||
//@formatter:off
|
||||
assertThat(messageString, stringContainsInOrder(
|
||||
"meta",
|
||||
"String Extension",
|
||||
"Organization/2.25.79433498044103547197447759549862032393",
|
||||
"furry-grey",
|
||||
"furry-white",
|
||||
"FamilyName"
|
||||
));
|
||||
assertThat(messageString, not(stringContainsInOrder(
|
||||
"extension",
|
||||
"meta"
|
||||
)));
|
||||
//@formatter:on
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
|
||||
ValidationResult result = val.validateWithResult(messageString);
|
||||
|
||||
logOperationOutcome(result);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
|
||||
assertThat(messageString, containsString("valueReference"));
|
||||
assertThat(messageString, not(containsString("valueResource")));
|
||||
}
|
||||
|
||||
private Matcher<? super String> stringContainsInOrder(java.lang.String... substrings) {
|
||||
return Matchers.stringContainsInOrder(Arrays.asList(substrings));
|
||||
}
|
||||
|
||||
/**
|
||||
* See
|
||||
* https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium=
|
||||
* email&utm_source=footer
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithExtensionsXml() {
|
||||
PatientProfileDstu2 myPatient = new PatientProfileDstu2();
|
||||
myPatient.setColorPrimary(new CodeableConceptDt("http://example.com#animalColor", "furry-grey"));
|
||||
myPatient.setColorSecondary(new CodeableConceptDt("http://example.com#animalColor", "furry-white"));
|
||||
myPatient.setOwningOrganization(new ResourceReferenceDt("Organization/2.25.79433498044103547197447759549862032393"));
|
||||
myPatient.addName().addFamily("FamilyName");
|
||||
myPatient.addUndeclaredExtension(new ExtensionDt().setUrl("http://foo.com/example").setValue(new StringDt("String Extension")));
|
||||
|
||||
IParser p = FhirContext.forDstu2().newXmlParser().setPrettyPrint(true);
|
||||
String messageString = p.encodeResourceToString(myPatient);
|
||||
ourLog.info(messageString);
|
||||
|
||||
//@formatter:off
|
||||
assertThat(messageString, stringContainsInOrder(
|
||||
"meta",
|
||||
"Organization/2.25.79433498044103547197447759549862032393",
|
||||
"furry-grey",
|
||||
"furry-white",
|
||||
"String Extension",
|
||||
"FamilyName"
|
||||
));
|
||||
assertThat(messageString, not(stringContainsInOrder(
|
||||
"extension",
|
||||
"meta"
|
||||
)));
|
||||
assertThat(messageString, containsString("url=\"http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorSecondary\""));
|
||||
assertThat(messageString, containsString("url=\"http://foo.com/example\""));
|
||||
//@formatter:on
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
|
||||
ValidationResult result = val.validateWithResult(messageString);
|
||||
|
||||
logOperationOutcome(result);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
|
||||
assertThat(messageString, containsString("valueReference"));
|
||||
assertThat(messageString, not(containsString("valueResource")));
|
||||
}
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public static class TestPatientFor327 extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "testCondition")
|
||||
@ca.uhn.fhir.model.api.annotation.Extension(url = "testCondition", definedLocally = true, isModifier = false)
|
||||
private List<ResourceReferenceDt> testConditions = null;
|
||||
|
||||
public List<ResourceReferenceDt> getConditions() {
|
||||
return this.testConditions;
|
||||
}
|
||||
|
||||
public void setCondition(List<ResourceReferenceDt> ref) {
|
||||
this.testConditions = ref;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
@ResourceDef(name="Patient", profile = "http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient")
|
||||
public class PatientProfileDstu2 extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name="owner", min=0, max=1)
|
||||
@Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#owningOrganization", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The organization that owns this animal")
|
||||
private ResourceReferenceDt owningOrganization;
|
||||
|
||||
public ResourceReferenceDt getOwningOrganization() {
|
||||
if (owningOrganization == null) {
|
||||
owningOrganization = new ResourceReferenceDt();
|
||||
}
|
||||
return owningOrganization;
|
||||
}
|
||||
|
||||
public PatientProfileDstu2 setOwningOrganization(ResourceReferenceDt owningOrganization) {
|
||||
this.owningOrganization = owningOrganization;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Child(name="colorPrimary", min=0, max=1)
|
||||
@Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorPrimary", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The animals primary color")
|
||||
private CodeableConceptDt colorPrimary;
|
||||
|
||||
@Child(name="colorSecondary", min=0, max=1)
|
||||
@Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorSecondary", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The animals secondary color")
|
||||
private CodeableConceptDt colorSecondary;
|
||||
|
||||
public CodeableConceptDt getColorPrimary() {
|
||||
if (this.colorPrimary == null) {
|
||||
return new CodeableConceptDt();
|
||||
}
|
||||
return colorPrimary;
|
||||
}
|
||||
|
||||
public void setColorPrimary(CodeableConceptDt colorPrimary) {
|
||||
this.colorPrimary = colorPrimary;
|
||||
}
|
||||
|
||||
public CodeableConceptDt getColorSecondary() {
|
||||
if (this.colorSecondary == null) {
|
||||
return new CodeableConceptDt();
|
||||
}
|
||||
return colorSecondary;
|
||||
}
|
||||
|
||||
public void setColorSecondary(CodeableConceptDt colorSecondary) {
|
||||
this.colorSecondary = colorSecondary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(owningOrganization) && ElementUtil.isEmpty(colorPrimary)
|
||||
&& ElementUtil.isEmpty(colorSecondary) ;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,60 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu21;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu2016may.model.Identifier;
|
||||
import org.hl7.fhir.dstu2016may.model.Patient;
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public class PatientWithExtendedContactDstu3 extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* A contact party (e.g. guardian, partner, friend) for the patient.
|
||||
*/
|
||||
@Child(name = "contact", type = {}, order = Child.REPLACE_PARENT, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = false)
|
||||
@Description(shortDefinition = "A contact party (e.g. guardian, partner, friend) for the patient", formalDefinition = "A contact party (e.g. guardian, partner, friend) for the patient.")
|
||||
protected List<CustomContactComponent> customContact;
|
||||
|
||||
public List<CustomContactComponent> getCustomContact() {
|
||||
if (customContact == null) {
|
||||
customContact = new ArrayList<CustomContactComponent>();
|
||||
}
|
||||
return customContact;
|
||||
}
|
||||
|
||||
@Block()
|
||||
public static class CustomContactComponent extends ContactComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Child(name = "contact-eyecolour", type = { Identifier.class }, modifier = true)
|
||||
@Description(shortDefinition = "Application ID")
|
||||
@Extension(url = "http://foo.com/contact-eyecolour", definedLocally = false, isModifier = false)
|
||||
private Identifier myEyeColour;
|
||||
|
||||
/*
|
||||
* Get messageHeaderApplicationId
|
||||
*/
|
||||
public Identifier getEyeColour() {
|
||||
if (myEyeColour == null) {
|
||||
myEyeColour = new Identifier();
|
||||
}
|
||||
return myEyeColour;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set messageHeaderApplicationId
|
||||
*/
|
||||
public void setEyeColour(Identifier messageHeaderApplicationId) {
|
||||
this.myEyeColour = messageHeaderApplicationId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,136 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
|
||||
|
||||
import java.io.IOException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import org.hl7.fhir.instance.hapi.validation.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.instance.hapi.validation.FhirInstanceValidator;
|
||||
import org.hl7.fhir.instance.model.DateType;
|
||||
import org.hl7.fhir.instance.model.Observation;
|
||||
import org.hl7.fhir.instance.model.QuestionnaireResponse;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_HL7ORG_DSTU2;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
public class FhirInstanceValidatorTest {
|
||||
private FhirInstanceValidator ourValidator = new FhirInstanceValidator(new DefaultProfileValidationSupport());
|
||||
private FhirContext ourCtxHl7OrgDstu2 = FhirContext.forDstu2Hl7Org();
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirInstanceValidatorTest.class);
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
WRAP.option(),
|
||||
HAPI_FHIR_VALIDATION_HL7ORG_DSTU2.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuestionnaireResponse() {
|
||||
QuestionnaireResponse qr = new QuestionnaireResponse();
|
||||
qr.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
|
||||
qr.getGroup().addGroup().addQuestion().setLinkId("foo");
|
||||
qr.getGroup().addQuestion().setLinkId("bar");
|
||||
|
||||
FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
|
||||
|
||||
val.registerValidatorModule(ourValidator);
|
||||
|
||||
ValidationResult result = val.validateWithResult(qr);
|
||||
|
||||
String encoded = ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObservation() {
|
||||
Observation o = new Observation();
|
||||
o.addIdentifier().setSystem("http://acme.org").setValue("1234");
|
||||
o.setStatus(Observation.ObservationStatus.FINAL);
|
||||
o.getCode().addCoding().setSystem("http://loinc.org").setCode("12345");
|
||||
o.getEncounter().setReference("Encounter/1234");
|
||||
|
||||
FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
|
||||
|
||||
val.registerValidatorModule(ourValidator);
|
||||
|
||||
ValidationResult result = val.validateWithResult(o);
|
||||
|
||||
String encoded = ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParametersWithTwoParameters() {
|
||||
org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
|
||||
patient.addName().addGiven("James");
|
||||
patient.setBirthDateElement(new DateType("2011-02-02"));
|
||||
|
||||
org.hl7.fhir.instance.model.Parameters input = new org.hl7.fhir.instance.model.Parameters();
|
||||
input.addParameter().setName("mode").setValue(new StringType("create"));
|
||||
input.addParameter().setName("resource").setResource(patient);
|
||||
|
||||
FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
|
||||
|
||||
val.registerValidatorModule(ourValidator);
|
||||
|
||||
ValidationResult result = val.validateWithResult(input);
|
||||
|
||||
String encoded = ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
assertThat(encoded, not(containsString("A parameter must have a value or a resource, but not both")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParametersHl7OrgDstu2() {
|
||||
org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
|
||||
patient.addName().addGiven("James");
|
||||
patient.setBirthDateElement(new DateType("2011-02-02"));
|
||||
|
||||
org.hl7.fhir.instance.model.Parameters input = new org.hl7.fhir.instance.model.Parameters();
|
||||
input.addParameter().setName("resource").setResource(patient);
|
||||
|
||||
FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
|
||||
|
||||
val.registerValidatorModule(ourValidator);
|
||||
|
||||
ValidationResult result = val.validateWithResult(input);
|
||||
|
||||
ourLog.info(ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
|
||||
assertTrue(result.isSuccessful());
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,106 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import org.hl7.fhir.instance.model.Attachment;
|
||||
import org.hl7.fhir.instance.model.BackboneElement;
|
||||
import org.hl7.fhir.instance.model.DateType;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
|
||||
|
||||
|
||||
@ResourceDef(name="Patient")
|
||||
public class MyObservationWithExtensions extends Patient {
|
||||
|
||||
@Extension(url = "urn:patientext:att", definedLocally = false, isModifier = false)
|
||||
@Child(name = "extAtt", order = 0)
|
||||
private Attachment myExtAtt;
|
||||
|
||||
@Extension(url = "urn:patientext:moreext", definedLocally = false, isModifier = false)
|
||||
@Child(name = "moreExt", order = 1)
|
||||
private MoreExt myMoreExt;
|
||||
|
||||
@Extension(url = "urn:modext", definedLocally = false, isModifier = true)
|
||||
@Child(name = "modExt", order = 2)
|
||||
private DateType myModExt;
|
||||
|
||||
public Attachment getExtAtt() {
|
||||
return myExtAtt;
|
||||
}
|
||||
|
||||
public MoreExt getMoreExt() {
|
||||
return myMoreExt;
|
||||
}
|
||||
|
||||
public void setMoreExt(MoreExt theMoreExt) {
|
||||
myMoreExt = theMoreExt;
|
||||
}
|
||||
|
||||
public DateType getModExt() {
|
||||
return myModExt;
|
||||
}
|
||||
|
||||
public void setModExt(DateType theModExt) {
|
||||
myModExt = theModExt;
|
||||
}
|
||||
|
||||
public void setExtAtt(Attachment theExtAtt) {
|
||||
myExtAtt = theExtAtt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(myExtAtt, myModExt, myMoreExt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Block class for child element: <b>Observation.referenceRange</b> (Provides guide for interpretation)
|
||||
*
|
||||
* <p>
|
||||
* <b>Definition:</b> Guidance on how to interpret the value by comparison to a normal or recommended range
|
||||
* </p>
|
||||
*/
|
||||
@Block(name = "Observation.someExtensions")
|
||||
public static class MoreExt extends BackboneElement implements IBaseBackboneElement {
|
||||
|
||||
@Extension(url = "urn:patientext:moreext:1", definedLocally = false, isModifier = false)
|
||||
@Child(name = "str1", order = 0)
|
||||
private StringType myStr1;
|
||||
|
||||
@Extension(url = "urn:patientext:moreext:2", definedLocally = false, isModifier = false)
|
||||
@Child(name = "str2", order = 1)
|
||||
private StringType myStr2;
|
||||
|
||||
public StringType getStr1() {
|
||||
return myStr1;
|
||||
}
|
||||
|
||||
public void setStr1(StringType theStr1) {
|
||||
myStr1 = theStr1;
|
||||
}
|
||||
|
||||
public StringType getStr2() {
|
||||
return myStr2;
|
||||
}
|
||||
|
||||
public void setStr2(StringType theStr2) {
|
||||
myStr2 = theStr2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return ElementUtil.isEmpty(myStr1, myStr2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackboneElement copy() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.instance.model.Organization;
|
||||
|
||||
@ResourceDef()
|
||||
public class MyOrganizationDstu2 extends Organization {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.instance.model.DateTimeType;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
import org.hl7.fhir.instance.model.Reference;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
|
||||
|
||||
@ResourceDef()
|
||||
public class MyPatientHl7Org extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name="petName")
|
||||
@Extension(url="http://example.com/dontuse#petname", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The name of the patient's favourite pet")
|
||||
private StringType myPetName;
|
||||
|
||||
@Child(name="importantDates", max=Child.MAX_UNLIMITED)
|
||||
@Extension(url="http://example.com/dontuse#importantDates", definedLocally=false, isModifier=true)
|
||||
@Description(shortDefinition="Some dates of note for the patient")
|
||||
private List<DateTimeType> myImportantDates;
|
||||
|
||||
@Child(name="managingOrganization", order=Child.REPLACE_PARENT, min=0, max=1, type={
|
||||
MyOrganizationDstu2.class })
|
||||
@Description(
|
||||
shortDefinition="Organization that is the custodian of the patient record",
|
||||
formalDefinition="Organization that is the custodian of the patient record"
|
||||
)
|
||||
private Reference myManagingOrganization;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && myPetName.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public List<DateTimeType> getImportantDates() {
|
||||
if (myImportantDates==null) {
|
||||
myImportantDates = new ArrayList<DateTimeType>();
|
||||
}
|
||||
return myImportantDates;
|
||||
}
|
||||
|
||||
public StringType getPetName() {
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
public void setImportantDates(List<DateTimeType> theImportantDates) {
|
||||
myImportantDates = theImportantDates;
|
||||
}
|
||||
|
||||
public void setPetName(StringType thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.instance.model.Address.AddressUse;
|
||||
import org.hl7.fhir.instance.model.Enumeration;
|
||||
import org.hl7.fhir.instance.model.Patient;
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public class MyPatientWithOneDeclaredEnumerationExtension extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(order = 0, name = "foo")
|
||||
@ca.uhn.fhir.model.api.annotation.Extension(url = "urn:foo", definedLocally = true, isModifier = false)
|
||||
private Enumeration<AddressUse> myFoo;
|
||||
|
||||
public Enumeration<AddressUse> getFoo() {
|
||||
return myFoo;
|
||||
}
|
||||
|
||||
public void setFoo(Enumeration<AddressUse> theFoo) {
|
||||
myFoo = theFoo;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
|
||||
|
||||
import java.util.List;
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.instance.model.BackboneElement;
|
||||
import org.hl7.fhir.instance.model.CodeableConcept;
|
||||
import org.hl7.fhir.instance.model.DateType;
|
||||
import org.hl7.fhir.instance.model.DomainResource;
|
||||
import org.hl7.fhir.instance.model.Identifier;
|
||||
import org.hl7.fhir.instance.model.ResourceType;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
|
||||
@ResourceDef(name = "ResourceWithExtensionsA", id="0001")
|
||||
public class ResourceWithExtensionsA extends DomainResource {
|
||||
|
||||
/*
|
||||
* NB: several unit tests depend on the structure here
|
||||
* so check the unit tests immediately after any changes
|
||||
*/
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "foo1", type = StringType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://foo/#f1", definedLocally=true, isModifier=false)
|
||||
private List<StringType> myFoo1;
|
||||
|
||||
@Child(name = "foo2", type = StringType.class, order = 1, min = 0, max = 1)
|
||||
@Extension(url = "http://foo/#f2", definedLocally=true, isModifier=true)
|
||||
private StringType myFoo2;
|
||||
|
||||
@Child(name = "bar1", type = Bar1.class, order = 2, min = 1, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://bar/#b1", definedLocally=true, isModifier=false)
|
||||
private List<Bar1> myBar1;
|
||||
|
||||
@Child(name = "bar2", type = Bar1.class, order = 3, min = 1, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://bar/#b2", definedLocally=true, isModifier=false)
|
||||
private Bar1 myBar2;
|
||||
|
||||
@Child(name="baz", type = CodeableConcept.class, order = 4)
|
||||
@Extension(url= "http://baz/#baz", definedLocally=true, isModifier=false)
|
||||
@Description(shortDefinition = "Contains a codeable concept")
|
||||
private CodeableConcept myBaz;
|
||||
|
||||
@Child(name = "identifier", type = Identifier.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
||||
private List<Identifier> myIdentifier;
|
||||
|
||||
public List<Bar1> getBar1() {
|
||||
return myBar1;
|
||||
}
|
||||
|
||||
public Bar1 getBar2() {
|
||||
return myBar2;
|
||||
}
|
||||
|
||||
public List<StringType> getFoo1() {
|
||||
return myFoo1;
|
||||
}
|
||||
|
||||
public StringType getFoo2() {
|
||||
return myFoo2;
|
||||
}
|
||||
|
||||
public CodeableConcept getBaz() { return myBaz; }
|
||||
|
||||
public List<Identifier> getIdentifier() {
|
||||
return myIdentifier;
|
||||
}
|
||||
|
||||
public void setBar1(List<Bar1> theBar1) {
|
||||
myBar1 = theBar1;
|
||||
}
|
||||
|
||||
public void setBar2(Bar1 theBar2) {
|
||||
myBar2 = theBar2;
|
||||
}
|
||||
|
||||
public void setFoo1(List<StringType> theFoo1) {
|
||||
myFoo1 = theFoo1;
|
||||
}
|
||||
|
||||
public void setFoo2(StringType theFoo2) {
|
||||
myFoo2 = theFoo2;
|
||||
}
|
||||
|
||||
public void setBaz(CodeableConcept myBaz) { this.myBaz = myBaz; }
|
||||
|
||||
public void setIdentifier(List<Identifier> theValue) {
|
||||
myIdentifier = theValue;
|
||||
}
|
||||
|
||||
@Block(name = "Bar1")
|
||||
public static class Bar1 extends BackboneElement {
|
||||
|
||||
public Bar1() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Child(name = "bar11", type = DateType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://bar/#b1/1", definedLocally=true, isModifier=false)
|
||||
private List<DateType> myBar11;
|
||||
|
||||
@Child(name = "bar12", type = DateType.class, order = 1, min = 0, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://bar/#b1/2", definedLocally=true, isModifier=false)
|
||||
private List<Bar2> myBar12;
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false; // not implemented
|
||||
}
|
||||
|
||||
public List<DateType> getBar11() {
|
||||
return myBar11;
|
||||
}
|
||||
|
||||
public List<Bar2> getBar12() {
|
||||
return myBar12;
|
||||
}
|
||||
|
||||
public void setBar11(List<DateType> theBar11) {
|
||||
myBar11 = theBar11;
|
||||
}
|
||||
|
||||
public void setBar12(List<Bar2> theBar12) {
|
||||
myBar12 = theBar12;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BackboneElement copy() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Block(name = "Bar2")
|
||||
public static class Bar2 extends BackboneElement {
|
||||
|
||||
@Child(name = "bar121", type = DateType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://bar/#b1/2/1", definedLocally=true, isModifier=false)
|
||||
private List<DateType> myBar121;
|
||||
|
||||
@Child(name = "bar122", type = DateType.class, order = 1, min = 0, max = Child.MAX_UNLIMITED)
|
||||
@Extension(url = "http://bar/#b1/2/2", definedLocally=true, isModifier=false)
|
||||
private List<DateType> myBar122;
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false; // not implemented
|
||||
}
|
||||
|
||||
|
||||
public List<DateType> getBar121() {
|
||||
return myBar121;
|
||||
}
|
||||
|
||||
public List<DateType> getBar122() {
|
||||
return myBar122;
|
||||
}
|
||||
|
||||
public void setBar121(List<DateType> theBar121) {
|
||||
myBar121 = theBar121;
|
||||
}
|
||||
|
||||
public void setBar122(List<DateType> theBar122) {
|
||||
myBar122 = theBar122;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackboneElement copy() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false; // not implemented
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DomainResource copy() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceType getResourceType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.DiagnosticReport;
|
||||
|
||||
@ResourceDef(name = "DiagnosticReport", profile = CustomDiagnosticReport.PROFILE)
|
||||
public class CustomDiagnosticReport extends DiagnosticReport {
|
||||
|
||||
public static final String PROFILE = "http://custom_DiagnosticReport";
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
|
||||
@ResourceDef(name = "Observation", profile = CustomObservation.PROFILE)
|
||||
public class CustomObservation extends Observation {
|
||||
|
||||
public static final String PROFILE = "http://custom_Observation";
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.BooleanType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
|
||||
@ResourceDef(name = "Patient", profile = "Patient")
|
||||
public class CustomPatientDstu3 extends Patient {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "homeless", order = 1)
|
||||
@Extension(url = "/StructureDefinition/homeless", definedLocally = true, isModifier = false)
|
||||
@Description(shortDefinition = "The patient being homeless, true if homeless")
|
||||
private BooleanType homeless;
|
||||
|
||||
|
||||
public BooleanType getHomeless() {
|
||||
return homeless;
|
||||
}
|
||||
|
||||
public void setHomeless(final BooleanType homeless) {
|
||||
this.homeless = homeless;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,46 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.Identifier;
|
||||
import org.hl7.fhir.dstu3.model.MessageHeader;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
@ResourceDef(name = "MessageHeader")
|
||||
public class FooMessageHeader extends MessageHeader {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Block()
|
||||
public static class FooMessageSourceComponent extends MessageSourceComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Child(name = "ext-messageheader-application-id", type = Identifier.class, modifier = true)
|
||||
@Description(shortDefinition = "Message Header Application ID")
|
||||
@Extension(url = "http://foo", definedLocally = false, isModifier = false)
|
||||
private Identifier messageHeaderApplicationId;
|
||||
|
||||
/*
|
||||
* Get messageHeaderApplicationId
|
||||
*/
|
||||
public Identifier getMessageHeaderApplicationId() throws FHIRException {
|
||||
|
||||
if (messageHeaderApplicationId == null) {
|
||||
messageHeaderApplicationId = new Identifier();
|
||||
}
|
||||
return messageHeaderApplicationId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set messageHeaderApplicationId
|
||||
*/
|
||||
public void setmessageHeaderApplicationId(Identifier messageHeaderApplicationId) {
|
||||
this.messageHeaderApplicationId = messageHeaderApplicationId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.Identifier;
|
||||
import org.hl7.fhir.dstu3.model.MessageHeader;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
@ResourceDef(name = "FooMessageHeader")
|
||||
public class FooMessageHeaderWithExplicitField extends MessageHeader {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* The source application from which this message originated.
|
||||
*/
|
||||
@Child(name = "source", type = {}, order = Child.REPLACE_PARENT, min = 1, max = 1, modifier = false, summary = true)
|
||||
@Description(shortDefinition = "Message Source Application", formalDefinition = "The source application from which this message originated.")
|
||||
protected FooMessageSourceComponent source;
|
||||
|
||||
public void setSourceNew(FooMessageSourceComponent theSource) {
|
||||
source = theSource;
|
||||
}
|
||||
|
||||
@Block()
|
||||
public static class FooMessageSourceComponent extends MessageSourceComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Child(name = "ext-messageheader-application-id", type = Identifier.class, modifier = true)
|
||||
@Description(shortDefinition = "Message Header Application ID")
|
||||
@Extension(url = "http://foo", definedLocally = false, isModifier = false)
|
||||
private Identifier messageHeaderApplicationId;
|
||||
|
||||
/*
|
||||
* Get messageHeaderApplicationId
|
||||
*/
|
||||
public Identifier getMessageHeaderApplicationId() throws FHIRException {
|
||||
|
||||
if (messageHeaderApplicationId == null) {
|
||||
messageHeaderApplicationId = new Identifier();
|
||||
}
|
||||
return messageHeaderApplicationId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set messageHeaderApplicationId
|
||||
*/
|
||||
public void setmessageHeaderApplicationId(Identifier messageHeaderApplicationId) {
|
||||
this.messageHeaderApplicationId = messageHeaderApplicationId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
|
||||
@ResourceDef()
|
||||
public class MyPatientWithCustomUrlExtension extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "petName")
|
||||
@Extension(url = "/petname", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The name of the patient's favourite pet")
|
||||
private StringType myPetName;
|
||||
|
||||
@Child(name = "customid")
|
||||
@Extension(url = "/customid", definedLocally = false, isModifier = false)
|
||||
@Description(shortDefinition = "The customid of the patient's ")
|
||||
private IdType myCustomId;
|
||||
|
||||
public StringType getPetName() {
|
||||
if (myPetName == null) {
|
||||
myPetName = new StringType();
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
public void setPetName(final StringType thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && getCustomId().isEmpty() && getPetName().isEmpty();
|
||||
}
|
||||
|
||||
public IdType getCustomId() {
|
||||
if (myCustomId == null) {
|
||||
myCustomId = new IdType();
|
||||
}
|
||||
return myCustomId;
|
||||
}
|
||||
|
||||
public void setCustomId(final IdType myCustomId) {
|
||||
this.myCustomId = myCustomId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import java.util.List;
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import org.hl7.fhir.dstu3.model.Address.AddressUse;
|
||||
import org.hl7.fhir.dstu3.model.Enumeration;
|
||||
import org.hl7.fhir.dstu3.model.Identifier;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public class MyPatientWithOneDeclaredEnumerationExtensionDstu3 extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(order = 0, name = "foo")
|
||||
@Extension(url = "urn:foo", definedLocally = true, isModifier = false)
|
||||
private Enumeration<AddressUse> myFoo;
|
||||
|
||||
/**
|
||||
* A contact party (e.g. guardian, partner, friend) for the patient.
|
||||
*/
|
||||
@Child(name = "contact", type = {}, order=Child.REPLACE_PARENT, min=0, max=Child.MAX_UNLIMITED, modifier=false, summary=false)
|
||||
@Description(shortDefinition="A contact party (e.g. guardian, partner, friend) for the patient", formalDefinition="A contact party (e.g. guardian, partner, friend) for the patient." )
|
||||
protected List<ContactComponent> contact;
|
||||
|
||||
public Enumeration<AddressUse> getFoo() {
|
||||
return myFoo;
|
||||
}
|
||||
|
||||
public void setFoo(Enumeration<AddressUse> theFoo) {
|
||||
myFoo = theFoo;
|
||||
}
|
||||
|
||||
@Block()
|
||||
public static class MessageSourceComponent extends ContactComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Child(name = "contact-eyecolour", type = { Identifier.class }, modifier = true)
|
||||
@Description(shortDefinition = "Application ID")
|
||||
@Extension(url = "http://foo.com/contact-eyecolour", definedLocally = false, isModifier = false)
|
||||
private Identifier myEyeColour;
|
||||
|
||||
/*
|
||||
* Get messageHeaderApplicationId
|
||||
*/
|
||||
public Identifier getEyeColour() {
|
||||
if (myEyeColour == null) {
|
||||
myEyeColour = new Identifier();
|
||||
}
|
||||
return myEyeColour;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set messageHeaderApplicationId
|
||||
*/
|
||||
public void setEyeColour(Identifier messageHeaderApplicationId) {
|
||||
this.myEyeColour = messageHeaderApplicationId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.Reference;
|
||||
|
||||
@ResourceDef(name="Patient", profile = "http://hl7.org/fhir/StructureDefinition/Patient")
|
||||
public class PatientProfileDstu3 extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name="owner", min=0, max=1)
|
||||
@Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#owningOrganization", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The organization that owns this animal")
|
||||
private Reference owningOrganization;
|
||||
|
||||
public Reference getOwningOrganization() {
|
||||
if (owningOrganization == null) {
|
||||
owningOrganization = new Reference();
|
||||
}
|
||||
return owningOrganization;
|
||||
}
|
||||
|
||||
public PatientProfileDstu3 setOwningOrganization(Reference owningOrganization) {
|
||||
this.owningOrganization = owningOrganization;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Child(name="colorPrimary", min=0, max=1)
|
||||
@Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorPrimary", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The animals primary color")
|
||||
private CodeableConcept colorPrimary;
|
||||
|
||||
@Child(name="colorSecondary", min=0, max=1)
|
||||
@Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorSecondary", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The animals secondary color")
|
||||
private CodeableConcept colorSecondary;
|
||||
|
||||
public CodeableConcept getColorPrimary() {
|
||||
if (this.colorPrimary == null) {
|
||||
return new CodeableConcept();
|
||||
}
|
||||
return colorPrimary;
|
||||
}
|
||||
|
||||
public void setColorPrimary(CodeableConcept colorPrimary) {
|
||||
this.colorPrimary = colorPrimary;
|
||||
}
|
||||
|
||||
public CodeableConcept getColorSecondary() {
|
||||
if (this.colorSecondary == null) {
|
||||
return new CodeableConcept();
|
||||
}
|
||||
return colorSecondary;
|
||||
}
|
||||
|
||||
public void setColorSecondary(CodeableConcept colorSecondary) {
|
||||
this.colorSecondary = colorSecondary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(owningOrganization) && ElementUtil.isEmpty(colorPrimary)
|
||||
&& ElementUtil.isEmpty(colorSecondary) ;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import org.hl7.fhir.dstu3.model.BackboneElement;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public class PatientWithCustomCompositeExtension extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* A custom extension
|
||||
*/
|
||||
@Child(name = "foo")
|
||||
@Extension(url="http://acme.org/fooParent", definedLocally = false, isModifier = false)
|
||||
protected FooParentExtension fooParentExtension;
|
||||
|
||||
public FooParentExtension getFooParentExtension() {
|
||||
return fooParentExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(fooParentExtension);
|
||||
}
|
||||
|
||||
public void setFooParentExtension(FooParentExtension theFooParentExtension) {
|
||||
fooParentExtension = theFooParentExtension;
|
||||
}
|
||||
|
||||
@Block
|
||||
public static class FooParentExtension extends BackboneElement {
|
||||
|
||||
private static final long serialVersionUID = 4522090347756045145L;
|
||||
|
||||
@Child(name = "childA")
|
||||
@Extension(url = "http://acme.org/fooChildA", definedLocally = false, isModifier = false)
|
||||
private StringType myChildA;
|
||||
|
||||
@Child(name = "childB")
|
||||
@Extension(url = "http://acme.org/fooChildB", definedLocally = false, isModifier = false)
|
||||
private StringType myChildB;
|
||||
|
||||
@Override
|
||||
public FooParentExtension copy() {
|
||||
FooParentExtension copy = new FooParentExtension();
|
||||
copy.myChildA = myChildA;
|
||||
copy.myChildB = myChildB;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(myChildA, myChildB);
|
||||
}
|
||||
|
||||
public StringType getChildA() {
|
||||
return myChildA;
|
||||
}
|
||||
|
||||
public StringType getChildB() {
|
||||
return myChildB;
|
||||
}
|
||||
|
||||
public void setChildA(StringType theChildA) {
|
||||
myChildA = theChildA;
|
||||
}
|
||||
|
||||
public void setChildB(StringType theChildB) {
|
||||
myChildB = theChildB;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,410 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.dstu3;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||
import ca.uhn.fhir.validation.*;
|
||||
import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.dstu3.conformance.ProfileUtilities;
|
||||
import org.hl7.fhir.dstu3.context.IWorkerContext;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_DSTU3;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
public class ResourceValidatorDstu3FeatureTest {
|
||||
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorDstu3FeatureTest.class);
|
||||
private FhirContext ourCtx = FhirContext.forDstu3();
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
HAPI_FHIR_VALIDATION_DSTU3.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
WRAP.option(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private List<SingleValidationMessage> logResultsAndReturnNonInformationalOnes(ValidationResult theOutput) {
|
||||
List<SingleValidationMessage> retVal = new ArrayList<>();
|
||||
|
||||
int index = 0;
|
||||
for (SingleValidationMessage next : theOutput.getMessages()) {
|
||||
ourLog.info("Result {}: {} - {} - {}",
|
||||
new Object[]{index, next.getSeverity(), next.getLocationString(), next.getMessage()});
|
||||
index++;
|
||||
|
||||
if (next.getSeverity() != ResultSeverityEnum.INFORMATION) {
|
||||
retVal.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #50
|
||||
*/
|
||||
@Test
|
||||
public void testOutOfBoundsDate() {
|
||||
Patient p = new Patient();
|
||||
p.setBirthDateElement(new DateType("2000-12-31"));
|
||||
|
||||
// Put in an invalid date
|
||||
IParser parser = ourCtx.newXmlParser();
|
||||
parser.setParserErrorHandler(new StrictErrorHandler());
|
||||
|
||||
String encoded = parser.setPrettyPrint(true).encodeResourceToString(p).replace("2000-12-31", "2000-15-31");
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, StringContains.containsString("2000-15-31"));
|
||||
|
||||
ValidationResult result = ourCtx.newValidator().validateWithResult(encoded);
|
||||
String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(resultString);
|
||||
|
||||
assertEquals(2, ((OperationOutcome) result.toOperationOutcome()).getIssue().size());
|
||||
assertThat(resultString, StringContains.containsString("cvc-pattern-valid"));
|
||||
|
||||
try {
|
||||
parser.parseResource(encoded);
|
||||
fail();
|
||||
} catch (DataFormatException e) {
|
||||
assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Invalid attribute value \"2000-15-31\": Invalid date/time format: \"2000-15-31\"", e.getMessage());
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testValidateCareTeamXsd() {
|
||||
CareTeam careTeam = new CareTeam();
|
||||
careTeam
|
||||
.addParticipant()
|
||||
.setMember(new Reference("http://example.com/Practitioner/1647bbb2-3b12-43cc-923c-a475f817e881"))
|
||||
.setOnBehalfOf(new Reference("Organization/5859a28f-01e7-42d8-a8ba-48b31679a828"));
|
||||
|
||||
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
String encoded = parser.encodeResourceToString(careTeam);
|
||||
|
||||
ourLog.info(encoded);
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
|
||||
ValidationResult result = val.validateWithResult(encoded);
|
||||
String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
|
||||
ourLog.info(resultString);
|
||||
|
||||
assertThat(resultString, containsString("No issues detected during validation"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCodeableConceptContainingOnlyBadCode() {
|
||||
Patient p = new Patient();
|
||||
p.getMaritalStatus().addCoding().setSystem("http://hl7.org/fhir/v3/MaritalStatus").setCode("FOO");
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
ValidationResult output = val.validateWithResult(p);
|
||||
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output);
|
||||
|
||||
assertEquals("None of the codes provided are in the value set http://hl7.org/fhir/ValueSet/marital-status (http://hl7.org/fhir/ValueSet/marital-status, and a code should come from this value set unless it has no suitable code) (codes = http://hl7.org/fhir/v3/MaritalStatus#FOO)", output.getMessages().get(0).getMessage());
|
||||
assertEquals(ResultSeverityEnum.WARNING, output.getMessages().get(0).getSeverity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCodeableConceptContainingOnlyGoodCode() {
|
||||
Patient p = new Patient();
|
||||
p.getMaritalStatus().addCoding().setSystem("http://hl7.org/fhir/v3/MaritalStatus").setCode("M");
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
ValidationResult output = val.validateWithResult(p);
|
||||
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output);
|
||||
assertEquals(0, all.size());
|
||||
assertEquals(0, output.getMessages().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateJsonNumericId() {
|
||||
String input = "{\"resourceType\": \"Patient\",\n" +
|
||||
" \"id\": 123,\n" +
|
||||
" \"meta\": {\n" +
|
||||
" \"versionId\": \"29\",\n" +
|
||||
" \"lastUpdated\": \"2015-12-22T19:53:11.000Z\"\n" +
|
||||
" },\n" +
|
||||
" \"communication\": {\n" +
|
||||
" \"language\": {\n" +
|
||||
" \"coding\": [\n" +
|
||||
" {\n" +
|
||||
" \"system\": \"urn:ietf:bcp:47\",\n" +
|
||||
" \"code\": \"hi\",\n" +
|
||||
" \"display\": \"Hindi\",\n" +
|
||||
" \"userSelected\": false\n" +
|
||||
" }],\n" +
|
||||
" \"text\": \"Hindi\"\n" +
|
||||
" },\n" +
|
||||
" \"preferred\": true\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
ValidationResult output = val.validateWithResult(input);
|
||||
|
||||
OperationOutcome operationOutcome = (OperationOutcome) output.toOperationOutcome();
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
|
||||
// ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, containsString("Error parsing JSON: the primitive value must be a string"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateQuestionnaireWithCanonicalUrl() {
|
||||
String input = "{\n" +
|
||||
" \"resourceType\": \"Questionnaire\",\n" +
|
||||
" \"url\": \"http://some.example.url\",\n" +
|
||||
" \"status\": \"active\",\n" +
|
||||
" \"subjectType\": [\n" +
|
||||
" \"Patient\"\n" +
|
||||
" ],\n" +
|
||||
" \"item\": [\n" +
|
||||
" {\n" +
|
||||
" \"linkId\": \"example-question\",\n" +
|
||||
" \"text\": \"Is the sky blue?\",\n" +
|
||||
" \"type\": \"choice\",\n" +
|
||||
" \"options\": {\n" +
|
||||
" \"reference\": \"http://loinc.org/vs/LL3044-6\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
|
||||
Questionnaire q = new Questionnaire();
|
||||
q = ourCtx.newJsonParser().parseResource(Questionnaire.class, input);
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
ValidationResult result = val.validateWithResult(q);
|
||||
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
|
||||
ourLog.info(encoded);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the elements that appear in all resources (meta, language, extension, etc) all appear in the correct order
|
||||
*/
|
||||
@Test
|
||||
public void testValidateResourceWithResourceElements() {
|
||||
TestPatientFor327 patient = new TestPatientFor327();
|
||||
patient.setBirthDate(new Date());
|
||||
patient.setId("123");
|
||||
patient.getText().setDivAsString("<div>FOO</div>");
|
||||
patient.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
|
||||
patient.getLanguageElement().setValue("en");
|
||||
patient.addExtension().setUrl("http://foo").setValue(new StringType("MOD"));
|
||||
patient.getMeta().setLastUpdated(new Date());
|
||||
|
||||
List<Reference> conditions = new ArrayList<Reference>();
|
||||
Condition condition = new Condition();
|
||||
condition.getSubject().setReference("Patient/123");
|
||||
condition.addBodySite().setText("BODY SITE");
|
||||
condition.getCode().setText("CODE");
|
||||
condition.setClinicalStatus(Condition.ConditionClinicalStatus.ACTIVE);
|
||||
condition.setVerificationStatus(Condition.ConditionVerificationStatus.CONFIRMED);
|
||||
conditions.add(new Reference(condition));
|
||||
patient.setCondition(conditions);
|
||||
patient.addIdentifier().setSystem("http://foo").setValue("123");
|
||||
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
ourLog.info(encoded);
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
ValidationResult result = val.validateWithResult(encoded);
|
||||
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
String ooencoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
|
||||
ourLog.info(ooencoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
|
||||
assertThat(ooencoded, containsString("Unknown extension http://foo"));
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium= email&utm_source=footer
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithExtensionsJson() {
|
||||
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
|
||||
myPatient.setId("1");
|
||||
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
|
||||
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-white")));
|
||||
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
|
||||
myPatient.addName().setFamily("FamilyName");
|
||||
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
|
||||
|
||||
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
String messageString = p.encodeResourceToString(myPatient);
|
||||
// ourLog.info(messageString);
|
||||
|
||||
String[] strings = {"meta",
|
||||
"String Extension",
|
||||
"Organization/2.25.79433498044103547197447759549862032393",
|
||||
"furry-grey",
|
||||
"furry-white",
|
||||
"FamilyName"};
|
||||
assertThat(messageString, stringContainsInOrder(
|
||||
Arrays.asList(strings)
|
||||
));
|
||||
String[] strings1 = {"extension",
|
||||
"meta"};
|
||||
assertThat(messageString, not(stringContainsInOrder(
|
||||
Arrays.asList(strings1)
|
||||
)));
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
ValidationResult result = val.validateWithResult(messageString);
|
||||
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
|
||||
assertThat(messageString, containsString("valueReference"));
|
||||
assertThat(messageString, not(containsString("valueResource")));
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium= email&utm_source=footer
|
||||
*/
|
||||
@Test
|
||||
public void testValidateWithExtensionsXml() {
|
||||
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
|
||||
myPatient.setId("1");
|
||||
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
|
||||
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-white")));
|
||||
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
|
||||
myPatient.addName().setFamily("FamilyName");
|
||||
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
|
||||
|
||||
IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
String messageString = p.encodeResourceToString(myPatient);
|
||||
ourLog.info(messageString);
|
||||
|
||||
//@formatter:off
|
||||
String[] strings = {"meta",
|
||||
"Organization/2.25.79433498044103547197447759549862032393",
|
||||
"furry-grey",
|
||||
"furry-white",
|
||||
"String Extension",
|
||||
"FamilyName"};
|
||||
assertThat(messageString, stringContainsInOrder(
|
||||
Arrays.asList(strings)
|
||||
));
|
||||
String[] strings1 = {"extension",
|
||||
"meta"};
|
||||
assertThat(messageString, not(stringContainsInOrder(
|
||||
Arrays.asList(strings1)
|
||||
)));
|
||||
assertThat(messageString, containsString("url=\"http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorSecondary\""));
|
||||
assertThat(messageString, containsString("url=\"http://foo.com/example\""));
|
||||
//@formatter:on
|
||||
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
|
||||
val.registerValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
ValidationResult result = val.validateWithResult(messageString);
|
||||
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertTrue(result.isSuccessful());
|
||||
|
||||
assertThat(messageString, containsString("valueReference"));
|
||||
assertThat(messageString, not(containsString("valueResource")));
|
||||
}
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
public static class TestPatientFor327 extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "testCondition")
|
||||
@ca.uhn.fhir.model.api.annotation.Extension(url = "testCondition", definedLocally = true, isModifier = false)
|
||||
private List<Reference> testConditions = null;
|
||||
|
||||
public List<Reference> getConditions() {
|
||||
return this.testConditions;
|
||||
}
|
||||
|
||||
public void setCondition(List<Reference> ref) {
|
||||
this.testConditions = ref;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.r4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
|
||||
import org.hl7.fhir.r4.model.Base;
|
||||
import org.hl7.fhir.r4.model.BooleanType;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.r4.utils.FHIRPathEngine;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_R4;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
public class FhirInstanceValidatorR4Test {
|
||||
|
||||
private FhirContext ourCtx = FhirContext.forR4();
|
||||
private FHIRPathEngine ourEngine = new FHIRPathEngine(new HapiWorkerContext(ourCtx, new DefaultProfileValidationSupport()));
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirInstanceValidatorR4Test.class);
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
HAPI_FHIR_VALIDATION_R4.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
WRAP.option(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAs() throws Exception {
|
||||
Observation obs = new Observation();
|
||||
obs.setValue(new StringType("FOO"));
|
||||
|
||||
List<Base> value = ourEngine.evaluate(obs, "Observation.value.as(String)");
|
||||
assertEquals(1, value.size());
|
||||
assertEquals("FOO", ((StringType)value.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsWithNoValue() throws FHIRException {
|
||||
Patient patient = new Patient();
|
||||
patient.setDeceased(new BooleanType());
|
||||
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
|
||||
ourLog.info(eval.toString());
|
||||
assertFalse(((BooleanType)eval.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsWithValue() throws FHIRException {
|
||||
Patient patient = new Patient();
|
||||
patient.setDeceased(new BooleanType(false));
|
||||
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
|
||||
ourLog.info(eval.toString());
|
||||
assertTrue(((BooleanType)eval.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenation() throws FHIRException {
|
||||
String exp = "Patient.name.family & '.'";
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("TEST");
|
||||
String result = ourEngine.evaluateToString(p, exp);
|
||||
assertEquals("TEST.", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcatenationFunction() throws FHIRException {
|
||||
String exp = "element.first().path.startsWith(%resource.type) and element.tail().all(path.startsWith(%resource.type&'.'))";
|
||||
|
||||
StructureDefinition sd = new StructureDefinition();
|
||||
StructureDefinition.StructureDefinitionDifferentialComponent diff = sd.getDifferential();
|
||||
|
||||
diff.addElement().setPath("Patient.name");
|
||||
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("TEST");
|
||||
List<Base> result = ourEngine.evaluate(null, p, diff, exp);
|
||||
ourLog.info(result.toString());
|
||||
// assertEquals("TEST.", result);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.r4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Extension;
|
||||
import org.hl7.fhir.r4.model.Medication;
|
||||
import org.hl7.fhir.r4.model.MedicationDispense;
|
||||
import org.hl7.fhir.r4.model.MedicationRequest;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_R4;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
public class R4JsonParserTest {
|
||||
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(R4JsonParserTest.class);
|
||||
private FhirContext ourCtx = FhirContext.forR4();
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
WRAP.option(),
|
||||
HAPI_FHIR_R4.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
|
||||
private Bundle createBundleWithPatient() {
|
||||
Bundle b = new Bundle();
|
||||
b.setId("BUNDLEID");
|
||||
b.getMeta().addProfile("http://FOO");
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setId("PATIENTID");
|
||||
p.getMeta().addProfile("http://BAR");
|
||||
p.addName().addGiven("GIVEN");
|
||||
b.addEntry().setResource(p);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* See #814
|
||||
*/
|
||||
@Test
|
||||
public void testDuplicateContainedResourcesNotOutputtedTwice() {
|
||||
MedicationDispense md = new MedicationDispense();
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
md.addAuthorizingPrescription().setResource(mr);
|
||||
|
||||
Medication med = new Medication();
|
||||
md.setMedication(new Reference(med));
|
||||
mr.setMedication(new Reference(med));
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(md);
|
||||
ourLog.info(encoded);
|
||||
|
||||
int idx = encoded.indexOf("\"Medication\"");
|
||||
assertNotEquals(-1, idx);
|
||||
|
||||
idx = encoded.indexOf("\"Medication\"", idx + 1);
|
||||
assertEquals(-1, idx);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #814
|
||||
*/
|
||||
@Test
|
||||
public void testDuplicateContainedResourcesNotOutputtedTwiceWithManualIds() {
|
||||
MedicationDispense md = new MedicationDispense();
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.setId("#MR");
|
||||
md.addAuthorizingPrescription().setResource(mr);
|
||||
|
||||
Medication med = new Medication();
|
||||
med.setId("#MED");
|
||||
md.setMedication(new Reference(med));
|
||||
mr.setMedication(new Reference(med));
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(md);
|
||||
ourLog.info(encoded);
|
||||
|
||||
int idx = encoded.indexOf("\"Medication\"");
|
||||
assertNotEquals(-1, idx);
|
||||
|
||||
idx = encoded.indexOf("\"Medication\"", idx + 1);
|
||||
assertEquals(-1, idx);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeNothing() {
|
||||
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
Set<String> excludes = new HashSet<>();
|
||||
// excludes.add("*.id");
|
||||
parser.setDontEncodeElements(excludes);
|
||||
|
||||
Bundle b = createBundleWithPatient();
|
||||
|
||||
String encoded = parser.encodeResourceToString(b);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, containsString("BUNDLEID"));
|
||||
assertThat(encoded, containsString("http://FOO"));
|
||||
assertThat(encoded, containsString("PATIENTID"));
|
||||
assertThat(encoded, containsString("http://BAR"));
|
||||
assertThat(encoded, containsString("GIVEN"));
|
||||
|
||||
b = parser.parseResource(Bundle.class, encoded);
|
||||
|
||||
assertEquals("BUNDLEID", b.getIdElement().getIdPart());
|
||||
assertEquals("Patient/PATIENTID", ((Patient) b.getEntry().get(0).getResource()).getId());
|
||||
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeRootStuff() {
|
||||
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
Set<String> excludes = new HashSet<>();
|
||||
excludes.add("id");
|
||||
excludes.add("meta");
|
||||
parser.setDontEncodeElements(excludes);
|
||||
|
||||
Bundle b = createBundleWithPatient();
|
||||
|
||||
String encoded = parser.encodeResourceToString(b);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, not(containsString("BUNDLEID")));
|
||||
assertThat(encoded, not(containsString("http://FOO")));
|
||||
assertThat(encoded, (containsString("PATIENTID")));
|
||||
assertThat(encoded, (containsString("http://BAR")));
|
||||
assertThat(encoded, containsString("GIVEN"));
|
||||
|
||||
b = parser.parseResource(Bundle.class, encoded);
|
||||
|
||||
assertNotEquals("BUNDLEID", b.getIdElement().getIdPart());
|
||||
assertEquals("Patient/PATIENTID", ((Patient) b.getEntry().get(0).getResource()).getId());
|
||||
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeStarDotStuff() {
|
||||
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
Set<String> excludes = new HashSet<>();
|
||||
excludes.add("*.id");
|
||||
excludes.add("*.meta");
|
||||
parser.setDontEncodeElements(excludes);
|
||||
|
||||
Bundle b = createBundleWithPatient();
|
||||
|
||||
String encoded = parser.encodeResourceToString(b);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, not(containsString("BUNDLEID")));
|
||||
assertThat(encoded, not(containsString("http://FOO")));
|
||||
assertThat(encoded, not(containsString("PATIENTID")));
|
||||
assertThat(encoded, not(containsString("http://BAR")));
|
||||
assertThat(encoded, containsString("GIVEN"));
|
||||
|
||||
b = parser.parseResource(Bundle.class, encoded);
|
||||
|
||||
assertNotEquals("BUNDLEID", b.getIdElement().getIdPart());
|
||||
assertNotEquals("Patient/PATIENTID", ((Patient) b.getEntry().get(0).getResource()).getId());
|
||||
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that long JSON strings don't get broken up
|
||||
*/
|
||||
@Test
|
||||
public void testNoBreakInLongString() {
|
||||
String longString = StringUtils.leftPad("", 100000, 'A');
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily(longString);
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
||||
|
||||
assertThat(encoded, containsString(longString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeExtensionWithValueWithExtension() {
|
||||
String input = "{\n" +
|
||||
" \"resourceType\": \"Patient\",\n" +
|
||||
" \"extension\": [\n" +
|
||||
" {\n" +
|
||||
" \"url\": \"https://purl.org/elab/fhir/network/StructureDefinition/1/BirthWeight\",\n" +
|
||||
" \"_valueDecimal\": {\n" +
|
||||
" \"extension\": [\n" +
|
||||
" {\n" +
|
||||
" \"url\": \"http://www.hl7.org/fhir/extension-data-absent-reason.html\",\n" +
|
||||
" \"valueCoding\": {\n" +
|
||||
" \"system\": \"http://hl7.org/fhir/ValueSet/birthweight\",\n" +
|
||||
" \"code\": \"Underweight\",\n" +
|
||||
" \"userSelected\": false\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" \"identifier\": [\n" +
|
||||
" {\n" +
|
||||
" \"system\": \"https://purl.org/elab/fhir/network/StructureDefinition/1/EuroPrevallStudySubjects\",\n" +
|
||||
" \"value\": \"1\"\n" +
|
||||
" }\n" +
|
||||
" ],\n" +
|
||||
" \"gender\": \"female\"\n" +
|
||||
"}";
|
||||
|
||||
IParser jsonParser = ourCtx.newJsonParser();
|
||||
IParser xmlParser = ourCtx.newXmlParser();
|
||||
jsonParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
|
||||
xmlParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
|
||||
|
||||
Patient parsed = jsonParser.parseResource(Patient.class, input);
|
||||
|
||||
ourLog.info(jsonParser.setPrettyPrint(true).encodeResourceToString(parsed));
|
||||
assertThat(xmlParser.encodeResourceToString(parsed), containsString("Underweight"));
|
||||
assertThat(jsonParser.encodeResourceToString(parsed), containsString("Underweight"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseExtensionOnPrimitive() throws IOException {
|
||||
String input = IOUtils.toString(R4JsonParserTest.class.getResourceAsStream("/extension-on-line.txt"));
|
||||
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
|
||||
Patient pt = parser.parseResource(Patient.class, input);
|
||||
|
||||
StringType line0 = pt.getAddressFirstRep().getLine().get(0);
|
||||
assertEquals("535 Sheppard Avenue West, Unit 1907", line0.getValue());
|
||||
Extension houseNumberExt = line0.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber");
|
||||
assertEquals("535", ((StringType) houseNumberExt.getValue()).getValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
package ca.uhn.fhir.tests.integration.karaf.r4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.hamcrest.core.IsNot;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Configuration;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.junit.PaxExam;
|
||||
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
|
||||
import org.ops4j.pax.exam.spi.reactors.PerClass;
|
||||
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_R4;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
|
||||
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.options;
|
||||
import static org.ops4j.pax.exam.CoreOptions.when;
|
||||
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
|
||||
|
||||
|
||||
/**
|
||||
* Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
|
||||
*/
|
||||
@RunWith(PaxExam.class)
|
||||
@ExamReactorStrategy(PerClass.class)
|
||||
public class R4XmlParserTest {
|
||||
|
||||
private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(R4XmlParserTest.class);
|
||||
private FhirContext ourCtx = FhirContext.forR4();
|
||||
|
||||
@Configuration
|
||||
public Option[] config() throws IOException {
|
||||
return options(
|
||||
KARAF.option(),
|
||||
WRAP.option(),
|
||||
HAPI_FHIR_R4.option(),
|
||||
mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
|
||||
when(false)
|
||||
.useOptions(
|
||||
debugConfiguration("5005", true))
|
||||
);
|
||||
}
|
||||
private Bundle createBundleWithPatient() {
|
||||
Bundle b = new Bundle();
|
||||
b.setId("BUNDLEID");
|
||||
b.getMeta().addProfile("http://FOO");
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setId("PATIENTID");
|
||||
p.getMeta().addProfile("http://BAR");
|
||||
p.addName().addGiven("GIVEN");
|
||||
b.addEntry().setResource(p);
|
||||
return b;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeXmlNumericEntity() {
|
||||
String input = "<Patient xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
" <name>\n" +
|
||||
" <family value=\"A 
 B\"/>\n" +
|
||||
" </name>\n" +
|
||||
"</Patient>";
|
||||
|
||||
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, input);
|
||||
assertEquals("A \n B", p.getNameFirstRep().getFamily());
|
||||
|
||||
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
|
||||
ourLog.info(output);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeNothing() {
|
||||
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
Set<String> excludes = new HashSet<>();
|
||||
// excludes.add("*.id");
|
||||
parser.setDontEncodeElements(excludes);
|
||||
|
||||
Bundle b = createBundleWithPatient();
|
||||
|
||||
String encoded = parser.encodeResourceToString(b);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, containsString("BUNDLEID"));
|
||||
assertThat(encoded, containsString("http://FOO"));
|
||||
assertThat(encoded, containsString("PATIENTID"));
|
||||
assertThat(encoded, containsString("http://BAR"));
|
||||
assertThat(encoded, containsString("GIVEN"));
|
||||
|
||||
b = parser.parseResource(Bundle.class, encoded);
|
||||
|
||||
assertEquals("BUNDLEID", b.getIdElement().getIdPart());
|
||||
assertEquals("Patient/PATIENTID", ((Patient) b.getEntry().get(0).getResource()).getId());
|
||||
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeRootStuff() {
|
||||
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
Set<String> excludes = new HashSet<>();
|
||||
excludes.add("id");
|
||||
excludes.add("meta");
|
||||
parser.setDontEncodeElements(excludes);
|
||||
|
||||
Bundle b = createBundleWithPatient();
|
||||
|
||||
String encoded = parser.encodeResourceToString(b);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, IsNot.not(containsString("BUNDLEID")));
|
||||
assertThat(encoded, IsNot.not(containsString("http://FOO")));
|
||||
assertThat(encoded, (containsString("PATIENTID")));
|
||||
assertThat(encoded, (containsString("http://BAR")));
|
||||
assertThat(encoded, containsString("GIVEN"));
|
||||
|
||||
b = parser.parseResource(Bundle.class, encoded);
|
||||
|
||||
assertNotEquals("BUNDLEID", b.getIdElement().getIdPart());
|
||||
assertEquals("Patient/PATIENTID", ((Patient) b.getEntry().get(0).getResource()).getId());
|
||||
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcludeStarDotStuff() {
|
||||
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
Set<String> excludes = new HashSet<>();
|
||||
excludes.add("*.id");
|
||||
excludes.add("*.meta");
|
||||
parser.setDontEncodeElements(excludes);
|
||||
|
||||
Bundle b = createBundleWithPatient();
|
||||
|
||||
String encoded = parser.encodeResourceToString(b);
|
||||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, IsNot.not(containsString("BUNDLEID")));
|
||||
assertThat(encoded, IsNot.not(containsString("http://FOO")));
|
||||
assertThat(encoded, IsNot.not(containsString("PATIENTID")));
|
||||
assertThat(encoded, IsNot.not(containsString("http://BAR")));
|
||||
assertThat(encoded, containsString("GIVEN"));
|
||||
|
||||
b = parser.parseResource(Bundle.class, encoded);
|
||||
|
||||
assertNotEquals("BUNDLEID", b.getIdElement().getIdPart());
|
||||
assertNotEquals("Patient/PATIENTID", ((Patient) b.getEntry().get(0).getResource()).getId());
|
||||
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndEncodeExtensionWithValueWithExtension() {
|
||||
String input = "<Patient xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
" <extension url=\"https://purl.org/elab/fhir/network/StructureDefinition/1/BirthWeight\">\n" +
|
||||
" <valueDecimal>\n" +
|
||||
" <extension url=\"http://www.hl7.org/fhir/extension-data-absent-reason.html\">\n" +
|
||||
" <valueCoding>\n" +
|
||||
" <system value=\"http://hl7.org/fhir/ValueSet/birthweight\"/>\n" +
|
||||
" <code value=\"Underweight\"/>\n" +
|
||||
" <userSelected value=\"false\"/>\n" +
|
||||
" </valueCoding>\n" +
|
||||
" </extension>\n" +
|
||||
" </valueDecimal>\n" +
|
||||
" </extension>\n" +
|
||||
" <identifier>\n" +
|
||||
" <system value=\"https://purl.org/elab/fhir/network/StructureDefinition/1/EuroPrevallStudySubjects\"/>\n" +
|
||||
" <value value=\"1\"/>\n" +
|
||||
" </identifier>\n" +
|
||||
" <gender value=\"female\"/>\n" +
|
||||
"</Patient>";
|
||||
|
||||
IParser xmlParser = ourCtx.newXmlParser();
|
||||
IParser jsonParser = ourCtx.newJsonParser();
|
||||
jsonParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
|
||||
xmlParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
|
||||
|
||||
Patient parsed = xmlParser.parseResource(Patient.class, input);
|
||||
|
||||
ourLog.info(jsonParser.setPrettyPrint(true).encodeResourceToString(parsed));
|
||||
assertThat(xmlParser.encodeResourceToString(parsed), containsString("Underweight"));
|
||||
assertThat(jsonParser.encodeResourceToString(parsed), containsString("Underweight"));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"resourceType": "Bundle",
|
||||
"id": "example",
|
||||
"meta": {
|
||||
"versionId": "1",
|
||||
"lastUpdated": "2014-08-18T01:43:30Z"
|
||||
},
|
||||
"type": "searchset",
|
||||
"total": 3,
|
||||
"link": [
|
||||
{
|
||||
"relation": "next",
|
||||
"url": "https://example.com/base/MedicationOrder?patient=347&searchId=ff15fd40-ff71-4b48-b366-09c706bed9d0&page=2"
|
||||
},
|
||||
{
|
||||
"relation": "self",
|
||||
"url": "https://example.com/base/MedicationOrder?patient=347&_include=MedicationOrder.medication"
|
||||
}
|
||||
],
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "http://example.com/base/MedicationOrder/3123/_history/1",
|
||||
"resource": {
|
||||
"resourceType": "MedicationOrder",
|
||||
"id": "3123",
|
||||
"meta" : {
|
||||
"versionId" : "1",
|
||||
"lastUpdated" : "2014-08-16T05:31:17Z"
|
||||
},
|
||||
"patient": {
|
||||
"reference": "Patient/347"
|
||||
},
|
||||
"medicationReference": {
|
||||
"reference": "Medication/example"
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"mode": "match",
|
||||
"score": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"fullUrl": "http://example.com/base/Medication/example",
|
||||
"resource": {
|
||||
"resourceType": "Medication",
|
||||
"id": "example"
|
||||
},
|
||||
"search": {
|
||||
"mode": "include"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<Bundle
|
||||
xmlns="http://hl7.org/fhir">
|
||||
<id value="487d3669-0e1c-4867-b124-400d1849548d"></id>
|
||||
<type value="searchset"></type>
|
||||
<base value="http://localhost:19080/fhir/dstu1"></base>
|
||||
<link>
|
||||
<relation value="just trying add link"></relation>
|
||||
<url value="blarion"></url>
|
||||
</link>
|
||||
<link>
|
||||
<relation value="self"></relation>
|
||||
<url value="http://localhost:19080/fhir/dstu1/Observation?subject.identifier=puppet|CLONE-AA102"></url>
|
||||
</link>
|
||||
<entry>
|
||||
<link>
|
||||
<relation value="orionhealth.edit"></relation>
|
||||
<url value="Observation"></url>
|
||||
</link>
|
||||
<resource>
|
||||
<Observation
|
||||
xmlns="http://hl7.org/fhir">
|
||||
<id value="0d87f02c-da2c-4551-9ead-2956f0165a4f"></id>
|
||||
<extension url="http://orionhealth.com/fhir/extensions#created-by"></extension>
|
||||
<extension url="http://orionhealth.com/fhir/extensions#last-modified-by"></extension>
|
||||
<extension url="http://orionhealth.com/fhir/extensions#received-instant">
|
||||
<valueInstant value="2015-06-25T17:08:47.190+12:00"></valueInstant>
|
||||
</extension>
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"></system>
|
||||
<code value="8867-4"></code>
|
||||
</coding>
|
||||
</code>
|
||||
<valueString value="observationValue"></valueString>
|
||||
<status value="final"></status>
|
||||
<reliability value="ok"></reliability>
|
||||
<subject>
|
||||
<reference value="Patient/INGE6TSFFVAUCMJQGJAHA5LQOBSXI"></reference>
|
||||
</subject>
|
||||
</Observation>
|
||||
</resource>
|
||||
</entry>
|
||||
<entry>
|
||||
<link>
|
||||
<relation value="orionhealth.edit"></relation>
|
||||
<url value="Observation"></url>
|
||||
</link>
|
||||
<resource>
|
||||
<Observation
|
||||
xmlns="http://hl7.org/fhir">
|
||||
<id value="c54ac0cc-a99f-40aa-9541-c5aa853a2e88"></id>
|
||||
<extension url="http://orionhealth.com/fhir/extensions#created-by"></extension>
|
||||
<extension url="http://orionhealth.com/fhir/extensions#last-modified-by"></extension>
|
||||
<extension url="http://orionhealth.com/fhir/extensions#received-instant">
|
||||
<valueInstant value="2015-06-25T17:08:47.190+12:00"></valueInstant>
|
||||
</extension>
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"></system>
|
||||
<code value="3141-9"></code>
|
||||
</coding>
|
||||
</code>
|
||||
<valueString value="observationValue"></valueString>
|
||||
<status value="final"></status>
|
||||
<reliability value="ok"></reliability>
|
||||
<subject>
|
||||
<reference value="Patient/INGE6TSFFVAUCMJQGJAHA5LQOBSXI"></reference>
|
||||
</subject>
|
||||
</Observation>
|
||||
</resource>
|
||||
</entry>
|
||||
</Bundle>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,77 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="fe7ff16d-8bdf-47a5-9de3-20165c6fe440" />
|
||||
<meta>
|
||||
<lastUpdated value="2016-08-25T12:17:12.159-04:00" />
|
||||
</meta>
|
||||
<type value="searchset" />
|
||||
<total value="208" />
|
||||
<link>
|
||||
<relation value="self" />
|
||||
<url value="http://foo.uhn.on.ca:25180/uhn-fhir-service-2.1/DiagnosticReport?_format=xml&_include=DiagnosticReport%3Aencounter&_include=Encounter%3AfacilityLocation&_include=Observation%3Aperformer&_include=DiagnosticReport%3Aresult&_include=Encounter%3Alocation&_include=Location.partOf&_include=Encounter%3Aparticipant&_include=DiagnosticReport%3Apatient&subject%3Aidentifier=urn%3Aoid%3A2.16.840.1.113883.3.239.18.148%7C7000135" />
|
||||
</link>
|
||||
<entry>
|
||||
<fullUrl value="http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-2.1/DiagnosticReport/7162221" />
|
||||
<resource>
|
||||
<DiagnosticReport xmlns="http://hl7.org/fhir">
|
||||
<id value="7162221" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/diagnosticreport" />
|
||||
</meta>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="10017.1" />
|
||||
</coding>
|
||||
<text value="Date Dictated" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<valueString value="Fri, 26 Sep 2014" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="N" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<extension url="http://fhir.uhn.ca/Profile/diagnosticreport#source_system_status">
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<identifier>
|
||||
<system value="urn:uhn:qcpr:order_ids" />
|
||||
<value value="GI93#discharge_5677961273802d07ad7d079141525bba" />
|
||||
</identifier>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.5" />
|
||||
<code value="5053" />
|
||||
</coding>
|
||||
<text value="Unscheduled Discharge Summary" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<encounter>
|
||||
<reference value="Encounter/5885735" />
|
||||
</encounter>
|
||||
<effectiveDateTime value="2014-09-26T11:55:00-04:00" />
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
</DiagnosticReport>
|
||||
</resource>
|
||||
</entry>
|
||||
</Bundle>
|
|
@ -0,0 +1,50 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="fe7ff16d-8bdf-47a5-9de3-20165c6fe440" />
|
||||
<meta>
|
||||
<lastUpdated value="2016-08-25T12:17:12.159-04:00" />
|
||||
</meta>
|
||||
<type value="searchset" />
|
||||
<total value="208" />
|
||||
<link>
|
||||
<relation value="self" />
|
||||
<url value="http://foo.uhn.on.ca:25180/uhn-fhir-service-2.1/DiagnosticReport?_format=xml&_include=DiagnosticReport%3Aencounter&_include=Encounter%3AfacilityLocation&_include=Observation%3Aperformer&_include=DiagnosticReport%3Aresult&_include=Encounter%3Alocation&_include=Location.partOf&_include=Encounter%3Aparticipant&_include=DiagnosticReport%3Apatient&subject%3Aidentifier=urn%3Aoid%3A2.16.840.1.113883.3.239.18.148%7C7000135" />
|
||||
</link>
|
||||
<entry>
|
||||
<fullUrl value="http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-2.1/DiagnosticReport/7162221" />
|
||||
<resource>
|
||||
<DiagnosticReport xmlns="http://hl7.org/fhir">
|
||||
<id value="7162221" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/diagnosticreport" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/diagnosticreport#source_system_status">
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<identifier>
|
||||
<system value="urn:uhn:qcpr:order_ids" />
|
||||
<value value="GI93#discharge_5677961273802d07ad7d079141525bba" />
|
||||
</identifier>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.5" />
|
||||
<code value="5053" />
|
||||
</coding>
|
||||
<text value="Unscheduled Discharge Summary" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<encounter>
|
||||
<reference value="Encounter/5885735" />
|
||||
</encounter>
|
||||
<effectiveDateTime value="2014-09-26T11:55:00-04:00" />
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<result>
|
||||
<reference value="#1" />
|
||||
</result>
|
||||
</DiagnosticReport>
|
||||
</resource>
|
||||
</entry>
|
||||
</Bundle>
|
|
@ -0,0 +1,317 @@
|
|||
<Bundle xmlns="http://hl7.org/fhir">
|
||||
<id value="fe7ff16d-8bdf-47a5-9de3-20165c6fe440" />
|
||||
<meta>
|
||||
<lastUpdated value="2016-08-25T12:17:12.159-04:00" />
|
||||
</meta>
|
||||
<type value="searchset" />
|
||||
<total value="208" />
|
||||
<link>
|
||||
<relation value="self" />
|
||||
<url value="http://foo.uhn.on.ca:25180/uhn-fhir-service-2.1/DiagnosticReport?_format=xml&_include=DiagnosticReport%3Aencounter&_include=Encounter%3AfacilityLocation&_include=Observation%3Aperformer&_include=DiagnosticReport%3Aresult&_include=Encounter%3Alocation&_include=Location.partOf&_include=Encounter%3Aparticipant&_include=DiagnosticReport%3Apatient&subject%3Aidentifier=urn%3Aoid%3A2.16.840.1.113883.3.239.18.148%7C7000135" />
|
||||
</link>
|
||||
<entry>
|
||||
<fullUrl value="http://uhnvesb01d.uhn.on.ca:25180/uhn-fhir-service-2.1/DiagnosticReport/7162221" />
|
||||
<resource>
|
||||
<DiagnosticReport xmlns="http://hl7.org/fhir">
|
||||
<id value="7162221" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/diagnosticreport" />
|
||||
</meta>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="1" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="10017.1" />
|
||||
</coding>
|
||||
<text value="Date Dictated" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<valueString value="Fri, 26 Sep 2014" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="N" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="2" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="1126527.2" />
|
||||
</coding>
|
||||
<text value="Dictated by" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<performer>
|
||||
<reference value="#3" />
|
||||
</performer>
|
||||
<valueString value="Gered Trystan King" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="normal" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<contained>
|
||||
<Practitioner xmlns="http://hl7.org/fhir">
|
||||
<id value="3" />
|
||||
<identifier>
|
||||
<system value="urn:uhn:qcpr:user_ids" />
|
||||
<value value="160920" />
|
||||
</identifier>
|
||||
<name>
|
||||
<family value="Gered Trystan King" />
|
||||
</name>
|
||||
</Practitioner>
|
||||
</contained>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="4" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="14002.3" />
|
||||
</coding>
|
||||
<text value="Attending/Staff" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<performer>
|
||||
<reference value="#5" />
|
||||
</performer>
|
||||
<valueString value="Gered Trystan King" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="normal" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<contained>
|
||||
<Practitioner xmlns="http://hl7.org/fhir">
|
||||
<id value="5" />
|
||||
<identifier>
|
||||
<system value="urn:uhn:qcpr:user_ids" />
|
||||
<value value="160920" />
|
||||
</identifier>
|
||||
<name>
|
||||
<family value="Gered Trystan King" />
|
||||
</name>
|
||||
</Practitioner>
|
||||
</contained>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="6" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="10063.4" />
|
||||
</coding>
|
||||
<text value="Distribute Y/N?" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<valueString value="yes" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="N" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="7" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="14001.5" />
|
||||
</coding>
|
||||
<text value="Medical Records Report" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<valueString value="Medical Records Report" />
|
||||
</Observation>
|
||||
</contained>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="8" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="10060.6" />
|
||||
</coding>
|
||||
<text value="Report Type" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<valueString value="Unscheduled Discharge Summary" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="N" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<contained>
|
||||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<id value="9" />
|
||||
<meta>
|
||||
<lastUpdated value="2014-09-26T11:55:33.000-04:00" />
|
||||
<profile value="http://fhir.uhn.ca/Profile/observation" />
|
||||
</meta>
|
||||
<extension url="http://fhir.uhn.ca/Profile/observation#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.6" />
|
||||
<code value="10064.7" />
|
||||
</coding>
|
||||
<text value="Review/Query?" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<valueString value="no" />
|
||||
<interpretation>
|
||||
<coding>
|
||||
<system value="urn:uhn:qcpr:interpretation_codes" />
|
||||
<code value="N" />
|
||||
</coding>
|
||||
</interpretation>
|
||||
</Observation>
|
||||
</contained>
|
||||
<extension url="http://fhir.uhn.ca/Profile/diagnosticreport#source_system_status">
|
||||
|
||||
<valueString value="F" />
|
||||
</extension>
|
||||
<identifier>
|
||||
<system value="urn:uhn:qcpr:order_ids" />
|
||||
<value value="GI93#discharge_5677961273802d07ad7d079141525bba" />
|
||||
</identifier>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="urn:oid:1.3.6.1.4.1.12201.102.5" />
|
||||
<code value="5053" />
|
||||
</coding>
|
||||
<text value="Unscheduled Discharge Summary" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/5556918" />
|
||||
</subject>
|
||||
<context>
|
||||
<reference value="Encounter/5885735" />
|
||||
</context>
|
||||
<effectiveDateTime value="2014-09-26T11:55:00-04:00" />
|
||||
<issued value="2014-09-26T11:55:33.000-04:00" />
|
||||
<result>
|
||||
<reference value="#1" />
|
||||
</result>
|
||||
<result>
|
||||
<reference value="#2" />
|
||||
</result>
|
||||
<result>
|
||||
<reference value="#4" />
|
||||
</result>
|
||||
<result>
|
||||
<reference value="#6" />
|
||||
</result>
|
||||
<result>
|
||||
<reference value="#7" />
|
||||
</result>
|
||||
<result>
|
||||
<reference value="#8" />
|
||||
</result>
|
||||
<result>
|
||||
<reference value="#9" />
|
||||
</result>
|
||||
</DiagnosticReport>
|
||||
</resource>
|
||||
</entry>
|
||||
</Bundle>
|
Binary file not shown.
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"resourceType": "Consent",
|
||||
"id": "consent-example-basic",
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n <p>\n\tAuthorize Normal access for Treatment\n\t</p><p>\n Patient "P. van de Heuvel" wishes to have all of the PHI collected at the Good Health Psychiatric Hospital \n available for normal treatment use.\n </p>\n </div>"
|
||||
},
|
||||
"status": "active",
|
||||
"patient": {
|
||||
"reference": "Patient/f001",
|
||||
"display": "P. van de Heuvel"
|
||||
},
|
||||
"period": {
|
||||
"start": "1964-01-01",
|
||||
"end": "2016-01-01"
|
||||
},
|
||||
"dateTime": "2016-05-11",
|
||||
"organization": [
|
||||
{
|
||||
"reference": "Organization/Infoway",
|
||||
"display": "Canada Infoway"
|
||||
}
|
||||
],
|
||||
"sourceAttachment": {
|
||||
"title": "The terms of the consent in lawyer speak."
|
||||
},
|
||||
"identifier": [
|
||||
{
|
||||
"use": "usual",
|
||||
"type": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://hl7.org/fhir/v2/0203",
|
||||
"code": "MR"
|
||||
}
|
||||
]
|
||||
},
|
||||
"system": "urn:oid:1.2.36.146.595.217.0.1",
|
||||
"value": "12345",
|
||||
"period": {
|
||||
"start": "2001-05-06"
|
||||
},
|
||||
"assigner": {
|
||||
"display": "Acme Healthcare"
|
||||
}
|
||||
}
|
||||
],
|
||||
"extension":[
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/StructureDefinition/PruebaExtension",
|
||||
"valueString" : "123456789"
|
||||
}
|
||||
],
|
||||
"policyRule": "http://goodhealth.org/consent/policy/opt-in"
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
{
|
||||
"resourceType":"Patient",
|
||||
"text":{
|
||||
"status":"generated",
|
||||
"div":"<div>\n <table>\n <tbody>\n <tr>\n <td>Name</td>\n <td>Peter James <b>Chalmers</b> (\"Jim\")</td>\n </tr>\n <tr>\n <td>Address</td>\n <td>534 Erewhon, Pleasantville, Vic, 3999</td>\n </tr>\n <tr>\n <td>Contacts</td>\n <td>Home: unknown. Work: (03) 5555 6473</td>\n </tr>\n <tr>\n <td>Id</td>\n <td>MRN: 12345 (Acme Healthcare)</td>\n </tr>\n </tbody>\n </table>\n </div>"
|
||||
},
|
||||
"extension":[
|
||||
{
|
||||
"url":"urn:patientext:att",
|
||||
"valueAttachment":{
|
||||
"contentType":"aaaa",
|
||||
"data":"AAAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url":"urn:patientext:moreext",
|
||||
"extension":[
|
||||
{
|
||||
"url":"urn:patientext:moreext:1",
|
||||
"valueString":"str1"
|
||||
},
|
||||
{
|
||||
"url":"urn:patientext:moreext:2",
|
||||
"valueString":"str2"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"modifierExtension":[
|
||||
{
|
||||
"url":"urn:modext",
|
||||
"valueDate":"2011-01-02"
|
||||
}
|
||||
],
|
||||
"identifier":[
|
||||
{
|
||||
"use":"usual",
|
||||
"system":"urn:oid:1.2.36.146.595.217.0.1",
|
||||
"value":"12345",
|
||||
"period":{
|
||||
"start":"2001-05-06"
|
||||
},
|
||||
"assigner":{
|
||||
"display":"Acme Healthcare"
|
||||
}
|
||||
}
|
||||
],
|
||||
"active":true,
|
||||
"name":[
|
||||
{
|
||||
"use":"official",
|
||||
"family":[
|
||||
"Chalmers"
|
||||
],
|
||||
"given":[
|
||||
"Peter",
|
||||
"James"
|
||||
]
|
||||
},
|
||||
{
|
||||
"use":"usual",
|
||||
"given":[
|
||||
"Jim"
|
||||
]
|
||||
}
|
||||
],
|
||||
"telecom":[
|
||||
{
|
||||
"use":"home"
|
||||
},
|
||||
{
|
||||
"system":"phone",
|
||||
"value":"(03) 5555 6473",
|
||||
"use":"work"
|
||||
}
|
||||
],
|
||||
"gender":"male",
|
||||
"birthDate":"1974-12-25",
|
||||
"deceasedBoolean":false,
|
||||
"address":[
|
||||
{
|
||||
"use":"home",
|
||||
"line":[
|
||||
"534 Erewhon St"
|
||||
],
|
||||
"city":"PleasantVille",
|
||||
"state":"Vic",
|
||||
"postalCode":"3999"
|
||||
},
|
||||
{
|
||||
"use":"old",
|
||||
"line":[
|
||||
"SecondAddress"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contact":[
|
||||
{
|
||||
"relationship":[
|
||||
{
|
||||
"coding":[
|
||||
{
|
||||
"system":"http://hl7.org/fhir/patient-contact-relationship",
|
||||
"code":"partner"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name":{
|
||||
"family":[
|
||||
"du",
|
||||
"Marché"
|
||||
],
|
||||
"_family":[
|
||||
{
|
||||
"extension":[
|
||||
{
|
||||
"url":"http://hl7.org/fhir/Profile/iso-21090#qualifier",
|
||||
"valueCode":"VV"
|
||||
}
|
||||
]
|
||||
},
|
||||
null
|
||||
],
|
||||
"given":[
|
||||
"Bénédicte"
|
||||
]
|
||||
},
|
||||
"telecom":[
|
||||
{
|
||||
"system":"phone",
|
||||
"value":"+33 (237) 998327"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"managingOrganization":{
|
||||
"reference":"Organization/1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<Patient xmlns="http://hl7.org/fhir">
|
||||
<text>
|
||||
<status value="generated"/>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>Peter James <b>Chalmers</b> ("Jim")</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Address</td>
|
||||
<td>534 Erewhon, Pleasantville, Vic, 3999</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Contacts</td>
|
||||
<td>Home: unknown. Work: (03) 5555 6473</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Id</td>
|
||||
<td>MRN: 12345 (Acme Healthcare)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</text>
|
||||
|
||||
<extension url="urn:patientext:att">
|
||||
<valueAttachment>
|
||||
<contentType value="aaaa"/>
|
||||
<data value="AAAA"/>
|
||||
</valueAttachment>
|
||||
</extension>
|
||||
|
||||
<extension url="urn:patientext:moreext">
|
||||
<extension url="urn:patientext:moreext:1">
|
||||
<valueString value="str1"/>
|
||||
</extension>
|
||||
<extension url="urn:patientext:moreext:2">
|
||||
<valueString value="str2"/>
|
||||
</extension>
|
||||
</extension>
|
||||
|
||||
<modifierExtension url="urn:modext">
|
||||
<valueDate value="2011-01-02"/>
|
||||
</modifierExtension>
|
||||
|
||||
<identifier>
|
||||
<use value="usual"/>
|
||||
<system value="urn:oid:1.2.36.146.595.217.0.1"/>
|
||||
<value value="12345"/>
|
||||
<period>
|
||||
<start value="2001-05-06"/>
|
||||
</period>
|
||||
<assigner>
|
||||
<display value="Acme Healthcare"/>
|
||||
</assigner>
|
||||
</identifier>
|
||||
|
||||
<active value="true"/>
|
||||
|
||||
<name>
|
||||
<use value="official"/>
|
||||
<family value="Chalmers"/>
|
||||
<given value="Peter"/>
|
||||
<given value="James"/>
|
||||
</name>
|
||||
<name>
|
||||
<use value="usual"/>
|
||||
<given value="Jim"/>
|
||||
</name>
|
||||
|
||||
<telecom>
|
||||
<use value="home"/>
|
||||
</telecom>
|
||||
<telecom>
|
||||
<system value="phone"/>
|
||||
<value value="(03) 5555 6473"/>
|
||||
<use value="work"/>
|
||||
</telecom>
|
||||
|
||||
<gender value="male"/>
|
||||
<birthDate value="1974-12-25"/>
|
||||
<deceasedBoolean value="false"/>
|
||||
|
||||
<address>
|
||||
<use value="home"/>
|
||||
<line value="534 Erewhon St"/>
|
||||
<city value="PleasantVille"/>
|
||||
<state value="Vic"/>
|
||||
<postalCode value="3999"/>
|
||||
</address>
|
||||
|
||||
<address>
|
||||
<use value="old"/>
|
||||
<line value="SecondAddress"/>
|
||||
</address>
|
||||
|
||||
<contact>
|
||||
<relationship>
|
||||
<coding>
|
||||
<system value="http://hl7.org/fhir/patient-contact-relationship"/>
|
||||
<code value="partner"/>
|
||||
</coding>
|
||||
</relationship>
|
||||
|
||||
<name>
|
||||
<family value="du">
|
||||
<extension url="http://hl7.org/fhir/Profile/iso-21090#qualifier">
|
||||
<valueCode value="VV"/>
|
||||
</extension>
|
||||
</family>
|
||||
<family value="Marché"/>
|
||||
<given value="Bénédicte"/>
|
||||
</name>
|
||||
|
||||
<telecom>
|
||||
<system value="phone"/>
|
||||
<value value="+33 (237) 998327"/>
|
||||
</telecom>
|
||||
</contact>
|
||||
|
||||
<managingOrganization>
|
||||
<reference value="Organization/1"/>
|
||||
</managingOrganization>
|
||||
|
||||
|
||||
</Patient>
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"resourceType": "Patient",
|
||||
"name": [
|
||||
{
|
||||
"family": "Doe",
|
||||
"given": [
|
||||
"John",
|
||||
"W."
|
||||
]
|
||||
}
|
||||
],
|
||||
"gender": "male",
|
||||
"birthDate": "2012-02-14",
|
||||
"address": [
|
||||
{
|
||||
"use": "home",
|
||||
"line": [
|
||||
"535 Sheppard Avenue West, Unit 1907",
|
||||
"RR 66, Station A, RPO 123"
|
||||
],
|
||||
"_line": [
|
||||
{
|
||||
"extension": [
|
||||
{
|
||||
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber",
|
||||
"valueString": "535"
|
||||
},
|
||||
{
|
||||
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-streetName",
|
||||
"valueString": "Sheppard"
|
||||
},
|
||||
{
|
||||
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-streetNameType",
|
||||
"valueString": "Avenue"
|
||||
},
|
||||
{
|
||||
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-direction",
|
||||
"valueString": "West"
|
||||
},
|
||||
{
|
||||
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-unitID",
|
||||
"valueString": "1907"
|
||||
},
|
||||
{
|
||||
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-postBox",
|
||||
"valueString": "1234"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"city": "Toronto",
|
||||
"state": "ON",
|
||||
"postalCode": "M3H4X8"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"resourceType": "Patient",
|
||||
"id": "dicom",
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div> Patient MINT_TEST, ID = MINT1234. Age = 56y, Size =\n 1.83m, Weight = 72.58kg </div>"
|
||||
},
|
||||
"http://nema.org/fhir/extensions#0010:1010": [
|
||||
{
|
||||
"valueQuantity": {
|
||||
"value": 56,
|
||||
"units": "Y"
|
||||
}
|
||||
}
|
||||
],
|
||||
"http://nema.org/fhir/extensions#0010:1020": [
|
||||
{
|
||||
"valueQuantity": {
|
||||
"value": 1.83,
|
||||
"units": "m"
|
||||
}
|
||||
}
|
||||
],
|
||||
"http://nema.org/fhir/extensions#0010:1030": [
|
||||
{
|
||||
"valueQuantity": {
|
||||
"value": 72.58,
|
||||
"units": "kg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"identifier": [
|
||||
{
|
||||
"system": "http://nema.org/examples/patients",
|
||||
"value": "MINT1234"
|
||||
}
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"family": [
|
||||
"MINT_TEST"
|
||||
]
|
||||
}
|
||||
],
|
||||
"gender": "male",
|
||||
"_gender": {
|
||||
"http://nema.org/examples/extensions#gender": [
|
||||
{
|
||||
"valueCoding": {
|
||||
"system": "http://nema.org/examples/gender",
|
||||
"code": "M"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"managingOrganization": {
|
||||
"reference": "Organization/1"
|
||||
},
|
||||
"active": true
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,455 @@
|
|||
<QuestionnaireResponse xmlns="http://hl7.org/fhir">
|
||||
<identifier>
|
||||
<value value="1234567890"/>
|
||||
</identifier>
|
||||
<questionnaire>
|
||||
<reference value="Questionnaire/q_jon"/>
|
||||
</questionnaire>
|
||||
<status value="completed"/>
|
||||
<subject>
|
||||
<reference value="http://fhirtest.uhn.ca/baseDstu3/Patient/proband"/>
|
||||
</subject>
|
||||
<author>
|
||||
<reference value="http://fhirtest.uhn.ca/baseDstu3/Practitioner/f007"/>
|
||||
</author>
|
||||
<authored value="2016-01-08"/>
|
||||
<item>
|
||||
<linkId value="root"/>
|
||||
<item>
|
||||
<linkId value="g1"/>
|
||||
<text value="CLINICAL INFORMATION"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="1.1"/>
|
||||
</extension>
|
||||
<linkId value="1.1"/>
|
||||
<text value="Patient Clinical Information"/>
|
||||
<answer>
|
||||
<valueString value="Previous chest X-RAY was suspicious. Heavy smoker, 15 pack years."/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="1.2"/>
|
||||
</extension>
|
||||
<linkId value="1.2"/>
|
||||
<text value="Previous Examination (Date and Modality)"/>
|
||||
<answer>
|
||||
<valueString value="Chest XR - September 23, 2015"/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<linkId value="g2"/>
|
||||
<text value="IMAGING PROCEDURE DESCRIPTION"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="2.1"/>
|
||||
</extension>
|
||||
<linkId value="2.1"/>
|
||||
<text value="Overall Image Quality:"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="2.1a"/>
|
||||
<display value="Adequate"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="2.2"/>
|
||||
</extension>
|
||||
<linkId value="2.2"/>
|
||||
<text value="Intravenous Contrast Used?"/>
|
||||
<answer>
|
||||
<valueBoolean value="false"/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="2.3"/>
|
||||
</extension>
|
||||
<linkId value="2.3"/>
|
||||
<text value="Additional Comments"/>
|
||||
<answer>
|
||||
<valueString value="n/a."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<linkId value="g3"/>
|
||||
<text value="FINDINGS"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3"/>
|
||||
</extension>
|
||||
<linkId value="g3.0"/>
|
||||
<text value="T Category"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.1"/>
|
||||
</extension>
|
||||
<linkId value="g3.1"/>
|
||||
<text value="Location of Main Nodule/Mass (Primary tumor, or Reference tumor)"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.1.1"/>
|
||||
</extension>
|
||||
<linkId value="q3.1.1"/>
|
||||
<text value="Location of main nodule/mass:"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="3.1.1a"/>
|
||||
<display value="Peripheral"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.1.2"/>
|
||||
</extension>
|
||||
<linkId value="3.1.2"/>
|
||||
<answer>
|
||||
<valueString value="Right Upper Lung, Posterior segment."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.2"/>
|
||||
</extension>
|
||||
<linkId value="g3.2"/>
|
||||
<text value="Size and characteristics of main nodule/mass"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.2.1"/>
|
||||
</extension>
|
||||
<linkId value="3.2.1"/>
|
||||
<text value="Size of the nodule/mass:"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="3.2.1a"/>
|
||||
<display value="Solid nodule/mass"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
<item><!-- Measurement, image, series, etc for all 3 answer choices goes here. Conditonal. -->
|
||||
<linkId value="g3.2.1"/>
|
||||
<item><!-- Group for answer choice a -->
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen"><!-- Note that this extension is at the group level. -->
|
||||
<extension url="#question">
|
||||
<valueString value="3.2.1"/>
|
||||
</extension>
|
||||
<extension url="#answer">
|
||||
<valueCoding>
|
||||
<code value="3.2.1a"/>
|
||||
</valueCoding>
|
||||
</extension>
|
||||
</extension>
|
||||
<linkId value="g3.2.1a"/>
|
||||
<item>
|
||||
<linkId value="3.2.1a"/>
|
||||
<text value="largest dimension:"/>
|
||||
<answer>
|
||||
<valueInteger value="20"/>
|
||||
</answer>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl">
|
||||
<valueCodeableConcept>
|
||||
<coding>
|
||||
<system value="http://hl7.org/fhir/ValueSet/questionnaire-item-control"/>
|
||||
<code value="unit"/>
|
||||
</coding>
|
||||
</valueCodeableConcept>
|
||||
</extension>
|
||||
<text value="mm"/>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<linkId value="3.2.1a.image"/>
|
||||
<text value="image"/>
|
||||
<answer>
|
||||
<valueString value="32"/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<linkId value="3.2.1a.series"/>
|
||||
<text value="series"/>
|
||||
<answer>
|
||||
<valueString value="3"/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.2.2"/>
|
||||
</extension>
|
||||
<linkId value="3.2.2"/>
|
||||
<text value="Plane in which the mass was measured:"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="3.2.2a"/>
|
||||
<display value="Axial"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.2.3"/>
|
||||
</extension>
|
||||
<linkId value="3.2.3"/>
|
||||
<answer>
|
||||
<valueString value="Solid attenuation of mass, margins spiculated."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.3"/>
|
||||
</extension>
|
||||
<linkId value="g3.3"/>
|
||||
<text value="Structures directly involved"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.3.1"/>
|
||||
</extension>
|
||||
<linkId value="3.3.1"/>
|
||||
<text value="State if there is bronchial involvement:"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="3.3.1b"/>
|
||||
<display value="No"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.3.2"/>
|
||||
</extension>
|
||||
<linkId value="3.3.2"/>
|
||||
<text value="Is there direct involvement of any other anatomical structures?"/>
|
||||
<answer>
|
||||
<valueBoolean value="false"/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.3.3"/>
|
||||
</extension>
|
||||
<linkId value="3.3.3"/>
|
||||
<text value="Are there additional suspicious pulmonary nodules?"/>
|
||||
<answer>
|
||||
<valueBoolean value="false"/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="3.3.4"/>
|
||||
</extension>
|
||||
<linkId value="3.3.4"/>
|
||||
<text value="Other notable intrathoracic findings (eg lymphangitis carcinomatosis):"/>
|
||||
<answer>
|
||||
<valueString value="n/a"/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="4"/>
|
||||
</extension>
|
||||
<linkId value="4.0"/>
|
||||
<text value="N Category"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="4.1"/>
|
||||
</extension>
|
||||
<linkId value="4.1"/>
|
||||
<text value="Are there enlarged lymph nodes?"/>
|
||||
<answer>
|
||||
<valueBoolean value="false"/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="4.2"/>
|
||||
</extension>
|
||||
<linkId value="4.2"/>
|
||||
<text value="Other notable findings:"/>
|
||||
<answer>
|
||||
<valueString value="Liner / scar atelectasis lingua, anterior segment of right upper lobe and bilateral lower lobes."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="5"/>
|
||||
</extension>
|
||||
<linkId value="5.0"/>
|
||||
<text value="M Category (Suspicious Extrathoracic Findings (M1b))"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="5.1"/>
|
||||
</extension>
|
||||
<linkId value="5.1"/>
|
||||
<text value="Are there suspicious extrathoracic findings?"/>
|
||||
<answer>
|
||||
<valueBoolean value="true"/>
|
||||
</answer>
|
||||
<item>
|
||||
<linkId value="g5.1.yes"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen">
|
||||
<extension url="#question">
|
||||
<valueString value="5.1"/>
|
||||
</extension>
|
||||
<extension url="#answer">
|
||||
<valueBoolean value="true"/>
|
||||
</extension>
|
||||
</extension>
|
||||
<linkId value="5.1.yes"/>
|
||||
<text value="Applicable Structures and Descriptions:"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="5.1.yes.d"/>
|
||||
<display value="Other"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen">
|
||||
<extension url="#question">
|
||||
<valueString value="5.1.yes"/>
|
||||
</extension>
|
||||
<extension url="#answer">
|
||||
<valueCoding>
|
||||
<code value="5.1.yes.d"/>
|
||||
</valueCoding>
|
||||
</extension>
|
||||
</extension>
|
||||
<linkId value="5.1.yes.d.description"/>
|
||||
<text value="Description of structures:"/>
|
||||
<answer>
|
||||
<valueString value="3 cm calcified thyroid nodule on TUL left."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="6"/>
|
||||
</extension>
|
||||
<linkId value="6.0"/>
|
||||
<text value="Additional Findings"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="6.1"/>
|
||||
</extension>
|
||||
<linkId value="6.1"/>
|
||||
<text value="Are there additional findings?"/>
|
||||
<answer>
|
||||
<valueBoolean value="true"/>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="6.2"/>
|
||||
</extension>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen">
|
||||
<extension url="#question">
|
||||
<valueString value="6.1"/>
|
||||
</extension>
|
||||
<extension url="#answer">
|
||||
<valueBoolean value="true"/>
|
||||
</extension>
|
||||
</extension>
|
||||
<linkId value="6.2"/>
|
||||
<text value="Findings and Descriptions:"/>
|
||||
<answer>
|
||||
<valueString value="Oligemic changes in right upper lobe from possible old pulmonary embolus."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<linkId value="g7"/>
|
||||
<text value="IMPRESSIONS"/>
|
||||
<item>
|
||||
<linkId value="g7.1"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="7.1"/>
|
||||
</extension>
|
||||
<linkId value="7.1"/>
|
||||
<text value="Impression/Summary:"/>
|
||||
<answer>
|
||||
<valueString value="Spiculated mass in posterior segment of right upper lobe that has increasing size from 16 to 20 mm."/>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="7.2"/>
|
||||
</extension>
|
||||
<linkId value="g7.2"/>
|
||||
<text value="Radiologic Staging (TNM Version – 7th edition)"/>
|
||||
<item>
|
||||
<linkId value="g7.20"/>
|
||||
<text value="If this is a biopsy proven carcinoma, the preliminary radiologic stage is:"/>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="i)"/>
|
||||
</extension>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-questionControl" >
|
||||
<valueCodeableConcept>
|
||||
<coding>
|
||||
<code value="radio-button"/>
|
||||
<display value="Radio Button"/>
|
||||
</coding>
|
||||
</valueCodeableConcept>
|
||||
</extension>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-choiceOrientation" >
|
||||
<valueCode value="horizontal"/>
|
||||
</extension>
|
||||
<linkId value="7.2i"/>
|
||||
<text value="Primary Tumour (T):"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="T1a"/>
|
||||
<display value="T1a"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="ii)"/>
|
||||
</extension>
|
||||
<linkId value="7.2ii"/>
|
||||
<text value="Regional Lymph Nodes (N):"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="N0"/>
|
||||
<display value="N0"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
<item>
|
||||
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
|
||||
<valueString value="iii)"/>
|
||||
</extension>
|
||||
<linkId value="7.2iii"/>
|
||||
<text value="Distant Metastasis (M):"/>
|
||||
<answer>
|
||||
<valueCoding>
|
||||
<code value="M0"/>
|
||||
<display value="M0"/>
|
||||
</valueCoding>
|
||||
</answer>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
</item>
|
||||
</QuestionnaireResponse>
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"resourceType": "Bundle",
|
||||
"entry": [
|
||||
{
|
||||
"fullUrl": "http://localhost:5555/phr/baseDstu3/Person/PERSON1",
|
||||
"resource": {
|
||||
"resourceType": "Person",
|
||||
"id": "PERSON1",
|
||||
"meta": {
|
||||
"versionId": "1",
|
||||
"lastUpdated": "2017-08-17T16:19:40.109+03:00"
|
||||
},
|
||||
"identifier": [
|
||||
{
|
||||
"value": "081181-9984"
|
||||
}
|
||||
],
|
||||
"name": [
|
||||
{
|
||||
"text": "Anna Testi",
|
||||
"family": "Testi",
|
||||
"given": [
|
||||
"Anna"
|
||||
]
|
||||
},
|
||||
{
|
||||
"family": "asdfas"
|
||||
}
|
||||
],
|
||||
"telecom": [
|
||||
{
|
||||
"use": "home"
|
||||
},
|
||||
{
|
||||
"system": "phone",
|
||||
"value": "(044) 1234567",
|
||||
"use": "work"
|
||||
}
|
||||
],
|
||||
"gender": "female",
|
||||
"birthDate": "1981-11-08",
|
||||
"address": [
|
||||
{
|
||||
"line": [
|
||||
"Osuuspankkitie 2"
|
||||
],
|
||||
"city": "Helsinki",
|
||||
"postalCode": "00120",
|
||||
"country": "Suomi"
|
||||
},
|
||||
{
|
||||
"city": "Blo-49847020"
|
||||
}
|
||||
],
|
||||
"active": true,
|
||||
"link": [
|
||||
{
|
||||
"target": {
|
||||
"reference": "Patient/PATIENT1",
|
||||
"display": "Anna Testi"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"request": {
|
||||
"method": "PUT",
|
||||
"url": "Person/PERSON1",
|
||||
"ifMatch": "1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,298 @@
|
|||
{
|
||||
"resourceType": "TestScript",
|
||||
"id": "search",
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div><p><b>Generated Narrative with Details</b></p><p><b>id</b>: search</p><p><b>name</b>: Read, Search and Conditional Create and Delete</p><p><b>description</b>: Test Script for testing search, read, and conditional create and delete</p><h3>Fixtures</h3><table><tr><td>-</td><td><b>Resource</b></td></tr><tr><td>*</td><td><a>Patient/patient-example.xml</a></td></tr></table><blockquote><p><b>variable</b></p><p><b>name</b>: V1</p><p><b>sourceId</b>: R1</p><p><b>headerField</b>: Location</p></blockquote><blockquote><p><b>variable</b></p><p><b>name</b>: V2</p><p><b>sourceId</b>: R3</p><p><b>path</b>: fhir:Patient/fhir:name/fhir:given/@value</p></blockquote><blockquote><p><b>setup</b></p><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td><td><b>Type</b></td><td><b>Resource</b></td><td><b>Params</b></td></tr><tr><td>*</td><td>delete</td><td>Patient</td><td>given=John&family=Doe</td></tr></table></blockquote></blockquote><blockquote><p><b>test</b></p><p><b>name</b>: Create</p><p><b>description</b>: Create, read, search, conditional create, conditional delete.</p><blockquote><p><b>metadata</b></p><h3>Links</h3><table><tr><td>-</td><td><b>Url</b></td><td><b>Description</b></td></tr><tr><td>*</td><td><a>http://hl7.org/implement/standards/FHIR-Develop/patient.html</a></td><td>FHIR Patient</td></tr></table><blockquote><p><b>operation</b></p><p><b>type</b>: create</p><p><b>resource</b>: Patient</p><p><b>description</b>: Conditional Create Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.13.1</a></p><p><b>required</b>: true</p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: delete</p><p><b>resource</b>: Patient</p><p><b>description</b>: Conditional Delete Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.12.1</a></p><p><b>required</b>: true</p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: read</p><p><b>resource</b>: Patient</p><p><b>description</b>: Patient Read Operation</p><p><b>link</b>: <a>http://hl7.org/implement/standards/FHIR-Develop/http.html#read</a></p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: search</p><p><b>resource</b>: Patient</p><p><b>description</b>: Patient Search Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.14</a></p><p><b>validated</b>: true</p></blockquote></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote></blockquote></div>"
|
||||
},
|
||||
"url": "http://hl7.org/fhir/TestScript/search",
|
||||
"name": "Read, Search and Conditional Create and Delete",
|
||||
"status": "draft",
|
||||
"description": "Test Script for testing search, read, and conditional create and delete",
|
||||
"metadata": {
|
||||
"capability": [
|
||||
{
|
||||
"required": true,
|
||||
"description": "Patient Create and Read Operations",
|
||||
"link": [
|
||||
"http://hl7.org/implement/standards/FHIR-Develop/http.html#create",
|
||||
"http://hl7.org/implement/standards/FHIR-Develop/http.html#read"
|
||||
],
|
||||
"conformance": {
|
||||
"reference": "Conformance/example"
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"description": "Patient Conditional Delete Operation",
|
||||
"link": [
|
||||
"http://hl7-fhir.github.io/http.html#2.1.0.12.1"
|
||||
],
|
||||
"conformance": {
|
||||
"reference": "Conformance/example"
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"description": "Patient Conditional Create Operation",
|
||||
"link": [
|
||||
"http://hl7-fhir.github.io/http.html#2.1.0.13.1"
|
||||
],
|
||||
"conformance": {
|
||||
"reference": "Conformance/example"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"fixture": [
|
||||
{
|
||||
"id": "example-patient",
|
||||
"resource": {
|
||||
"reference": "Patient/example"
|
||||
}
|
||||
}
|
||||
],
|
||||
"variable": [
|
||||
{
|
||||
"name": "V1",
|
||||
"headerField": "Location",
|
||||
"sourceId": "R1"
|
||||
},
|
||||
{
|
||||
"name": "V2",
|
||||
"path": "fhir:Patient/fhir:name/fhir:given/@value",
|
||||
"sourceId": "R3"
|
||||
},
|
||||
{
|
||||
"name": "DefaultValue",
|
||||
"defaultValue": "Replace at Runtime"
|
||||
}
|
||||
],
|
||||
"setup": {
|
||||
"action": [
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Conditional Delete "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "delete"
|
||||
},
|
||||
"resource": "Patient",
|
||||
"params": "given=John&family=Doe"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"test": [
|
||||
{
|
||||
"id": "Test1",
|
||||
"name": "Create",
|
||||
"description": "Create, read, search, conditional create, conditional delete.",
|
||||
"metadata": {
|
||||
"link": [
|
||||
{
|
||||
"url": "http://hl7.org/implement/standards/FHIR-Develop/patient.html",
|
||||
"description": "FHIR Patient"
|
||||
}
|
||||
],
|
||||
"capability": [
|
||||
{
|
||||
"validated": true,
|
||||
"description": "Patient Search Operation",
|
||||
"link": [
|
||||
"http://hl7.org/implement/standards/FHIR-Develop/http.html#search"
|
||||
],
|
||||
"conformance": {
|
||||
"reference": "Conformance/example"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"action": [
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Create the patient using fixture "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "create"
|
||||
},
|
||||
"sourceId": "example-patient"
|
||||
}
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"responseCode": "201"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Patient search by name. Save the responseBody in 'F1' fixture.\n\t\t\t\tSave the responseHeader in H1 "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "search"
|
||||
},
|
||||
"resource": "Patient",
|
||||
"contentType": "json",
|
||||
"params": "?given=John&family=Doe",
|
||||
"responseId": "R1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Verify that the Location in response-header is valid "
|
||||
],
|
||||
"assert": {
|
||||
"headerField": "Location",
|
||||
"operator": "notEmpty",
|
||||
"warningOnly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Verify that the birthdate got persisted and is being returned properly "
|
||||
],
|
||||
"assert": {
|
||||
"operator": "equals",
|
||||
"path": "fhir:Patient/fhir:birthDate/@value",
|
||||
"sourceId": "R1",
|
||||
"value": "1974-12-31"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Verify that the navigation links are valid "
|
||||
],
|
||||
"assert": {
|
||||
"navigationLinks": true,
|
||||
"warningOnly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Use the Location returned earlier to grab the resource\n\t\t \t\tto verify that Location was pointing to correct resource. "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "search"
|
||||
},
|
||||
"accept": "json",
|
||||
"responseId": "R2",
|
||||
"url": "${V1}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"contentType": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"response": "okay"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Search for the resource but this time using the birthdate\n\t\t\t\tas a search parameter to make sure search by birthDate works "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "search"
|
||||
},
|
||||
"resource": "Patient",
|
||||
"accept": "json",
|
||||
"params": "?given=John&family=Doe&birthdate=1974-12-31",
|
||||
"responseId": "R3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"contentType": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"response": "okay"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Verify that the birthDate matches expectations "
|
||||
],
|
||||
"assert": {
|
||||
"compareToSourceId": "R2",
|
||||
"compareToSourcePath": "fhir:Patient/fhir:birthDate/@value",
|
||||
"path": "fhir:Patient/fhir:birthDate/@value",
|
||||
"sourceId": "R3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Verify that the name matches expectations "
|
||||
],
|
||||
"assert": {
|
||||
"path": "fhir:Patient/fhir:name/fhir:given/@value",
|
||||
"sourceId": "R3",
|
||||
"value": "John"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Conditional Create "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "create"
|
||||
},
|
||||
"requestHeader": [
|
||||
{
|
||||
"field": "If-None-Exist",
|
||||
"value": "Patient?given=John&Doe&birthdate=1974-12-31"
|
||||
}
|
||||
],
|
||||
"sourceId": "F1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" The response code of 200 verifies that the resource\n\t\t\t\talready exists and did not get created "
|
||||
],
|
||||
"assert": {
|
||||
"responseCode": "200"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Conditional Delete "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "delete"
|
||||
},
|
||||
"resource": "Patient",
|
||||
"params": "?given=John&family=Doe&birthdate=1974-12-31"
|
||||
}
|
||||
},
|
||||
{
|
||||
"fhir_comments": [
|
||||
" Search again and make sure the patient has been deleted.\n\t\t \t\t This time perform read by id using variable "
|
||||
],
|
||||
"operation": {
|
||||
"type": {
|
||||
"code": "read"
|
||||
},
|
||||
"resource": "Patient",
|
||||
"params": "/${V2}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"assert": {
|
||||
"responseCode": "410"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
130
pom.xml
130
pom.xml
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.sonatype.oss</groupId>
|
||||
|
@ -411,6 +412,11 @@
|
|||
<id>anthonys123</id>
|
||||
<name>Anthony Sute</name>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>johnpoth</id>
|
||||
<name>John Poth</name>
|
||||
<organization>Red Hat</organization>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
|
@ -431,24 +437,38 @@
|
|||
<scmPubCheckoutDirectory>${user.home}/sites/scm/hapi-fhir</scmPubCheckoutDirectory>
|
||||
|
||||
<!-- Dependency Versions -->
|
||||
<apache_karaf_version>4.1.4</apache_karaf_version>
|
||||
<commons_codec_version>1.10</commons_codec_version>
|
||||
<commons_io_version>2.5</commons_io_version>
|
||||
<commons_lang3_version>3.6</commons_lang3_version>
|
||||
<derby_version>10.14.1.0</derby_version>
|
||||
<error_prone_annotations_version>2.0.18</error_prone_annotations_version>
|
||||
<guava_version>23.0</guava_version>
|
||||
<gson_version>2.8.1</gson_version>
|
||||
<jaxb_api_version>2.3.0</jaxb_api_version>
|
||||
<jaxb_core_version>2.3.0</jaxb_core_version>
|
||||
<jersey_version>2.25.1</jersey_version>
|
||||
<jetty_version>9.4.8.v20171121</jetty_version>
|
||||
<jsr305_version>3.0.2</jsr305_version>
|
||||
<!--<hibernate_version>5.2.10.Final</hibernate_version>-->
|
||||
<hibernate_version>5.2.12.Final</hibernate_version>
|
||||
<hibernate_validator_version>5.4.1.Final</hibernate_validator_version>
|
||||
<!-- Update lucene version when you update hibernate-search version -->
|
||||
<hibernate_search_version>5.7.1.Final</hibernate_search_version>
|
||||
<httpcore_version>4.4.6</httpcore_version>
|
||||
<httpclient_version>4.5.3</httpclient_version>
|
||||
<lucene_version>5.5.4</lucene_version>
|
||||
<maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version>
|
||||
<maven_license_plugin_version>1.8</maven_license_plugin_version>
|
||||
<phloc_schematron_version>2.7.1</phloc_schematron_version>
|
||||
<phloc_commons_version>4.4.11</phloc_commons_version>
|
||||
<servicemix_saxon_version>9.5.1-5_1</servicemix_saxon_version>
|
||||
<servicemix_xmlresolver_version>1.2_5</servicemix_xmlresolver_version>
|
||||
<spring_version>5.0.3.RELEASE</spring_version>
|
||||
<spring-boot.version>1.5.6.RELEASE</spring-boot.version>
|
||||
<stax2_api_version>3.1.4</stax2_api_version>
|
||||
<thymeleaf-version>3.0.9.RELEASE</thymeleaf-version>
|
||||
<woodstox_core_asl_version>4.4.1</woodstox_core_asl_version>
|
||||
|
||||
<!-- We are aiming to still work on a very old version of SLF4j even though we depend on the newest, just to be nice to users of the API. This version is tested in the hapi-fhir-cobertura. -->
|
||||
<slf4j_target_version>1.6.0</slf4j_target_version>
|
||||
|
@ -532,7 +552,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>23.0</version>
|
||||
<version>${guava_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
@ -567,12 +587,12 @@
|
|||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.10</version>
|
||||
<version>${commons_codec_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
<version>${commons_io_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>directory-naming</groupId>
|
||||
|
@ -590,7 +610,7 @@
|
|||
<groupId>es.nitaur.markdown</groupId>
|
||||
<artifactId>txtmark</artifactId>
|
||||
<version>0.16</version>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ejb</groupId>
|
||||
<artifactId>ejb-api</artifactId>
|
||||
|
@ -619,7 +639,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.1</version>
|
||||
<version>${gson_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
|
@ -657,9 +677,9 @@
|
|||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>lt.velykis.maven.skins</groupId>
|
||||
|
@ -713,7 +733,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>${commons_lang3_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
|
@ -733,7 +753,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.3</version>
|
||||
<version>${httpclient_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
|
@ -743,7 +763,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.4.6</version>
|
||||
<version>${httpcore_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
|
@ -828,7 +848,7 @@
|
|||
<dependency>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
<version>4.4.1</version>
|
||||
<version>${woodstox_core_asl_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
|
@ -1127,7 +1147,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.5.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -1301,7 +1321,8 @@
|
|||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>
|
||||
jacoco-maven-plugin</artifactId>
|
||||
jacoco-maven-plugin
|
||||
</artifactId>
|
||||
<version>0.7.9</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
@ -1549,7 +1570,9 @@
|
|||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken>http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-responsive.min.css</replacetoken>
|
||||
<replacetoken>
|
||||
http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-responsive.min.css
|
||||
</replacetoken>
|
||||
<replacevalue>./css/bootstrap-responsive.min.css</replacevalue>
|
||||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
|
@ -1559,8 +1582,10 @@
|
|||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken>http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css</replacetoken>
|
||||
<replacevalue>https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css</replacevalue>
|
||||
<replacetoken>http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css
|
||||
</replacetoken>
|
||||
<replacevalue>https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css
|
||||
</replacevalue>
|
||||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
|
@ -1604,28 +1629,35 @@
|
|||
<echo>Adding Fontawesome</echo>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken><![CDATA[<a href="download.html" title="Download">Download</a>]]></replacetoken>
|
||||
<replacevalue><![CDATA[<a href="download.html" title="Download"><i class="fa fa-download"></i> Download</a>]]></replacevalue>
|
||||
<replacetoken>
|
||||
<![CDATA[<a href="download.html" title="Download">Download</a>]]></replacetoken>
|
||||
<replacevalue>
|
||||
<![CDATA[<a href="download.html" title="Download"><i class="fa fa-download"></i> Download</a>]]></replacevalue>
|
||||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken><![CDATA[<a href="https://github.com/jamesagnew/hapi-fhir/" title="GitHub Project" class="externalLink">GitHub Project</a>]]></replacetoken>
|
||||
<replacevalue><![CDATA[<a href="https://github.com/jamesagnew/hapi-fhir/" title="GitHub Project" class="externalLink"><i class="fa fa-github"></i> GitHub Project</a>]]></replacevalue>
|
||||
<replacetoken>
|
||||
<![CDATA[<a href="https://github.com/jamesagnew/hapi-fhir/" title="GitHub Project" class="externalLink">GitHub Project</a>]]></replacetoken>
|
||||
<replacevalue>
|
||||
<![CDATA[<a href="https://github.com/jamesagnew/hapi-fhir/" title="GitHub Project" class="externalLink"><i class="fa fa-github"></i> GitHub Project</a>]]></replacevalue>
|
||||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken><![CDATA[data-toggle="dropdown">Test Servers <]]></replacetoken>
|
||||
<replacevalue><![CDATA[data-toggle="dropdown"><i class="fa fa-fire"></i> Test Servers <]]></replacevalue>
|
||||
<replacevalue>
|
||||
<![CDATA[data-toggle="dropdown"><i class="fa fa-fire"></i> Test Servers <]]></replacevalue>
|
||||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken><![CDATA[data-toggle="dropdown">Documentation <]]></replacetoken>
|
||||
<replacevalue><![CDATA[data-toggle="dropdown"><i class="fa fa-book"></i> Documentation <]]></replacevalue>
|
||||
<replacevalue>
|
||||
<![CDATA[data-toggle="dropdown"><i class="fa fa-book"></i> Documentation <]]></replacevalue>
|
||||
</replace>
|
||||
<replace dir="target/site" summary="true">
|
||||
<include name="*.html"/>
|
||||
<replacetoken><![CDATA[data-toggle="dropdown">Get Help <]]></replacetoken>
|
||||
<replacevalue><![CDATA[data-toggle="dropdown"><i class="fa fa-support"></i> Get Help <]]></replacevalue>
|
||||
<replacevalue>
|
||||
<![CDATA[data-toggle="dropdown"><i class="fa fa-support"></i> Get Help <]]></replacevalue>
|
||||
</replace>
|
||||
<echo>Changing Breadcrumbs</echo>
|
||||
<replace dir="target/site" summary="true">
|
||||
|
@ -1802,21 +1834,6 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<failBuildOnCVSS>8</failBuildOnCVSS>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -1856,9 +1873,12 @@
|
|||
<configuration>
|
||||
<reportsDirectories>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-base/target/surefire-reports/</reportDirectory>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-structures-dstu/target/surefire-reports/</reportDirectory>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-structures-dstu2/target/surefire-reports/</reportDirectory>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-jpaserver-base/target/surefire-reports/</reportDirectory>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-structures-dstu/target/surefire-reports/
|
||||
</reportDirectory>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-structures-dstu2/target/surefire-reports/
|
||||
</reportDirectory>
|
||||
<reportDirectory>${project.basedir}/hapi-fhir-jpaserver-base/target/surefire-reports/
|
||||
</reportDirectory>
|
||||
</reportsDirectories>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -2000,6 +2020,8 @@
|
|||
<module>hapi-fhir-cli</module>
|
||||
<module>hapi-fhir-dist</module>
|
||||
<module>examples</module>
|
||||
<module>osgi/hapi-fhir-karaf-features</module>
|
||||
<module>osgi/hapi-fhir-karaf-integration-tests</module>
|
||||
<module>example-projects/hapi-fhir-base-example-embedded-ws</module>
|
||||
<module>example-projects/hapi-fhir-standalone-overlay-example</module>
|
||||
<module>example-projects/hapi-fhir-jpaserver-cds-example</module>
|
||||
|
@ -2075,6 +2097,28 @@
|
|||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>OWASP</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<failBuildOnCVSS>8</failBuildOnCVSS>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -41,6 +41,28 @@
|
|||
</ul>
|
||||
]]>
|
||||
</action>
|
||||
<action tyoe="add" issue="871">
|
||||
A number of HAPI FHIR modules have been converted so that they now work
|
||||
as OSGi modules. Unlike the previous OSGi module, which was a mega-JAR
|
||||
with all of HAPI FHIR in it, this is simply the appropriate
|
||||
OSGi manifest inside the existing JARs. Thanks to John Poth
|
||||
for the Pull Request!
|
||||
<![CDATA[
|
||||
<br/><br/>
|
||||
Note that this does not cover all modules in the project. Current support includes:
|
||||
<ul>
|
||||
<li>HAPI-FHIR structures DSTU2, HL7ORGDSTU2, DSTU2.1, DSTU3, R4</li>
|
||||
<li>HAPI-FHIR Resource validation DSTU2, HL7ORGDSTU2, DSTU2.1, DSTU3, R4</li>
|
||||
<li>Apache Karaf features for all the above</li>
|
||||
<li> Integration Tests</li>
|
||||
</ul>
|
||||
Remaining work includes:
|
||||
<ul>
|
||||
<li>HAPI-FHIR Server support</li>
|
||||
<li> HAPI-FHIR narrative support. This might be tricky as Thymeleaf doesn't support OSGi.</li>
|
||||
</ul>
|
||||
]]>
|
||||
</action>
|
||||
<action type="fix">
|
||||
Fix a crash in the JSON parser when parsing extensions on repeatable
|
||||
elements (e.g. Patient.address.line) where there is an extension on the
|
||||
|
@ -275,6 +297,13 @@
|
|||
Suport for the :contains string search parameter modifier has been added to
|
||||
the JPA server. Thanks to Anthony Sute for the pull request!
|
||||
</action>
|
||||
<action type="fix">
|
||||
All instances of DefaultProfileValidationSupport (i.e. one for
|
||||
each version of FHIR) have been fixed so that they explicitly
|
||||
close any InputStreams they open in order to read the built-in
|
||||
profile resources. Leaving these open caused resource starvation
|
||||
in some cases under heavy load.
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.2.0" date="2018-01-13">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue