Merge remote-tracking branch 'origin/master' into im_20200728_term_multi_version_support
This commit is contained in:
commit
640ee94c5c
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 2097
|
||||||
|
title: "A crash in the JPA server was fixed when performing a search containined two chained search parameters to
|
||||||
|
date target types."
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 2099
|
||||||
|
title: "When using an NPM package spec in STORE_AND_INSTALL mode, conformance resources will only be stored if they
|
||||||
|
have a status of `active`. This fixes a bug wgere installing the US Core IG caused searches to stop working due to
|
||||||
|
draft Search Parameters."
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 2099
|
||||||
|
title: "Stored SearchParameter resources with a status of DRAFT will no longer override and disable existing built-in
|
||||||
|
search parameters. This is done in order to avoid issues caused by uploading NPM packages such as US Core that
|
||||||
|
contain a large number of draft parameters."
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 2101
|
||||||
|
title: "In some circumstances when using a Plain Server, the generated CapabilityStatement could have duplciate
|
||||||
|
Search Parameter definitions. This has been corrected."
|
|
@ -28,6 +28,7 @@ public class DaoMethodOutcome extends MethodOutcome {
|
||||||
|
|
||||||
private IBasePersistedResource myEntity;
|
private IBasePersistedResource myEntity;
|
||||||
private IBaseResource myPreviousResource;
|
private IBaseResource myPreviousResource;
|
||||||
|
private boolean myNop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -36,6 +37,20 @@ public class DaoMethodOutcome extends MethodOutcome {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was this a NO-OP - Typically because of an update to a resource that already matched the contents provided
|
||||||
|
*/
|
||||||
|
public boolean isNop() {
|
||||||
|
return myNop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was this a NO-OP - Typically because of an update to a resource that already matched the contents provided
|
||||||
|
*/
|
||||||
|
public void setNop(boolean theNop) {
|
||||||
|
myNop = theNop;
|
||||||
|
}
|
||||||
|
|
||||||
public IBasePersistedResource getEntity() {
|
public IBasePersistedResource getEntity() {
|
||||||
return myEntity;
|
return myEntity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||||
|
@ -128,6 +129,12 @@ public abstract class BaseStorageDao {
|
||||||
protected DaoMethodOutcome toMethodOutcome(RequestDetails theRequest, @Nonnull final IBasePersistedResource theEntity, @Nonnull IBaseResource theResource) {
|
protected DaoMethodOutcome toMethodOutcome(RequestDetails theRequest, @Nonnull final IBasePersistedResource theEntity, @Nonnull IBaseResource theResource) {
|
||||||
DaoMethodOutcome outcome = new DaoMethodOutcome();
|
DaoMethodOutcome outcome = new DaoMethodOutcome();
|
||||||
|
|
||||||
|
if (theEntity instanceof ResourceTable) {
|
||||||
|
if (((ResourceTable) theEntity).isUnchangedInCurrentOperation()) {
|
||||||
|
outcome.setNop(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IIdType id = null;
|
IIdType id = null;
|
||||||
if (theResource.getIdElement().getValue() != null) {
|
if (theResource.getIdElement().getValue() != null) {
|
||||||
id = theResource.getIdElement();
|
id = theResource.getIdElement();
|
||||||
|
|
|
@ -49,7 +49,6 @@ import java.util.Map;
|
||||||
public class PredicateBuilderDate extends BasePredicateBuilder implements IPredicateBuilder {
|
public class PredicateBuilderDate extends BasePredicateBuilder implements IPredicateBuilder {
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(PredicateBuilderDate.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(PredicateBuilderDate.class);
|
||||||
|
|
||||||
private Map<String, From<?, ResourceIndexedSearchParamDate>> myJoinMap;
|
|
||||||
|
|
||||||
PredicateBuilderDate(SearchBuilder theSearchBuilder) {
|
PredicateBuilderDate(SearchBuilder theSearchBuilder) {
|
||||||
super(theSearchBuilder);
|
super(theSearchBuilder);
|
||||||
|
@ -64,15 +63,15 @@ public class PredicateBuilderDate extends BasePredicateBuilder implements IPredi
|
||||||
|
|
||||||
String paramName = theSearchParam.getName();
|
String paramName = theSearchParam.getName();
|
||||||
boolean newJoin = false;
|
boolean newJoin = false;
|
||||||
if (myJoinMap == null) {
|
|
||||||
myJoinMap = new HashMap<>();
|
Map<String, From<?, ResourceIndexedSearchParamDate>> joinMap = myQueryStack.getJoinMap();
|
||||||
}
|
|
||||||
String key = theResourceName + " " + paramName;
|
String key = theResourceName + " " + paramName;
|
||||||
|
|
||||||
From<?, ResourceIndexedSearchParamDate> join = myJoinMap.get(key);
|
From<?, ResourceIndexedSearchParamDate> join = joinMap.get(key);
|
||||||
|
|
||||||
if (join == null) {
|
if (join == null) {
|
||||||
join = myQueryStack.createJoin(SearchBuilderJoinEnum.DATE, paramName);
|
join = myQueryStack.createJoin(SearchBuilderJoinEnum.DATE, paramName);
|
||||||
myJoinMap.put(key, join);
|
joinMap.put(key, join);
|
||||||
newJoin = true;
|
newJoin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.dao.predicate.querystack;
|
||||||
import ca.uhn.fhir.jpa.dao.predicate.IndexJoins;
|
import ca.uhn.fhir.jpa.dao.predicate.IndexJoins;
|
||||||
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinEnum;
|
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinEnum;
|
||||||
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinKey;
|
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinKey;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||||
|
|
||||||
import javax.persistence.criteria.AbstractQuery;
|
import javax.persistence.criteria.AbstractQuery;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
@ -37,7 +38,9 @@ import javax.persistence.criteria.Subquery;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
abstract class QueryRootEntry {
|
abstract class QueryRootEntry {
|
||||||
|
@ -45,6 +48,7 @@ abstract class QueryRootEntry {
|
||||||
private final IndexJoins myIndexJoins = new IndexJoins();
|
private final IndexJoins myIndexJoins = new IndexJoins();
|
||||||
private final CriteriaBuilder myCriteriaBuilder;
|
private final CriteriaBuilder myCriteriaBuilder;
|
||||||
private boolean myHasImplicitTypeSelection;
|
private boolean myHasImplicitTypeSelection;
|
||||||
|
private Map<String, From<?, ResourceIndexedSearchParamDate>> myJoinMap;
|
||||||
|
|
||||||
QueryRootEntry(CriteriaBuilder theCriteriaBuilder) {
|
QueryRootEntry(CriteriaBuilder theCriteriaBuilder) {
|
||||||
myCriteriaBuilder = theCriteriaBuilder;
|
myCriteriaBuilder = theCriteriaBuilder;
|
||||||
|
@ -108,6 +112,15 @@ abstract class QueryRootEntry {
|
||||||
return getQueryRoot();
|
return getQueryRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, From<?, ResourceIndexedSearchParamDate>> getJoinMap() {
|
||||||
|
Map<String, From<?, ResourceIndexedSearchParamDate>> retVal = myJoinMap;
|
||||||
|
if (retVal==null) {
|
||||||
|
retVal = new HashMap<>();
|
||||||
|
myJoinMap = retVal;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
abstract void orderBy(List<Order> theOrders);
|
abstract void orderBy(List<Order> theOrders);
|
||||||
|
|
||||||
abstract Expression<Date> getLastUpdatedColumn();
|
abstract Expression<Date> getLastUpdatedColumn();
|
||||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.dao.predicate.querystack;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinEnum;
|
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinEnum;
|
||||||
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinKey;
|
import ca.uhn.fhir.jpa.dao.predicate.SearchBuilderJoinKey;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ import javax.persistence.criteria.Root;
|
||||||
import javax.persistence.criteria.Subquery;
|
import javax.persistence.criteria.Subquery;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
@ -281,4 +283,9 @@ public class QueryStack {
|
||||||
public Predicate addNeverMatchingPredicate() {
|
public Predicate addNeverMatchingPredicate() {
|
||||||
return top().addNeverMatchingPredicate();
|
return top().addNeverMatchingPredicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, From<?, ResourceIndexedSearchParamDate>> getJoinMap() {
|
||||||
|
return top().getJoinMap();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao;
|
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao;
|
||||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
|
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
@ -35,7 +36,6 @@ import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.param.UriParam;
|
import ca.uhn.fhir.rest.param.UriParam;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
|
||||||
import ca.uhn.fhir.util.FhirTerser;
|
import ca.uhn.fhir.util.FhirTerser;
|
||||||
import ca.uhn.fhir.util.SearchParameterUtil;
|
import ca.uhn.fhir.util.SearchParameterUtil;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -208,6 +208,7 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
|
||||||
count[i] = resources.size();
|
count[i] = resources.size();
|
||||||
|
|
||||||
for (IBaseResource next : resources) {
|
for (IBaseResource next : resources) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
next = isStructureDefinitionWithoutSnapshot(next) ? generateSnapshot(next) : next;
|
next = isStructureDefinitionWithoutSnapshot(next) ? generateSnapshot(next) : next;
|
||||||
create(next, theOutcome);
|
create(next, theOutcome);
|
||||||
|
@ -215,6 +216,7 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
|
||||||
ourLog.warn("Failed to upload resource of type {} with ID {} - Error: {}", myFhirContext.getResourceType(next), next.getIdElement().getValue(), e.toString());
|
ourLog.warn("Failed to upload resource of type {} with ID {} - Error: {}", myFhirContext.getResourceType(next), next.getIdElement().getValue(), e.toString());
|
||||||
throw new ImplementationGuideInstallationException(String.format("Error installing IG %s#%s: %s", name, version, e.toString()), e);
|
throw new ImplementationGuideInstallationException(String.format("Error installing IG %s#%s: %s", name, version, e.toString()), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -321,10 +323,11 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ourLog.info("Updating existing resource matching {}", map.toNormalizedQueryString(myFhirContext));
|
ourLog.info("Updating existing resource matching {}", map.toNormalizedQueryString(myFhirContext));
|
||||||
theOutcome.incrementResourcesInstalled(myFhirContext.getResourceType(theResource));
|
theResource.setId(searchResult.getResources(0, 1).get(0).getIdElement().toUnqualifiedVersionless());
|
||||||
theResource.setId(searchResult.getResources(0,1).get(0).getIdElement().toUnqualifiedVersionless());
|
DaoMethodOutcome outcome = dao.update(theResource);
|
||||||
dao.update(theResource);
|
if (!outcome.isNop()) {
|
||||||
|
theOutcome.incrementResourcesInstalled(myFhirContext.getResourceType(theResource));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -349,6 +352,13 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<IPrimitiveType> statusTypes = myFhirContext.newFhirPath().evaluate(theResource, "status", IPrimitiveType.class);
|
||||||
|
if (statusTypes.size() > 0) {
|
||||||
|
if (!statusTypes.get(0).getValueAsString().equals("active")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ca.uhn.fhir.jpa.dao.r4;
|
package ca.uhn.fhir.jpa.dao.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
import ca.uhn.fhir.interceptor.api.IAnonymousInterceptor;
|
import ca.uhn.fhir.interceptor.api.IAnonymousInterceptor;
|
||||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
|
@ -462,6 +463,24 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuiltInSearchParameterNotReplacedByDraftSearchParameter() {
|
||||||
|
myModelConfig.setDefaultSearchParamsCanBeOverridden(true);
|
||||||
|
|
||||||
|
SearchParameter memberSp = new SearchParameter();
|
||||||
|
memberSp.setCode("family");
|
||||||
|
memberSp.addBase("Patient");
|
||||||
|
memberSp.setType(Enumerations.SearchParamType.STRING);
|
||||||
|
memberSp.setExpression("Patient.name.family");
|
||||||
|
memberSp.setStatus(Enumerations.PublicationStatus.DRAFT);
|
||||||
|
mySearchParameterDao.create(memberSp, mySrd);
|
||||||
|
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
RuntimeSearchParam sp = mySearchParamRegistry.getActiveSearchParam("Patient", "family");
|
||||||
|
assertEquals(RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, sp.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -72,6 +72,7 @@ import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.CodeType;
|
import org.hl7.fhir.r4.model.CodeType;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
|
import org.hl7.fhir.r4.model.Communication;
|
||||||
import org.hl7.fhir.r4.model.CommunicationRequest;
|
import org.hl7.fhir.r4.model.CommunicationRequest;
|
||||||
import org.hl7.fhir.r4.model.Condition;
|
import org.hl7.fhir.r4.model.Condition;
|
||||||
import org.hl7.fhir.r4.model.ContactPoint.ContactPointSystem;
|
import org.hl7.fhir.r4.model.ContactPoint.ContactPointSystem;
|
||||||
|
@ -5080,6 +5081,34 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
||||||
assertThat(toUnqualifiedVersionlessIdValues(outcome), contains(crId));
|
assertThat(toUnqualifiedVersionlessIdValues(outcome), contains(crId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithTwoChainedDates() {
|
||||||
|
// Matches
|
||||||
|
Encounter e1 = new Encounter();
|
||||||
|
e1.setPeriod(new Period().setStartElement(new DateTimeType("2020-09-14T12:00:00Z")).setEndElement(new DateTimeType("2020-09-14T12:00:00Z")));
|
||||||
|
String e1Id = myEncounterDao.create(e1).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
Communication c1 = new Communication();
|
||||||
|
c1.getEncounter().setReference(e1Id);
|
||||||
|
myCommunicationDao.create(c1);
|
||||||
|
|
||||||
|
// Doesn't match
|
||||||
|
Encounter e2 = new Encounter();
|
||||||
|
e2.setPeriod(new Period().setStartElement(new DateTimeType("2020-02-14T12:00:00Z")).setEndElement(new DateTimeType("2020-02-14T12:00:00Z")));
|
||||||
|
String e2Id = myEncounterDao.create(e2).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
Communication c2 = new Communication();
|
||||||
|
c2.getEncounter().setReference(e2Id);
|
||||||
|
myCommunicationDao.create(c2);
|
||||||
|
|
||||||
|
SearchParameterMap map = SearchParameterMap.newSynchronous();
|
||||||
|
map.add(Communication.SP_ENCOUNTER, new ReferenceParam("ge2020-09-14").setChain("date"));
|
||||||
|
map.add(Communication.SP_ENCOUNTER, new ReferenceParam("le2020-09-15").setChain("date"));
|
||||||
|
|
||||||
|
IBundleProvider outcome = myCommunicationDao.search(map);
|
||||||
|
assertEquals(1, outcome.sizeOrThrowNpe());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCircularReferencesDontBreakRevIncludes() {
|
public void testCircularReferencesDontBreakRevIncludes() {
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -114,6 +115,20 @@ public class NpmTestR4 extends BaseJpaR4Test {
|
||||||
|
|
||||||
PackageInstallationSpec spec = new PackageInstallationSpec().setName("hl7.fhir.us.core").setVersion("3.1.0").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL).setFetchDependencies(true);
|
PackageInstallationSpec spec = new PackageInstallationSpec().setName("hl7.fhir.us.core").setVersion("3.1.0").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL).setFetchDependencies(true);
|
||||||
igInstaller.install(spec);
|
igInstaller.install(spec);
|
||||||
|
|
||||||
|
runInTransaction(()->{
|
||||||
|
SearchParameterMap map = SearchParameterMap.newSynchronous(SearchParameter.SP_BASE, new TokenParam("NamingSystem"));
|
||||||
|
IBundleProvider outcome = mySearchParameterDao.search(map);
|
||||||
|
List<IBaseResource> resources = outcome.getResources(0, outcome.sizeOrThrowNpe());
|
||||||
|
for (int i = 0; i < resources.size(); i++) {
|
||||||
|
ourLog.info("**************************************************************************");
|
||||||
|
ourLog.info("**************************************************************************");
|
||||||
|
ourLog.info("Res " + i);
|
||||||
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resources.get(i)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
igInstaller.install(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,7 +177,8 @@ public class NpmTestR4 extends BaseJpaR4Test {
|
||||||
myFakeNpmServlet.myResponses.put("/hl7.fhir.uv.shorthand/0.12.0", bytes);
|
myFakeNpmServlet.myResponses.put("/hl7.fhir.uv.shorthand/0.12.0", bytes);
|
||||||
|
|
||||||
PackageInstallationSpec spec = new PackageInstallationSpec().setName("hl7.fhir.uv.shorthand").setVersion("0.12.0").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL);
|
PackageInstallationSpec spec = new PackageInstallationSpec().setName("hl7.fhir.uv.shorthand").setVersion("0.12.0").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL);
|
||||||
igInstaller.install(spec);
|
PackageInstallOutcomeJson outcome = igInstaller.install(spec);
|
||||||
|
assertEquals(1, outcome.getResourcesInstalled().get("CodeSystem"));
|
||||||
|
|
||||||
// Be sure no further communication with the server
|
// Be sure no further communication with the server
|
||||||
JettyUtil.closeServer(myServer);
|
JettyUtil.closeServer(myServer);
|
||||||
|
@ -215,11 +231,25 @@ public class NpmTestR4 extends BaseJpaR4Test {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
SearchParameterMap map = SearchParameterMap.newSynchronous();
|
SearchParameterMap map = SearchParameterMap.newSynchronous();
|
||||||
map.add(StructureDefinition.SP_URL, new UriParam("http://hl7.org/fhir/uv/shorthand/CodeSystem/shorthand-code-system"));
|
map.add(StructureDefinition.SP_URL, new UriParam("http://hl7.org/fhir/uv/shorthand/CodeSystem/shorthand-code-system"));
|
||||||
IBundleProvider outcome = myCodeSystemDao.search(map);
|
IBundleProvider result = myCodeSystemDao.search(map);
|
||||||
assertEquals(1, outcome.sizeOrThrowNpe());
|
assertEquals(1, result.sizeOrThrowNpe());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInstallR4Package_DraftResourcesNotInstalled() throws Exception {
|
||||||
|
myDaoConfig.setAllowExternalReferences(true);
|
||||||
|
|
||||||
|
byte[] bytes = loadClasspathBytes("/packages/test-draft-sample.tgz");
|
||||||
|
myFakeNpmServlet.myResponses.put("/hl7.fhir.uv.shorthand/0.11.1", bytes);
|
||||||
|
|
||||||
|
PackageInstallationSpec spec = new PackageInstallationSpec().setName("hl7.fhir.uv.shorthand").setVersion("0.11.1").setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL);
|
||||||
|
PackageInstallOutcomeJson outcome = igInstaller.install(spec);
|
||||||
|
assertEquals(0, outcome.getResourcesInstalled().size(), outcome.getResourcesInstalled().toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInstallR4Package_Twice() throws Exception {
|
public void testInstallR4Package_Twice() throws Exception {
|
||||||
myDaoConfig.setAllowExternalReferences(true);
|
myDaoConfig.setAllowExternalReferences(true);
|
||||||
|
@ -236,6 +266,11 @@ public class NpmTestR4 extends BaseJpaR4Test {
|
||||||
igInstaller.install(spec);
|
igInstaller.install(spec);
|
||||||
outcome = igInstaller.install(spec);
|
outcome = igInstaller.install(spec);
|
||||||
assertEquals(null, outcome.getResourcesInstalled().get("CodeSystem"));
|
assertEquals(null, outcome.getResourcesInstalled().get("CodeSystem"));
|
||||||
|
|
||||||
|
// Ensure that we loaded the contents
|
||||||
|
IBundleProvider searchResult = myCodeSystemDao.search(SearchParameterMap.newSynchronous("url", new UriParam("http://hl7.org/fhir/uv/shorthand/CodeSystem/shorthand-code-system")));
|
||||||
|
assertEquals(1, searchResult.sizeOrThrowNpe());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,9 +292,6 @@ public class NpmTestR4 extends BaseJpaR4Test {
|
||||||
assertEquals(null, pkg.description());
|
assertEquals(null, pkg.description());
|
||||||
assertEquals("UK.Core.r4", pkg.name());
|
assertEquals("UK.Core.r4", pkg.name());
|
||||||
|
|
||||||
// Ensure that we loaded the contents
|
|
||||||
IBundleProvider searchResult = myStructureDefinitionDao.search(SearchParameterMap.newSynchronous("url", new UriParam("https://fhir.nhs.uk/R4/StructureDefinition/UKCore-Patient")));
|
|
||||||
assertEquals(1, searchResult.sizeOrThrowNpe());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Binary file not shown.
|
@ -291,6 +291,9 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry {
|
||||||
if (runtimeSp == null) {
|
if (runtimeSp == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (runtimeSp.getStatus() == RuntimeSearchParam.RuntimeSearchParamStatusEnum.DRAFT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (String nextBaseName : SearchParameterUtil.getBaseAsStrings(myFhirContext, nextSp)) {
|
for (String nextBaseName : SearchParameterUtil.getBaseAsStrings(myFhirContext, nextSp)) {
|
||||||
if (isBlank(nextBaseName)) {
|
if (isBlank(nextBaseName)) {
|
||||||
|
|
|
@ -268,7 +268,7 @@ public class PersonHelper {
|
||||||
if (theAllowOverwriting || person.getName().isEmpty()) {
|
if (theAllowOverwriting || person.getName().isEmpty()) {
|
||||||
person.setName(patient.getName());
|
person.setName(patient.getName());
|
||||||
}
|
}
|
||||||
if (theAllowOverwriting || person.getName().isEmpty()) {
|
if (theAllowOverwriting || person.getAddress().isEmpty()) {
|
||||||
person.setAddress(patient.getAddress());
|
person.setAddress(patient.getAddress());
|
||||||
}
|
}
|
||||||
if (theAllowOverwriting || person.getTelecom().isEmpty()) {
|
if (theAllowOverwriting || person.getTelecom().isEmpty()) {
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging;
|
package ca.uhn.fhir.rest.server.messaging;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging;
|
package ca.uhn.fhir.rest.server.messaging;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging;
|
package ca.uhn.fhir.rest.server.messaging;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface IResourceMessage {
|
public interface IResourceMessage {
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging;
|
package ca.uhn.fhir.rest.server.messaging;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging.json;
|
package ca.uhn.fhir.rest.server.messaging.json;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging.json;
|
package ca.uhn.fhir.rest.server.messaging.json;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.springframework.messaging.MessageHeaders;
|
import org.springframework.messaging.MessageHeaders;
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
package ca.uhn.fhir.rest.server.messaging.json;
|
package ca.uhn.fhir.rest.server.messaging.json;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Server Framework
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2020 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
|
|
@ -332,6 +332,7 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
||||||
sortSearchParameters(searchParameters);
|
sortSearchParameters(searchParameters);
|
||||||
if (!searchParameters.isEmpty()) {
|
if (!searchParameters.isEmpty()) {
|
||||||
|
|
||||||
|
Set<String> paramNames = new HashSet<>();
|
||||||
for (SearchParameter nextParameter : searchParameters) {
|
for (SearchParameter nextParameter : searchParameters) {
|
||||||
|
|
||||||
if (nextParameter.getParamType() == null) {
|
if (nextParameter.getParamType() == null) {
|
||||||
|
@ -346,6 +347,10 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
||||||
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
|
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!paramNames.add(nextParamUnchainedName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String nextParamDescription = nextParameter.getDescription();
|
String nextParamDescription = nextParameter.getDescription();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -425,6 +430,8 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
||||||
param.setMin(nextParam.isRequired() ? 1 : 0);
|
param.setMin(nextParam.isRequired() ? 1 : 0);
|
||||||
param.setMax("1");
|
param.setMax("1");
|
||||||
param.setName(nextParam.getName());
|
param.setName(nextParam.getName());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,26 @@ import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.model.api.annotation.Description;
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.rest.annotation.*;
|
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Delete;
|
||||||
|
import ca.uhn.fhir.rest.annotation.History;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Read;
|
||||||
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Update;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Validate;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.param.DateParam;
|
||||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||||
|
@ -27,7 +42,8 @@ import ca.uhn.fhir.validation.ValidationResult;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.hapi.rest.server.ServerCapabilityStatementProvider;
|
import org.hl7.fhir.r4.hapi.rest.server.ServerCapabilityStatementProvider;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.CapabilityStatement;
|
||||||
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent;
|
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent;
|
||||||
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
||||||
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent;
|
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent;
|
||||||
|
@ -35,10 +51,18 @@ import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResource
|
||||||
import org.hl7.fhir.r4.model.CapabilityStatement.ConditionalDeleteStatus;
|
import org.hl7.fhir.r4.model.CapabilityStatement.ConditionalDeleteStatus;
|
||||||
import org.hl7.fhir.r4.model.CapabilityStatement.SystemRestfulInteraction;
|
import org.hl7.fhir.r4.model.CapabilityStatement.SystemRestfulInteraction;
|
||||||
import org.hl7.fhir.r4.model.CapabilityStatement.TypeRestfulInteraction;
|
import org.hl7.fhir.r4.model.CapabilityStatement.TypeRestfulInteraction;
|
||||||
|
import org.hl7.fhir.r4.model.CodeType;
|
||||||
|
import org.hl7.fhir.r4.model.DateType;
|
||||||
|
import org.hl7.fhir.r4.model.DiagnosticReport;
|
||||||
|
import org.hl7.fhir.r4.model.Encounter;
|
||||||
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
|
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
|
||||||
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
import org.hl7.fhir.r4.model.OperationDefinition;
|
||||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
|
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationKind;
|
import org.hl7.fhir.r4.model.OperationDefinition.OperationKind;
|
||||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse;
|
import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -49,6 +73,7 @@ import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
@ -65,8 +90,12 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class ServerCapabilityStatementProviderR4Test {
|
public class ServerCapabilityStatementProviderR4Test {
|
||||||
|
|
||||||
private static FhirContext ourCtx;
|
public static final String PATIENT_SUB = "PatientSub";
|
||||||
|
public static final String PATIENT_SUB_SUB = "PatientSubSub";
|
||||||
|
public static final String PATIENT_SUB_SUB_2 = "PatientSubSub2";
|
||||||
|
public static final String PATIENT_TRIPLE_SUB = "PatientTripleSub";
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProviderR4Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProviderR4Test.class);
|
||||||
|
private static FhirContext ourCtx;
|
||||||
private static FhirValidator ourValidator;
|
private static FhirValidator ourValidator;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -259,7 +288,9 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
assertNull(res.getConditionalUpdateElement().getValue());
|
assertNull(res.getConditionalUpdateElement().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See #379 */
|
/**
|
||||||
|
* See #379
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testOperationAcrossMultipleTypes() throws Exception {
|
public void testOperationAcrossMultipleTypes() throws Exception {
|
||||||
RestfulServer rs = new RestfulServer(ourCtx);
|
RestfulServer rs = new RestfulServer(ourCtx);
|
||||||
|
@ -513,10 +544,10 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
for (ResourceBinding resourceBinding : resourceBindings) {
|
for (ResourceBinding resourceBinding : resourceBindings) {
|
||||||
if (resourceBinding.getResourceName().equals("Patient")) {
|
if (resourceBinding.getResourceName().equals("Patient")) {
|
||||||
List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings();
|
List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings();
|
||||||
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
|
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
|
||||||
SearchParameter param = (SearchParameter) binding.getParameters().get(25);
|
SearchParameter param = (SearchParameter) binding.getParameters().get(25);
|
||||||
assertEquals("The organization at which this person is a patient", param.getDescription());
|
assertEquals("The organization at which this person is a patient", param.getDescription());
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTrue(found);
|
assertTrue(found);
|
||||||
|
@ -569,7 +600,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
@Test
|
@Test
|
||||||
public void testSearchReferenceParameterWithList() throws Exception {
|
public void testSearchReferenceParameterWithList() throws Exception {
|
||||||
|
|
||||||
RestfulServer rsNoType = new RestfulServer(ourCtx){
|
RestfulServer rsNoType = new RestfulServer(ourCtx) {
|
||||||
@Override
|
@Override
|
||||||
public RestfulServerConfiguration createConfiguration() {
|
public RestfulServerConfiguration createConfiguration() {
|
||||||
RestfulServerConfiguration retVal = super.createConfiguration();
|
RestfulServerConfiguration retVal = super.createConfiguration();
|
||||||
|
@ -586,7 +617,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
String confNoType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
|
String confNoType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
|
||||||
ourLog.info(confNoType);
|
ourLog.info(confNoType);
|
||||||
|
|
||||||
RestfulServer rsWithType = new RestfulServer(ourCtx){
|
RestfulServer rsWithType = new RestfulServer(ourCtx) {
|
||||||
@Override
|
@Override
|
||||||
public RestfulServerConfiguration createConfiguration() {
|
public RestfulServerConfiguration createConfiguration() {
|
||||||
RestfulServerConfiguration retVal = super.createConfiguration();
|
RestfulServerConfiguration retVal = super.createConfiguration();
|
||||||
|
@ -645,6 +676,46 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
assertThat(conf, containsString("<interaction><code value=\"" + TypeRestfulInteraction.HISTORYTYPE.toCode() + "\"/></interaction>"));
|
assertThat(conf, containsString("<interaction><code value=\"" + TypeRestfulInteraction.HISTORYTYPE.toCode() + "\"/></interaction>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStaticIncludeChains() throws Exception {
|
||||||
|
|
||||||
|
class MyProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<DiagnosticReport> getResourceType() {
|
||||||
|
return DiagnosticReport.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public List<IBaseResource> search(@RequiredParam(name = DiagnosticReport.SP_PATIENT + "." + Patient.SP_FAMILY) StringParam lastName,
|
||||||
|
@RequiredParam(name = DiagnosticReport.SP_PATIENT + "." + Patient.SP_GIVEN) StringParam firstName,
|
||||||
|
@RequiredParam(name = DiagnosticReport.SP_PATIENT + "." + Patient.SP_BIRTHDATE) DateParam dob,
|
||||||
|
@OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam range) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RestfulServer rs = new RestfulServer(ourCtx);
|
||||||
|
rs.setProviders(new MyProvider());
|
||||||
|
|
||||||
|
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider() {
|
||||||
|
};
|
||||||
|
rs.setServerConformanceProvider(sc);
|
||||||
|
|
||||||
|
rs.init(createServletConfig());
|
||||||
|
|
||||||
|
CapabilityStatement opDef = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
|
||||||
|
|
||||||
|
String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef);
|
||||||
|
ourLog.info(conf);
|
||||||
|
|
||||||
|
CapabilityStatementRestResourceComponent resource = opDef.getRest().get(0).getResource().get(0);
|
||||||
|
assertEquals("DiagnosticReport", resource.getType());
|
||||||
|
List<String> searchParamNames = resource.getSearchParam().stream().map(t -> t.getName()).collect(Collectors.toList());
|
||||||
|
assertThat(searchParamNames, containsInAnyOrder("patient", "date"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSystemLevelNamedQueryWithParameters() throws Exception {
|
public void testSystemLevelNamedQueryWithParameters() throws Exception {
|
||||||
RestfulServer rs = new RestfulServer(ourCtx);
|
RestfulServer rs = new RestfulServer(ourCtx);
|
||||||
|
@ -729,8 +800,8 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
assertThat(param.getUse(), is(OperationParameterUse.IN));
|
assertThat(param.getUse(), is(OperationParameterUse.IN));
|
||||||
|
|
||||||
CapabilityStatementRestResourceComponent patientResource = restComponent.getResource().stream()
|
CapabilityStatementRestResourceComponent patientResource = restComponent.getResource().stream()
|
||||||
.filter(r -> patientResourceName.equals(r.getType()))
|
.filter(r -> patientResourceName.equals(r.getType()))
|
||||||
.findAny().get();
|
.findAny().get();
|
||||||
assertThat("Named query parameters should not appear in the resource search params", patientResource.getSearchParam(), is(empty()));
|
assertThat("Named query parameters should not appear in the resource search params", patientResource.getSearchParam(), is(empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,25 +833,25 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
assertThat(opDef.getInstance(), is(false));
|
assertThat(opDef.getInstance(), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProfiledResourceStructureDefinitionLinks() throws Exception {
|
public void testProfiledResourceStructureDefinitionLinks() throws Exception {
|
||||||
RestfulServer rs = new RestfulServer(ourCtx);
|
RestfulServer rs = new RestfulServer(ourCtx);
|
||||||
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
|
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
|
||||||
|
|
||||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||||
rs.setServerConformanceProvider(sc);
|
rs.setServerConformanceProvider(sc);
|
||||||
|
|
||||||
rs.init(createServletConfig());
|
rs.init(createServletConfig());
|
||||||
|
|
||||||
CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
|
CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
|
||||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
|
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
|
||||||
|
|
||||||
List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource();
|
List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource();
|
||||||
CapabilityStatementRestResourceComponent patientResource = resources.stream()
|
CapabilityStatementRestResourceComponent patientResource = resources.stream()
|
||||||
.filter(resource -> "Patient".equals(resource.getType()))
|
.filter(resource -> "Patient".equals(resource.getType()))
|
||||||
.findFirst().get();
|
.findFirst().get();
|
||||||
assertThat(patientResource.getProfile(), containsString(PATIENT_SUB));
|
assertThat(patientResource.getProfile(), containsString(PATIENT_SUB));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> toOperationIdParts(List<CapabilityStatementRestResourceOperationComponent> theOperation) {
|
private List<String> toOperationIdParts(List<CapabilityStatementRestResourceOperationComponent> theOperation) {
|
||||||
ArrayList<String> retVal = Lists.newArrayList();
|
ArrayList<String> retVal = Lists.newArrayList();
|
||||||
|
@ -817,11 +888,6 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
assertTrue(result.isSuccessful(), outcome);
|
assertTrue(result.isSuccessful(), outcome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void afterClassClearContext() {
|
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class ConditionalProvider implements IResourceProvider {
|
public static class ConditionalProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
@ -866,7 +932,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
|
|
||||||
@Search(type = Patient.class)
|
@Search(type = Patient.class)
|
||||||
public Patient findPatient(@Description(shortDefinition = "The patient's identifier") @OptionalParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier,
|
public Patient findPatient(@Description(shortDefinition = "The patient's identifier") @OptionalParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier,
|
||||||
@Description(shortDefinition = "The patient's name") @OptionalParam(name = Patient.SP_NAME) StringParam theName) {
|
@Description(shortDefinition = "The patient's name") @OptionalParam(name = Patient.SP_NAME) StringParam theName) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +1008,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class PlainProviderWithExtendedOperationOnNoType {
|
public static class PlainProviderWithExtendedOperationOnNoType {
|
||||||
|
|
||||||
@Operation(name = "plain", idempotent = true, returnParameters = { @OperationParam(min = 1, max = 2, name = "out1", type = StringType.class) })
|
@Operation(name = "plain", idempotent = true, returnParameters = {@OperationParam(min = 1, max = 2, name = "out1", type = StringType.class)})
|
||||||
public IBundleProvider everything(HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart,
|
public IBundleProvider everything(HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart,
|
||||||
@OperationParam(name = "end") DateType theEnd) {
|
@OperationParam(name = "end") DateType theEnd) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -972,8 +1038,8 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
@Description(shortDefinition = "This is a search for stuff!")
|
@Description(shortDefinition = "This is a search for stuff!")
|
||||||
@Search
|
@Search
|
||||||
public List<DiagnosticReport> findDiagnosticReportsByPatient(@RequiredParam(name = DiagnosticReport.SP_SUBJECT + '.' + Patient.SP_IDENTIFIER) TokenParam thePatientId,
|
public List<DiagnosticReport> findDiagnosticReportsByPatient(@RequiredParam(name = DiagnosticReport.SP_SUBJECT + '.' + Patient.SP_IDENTIFIER) TokenParam thePatientId,
|
||||||
@OptionalParam(name = DiagnosticReport.SP_CODE) TokenOrListParam theNames, @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange,
|
@OptionalParam(name = DiagnosticReport.SP_CODE) TokenOrListParam theNames, @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange,
|
||||||
@IncludeParam(allow = { "DiagnosticReport.result" }) Set<Include> theIncludes) throws Exception {
|
@IncludeParam(allow = {"DiagnosticReport.result"}) Set<Include> theIncludes) throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,7 +1070,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
|
|
||||||
@Search(type = Patient.class)
|
@Search(type = Patient.class)
|
||||||
public Patient findPatient2(
|
public Patient findPatient2(
|
||||||
@Description(shortDefinition = "All patients linked to the given patient") @OptionalParam(name = "link", targetTypes = { Patient.class }) ReferenceAndListParam theLink) {
|
@Description(shortDefinition = "All patients linked to the given patient") @OptionalParam(name = "link", targetTypes = {Patient.class}) ReferenceAndListParam theLink) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,15 +1080,15 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
public static class SearchProviderWithWhitelist {
|
public static class SearchProviderWithWhitelist {
|
||||||
|
|
||||||
@Search(type = Patient.class)
|
@Search(type = Patient.class)
|
||||||
public Patient findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION, chainWhitelist = { "foo",
|
public Patient findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION, chainWhitelist = {"foo",
|
||||||
"bar" }) ReferenceAndListParam theIdentifier) {
|
"bar"}) ReferenceAndListParam theIdentifier) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class SearchProviderWithListNoType implements IResourceProvider {
|
public static class SearchProviderWithListNoType implements IResourceProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends IBaseResource> getResourceType() {
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
|
@ -1030,7 +1096,6 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Search()
|
@Search()
|
||||||
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
|
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1039,7 +1104,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static class SearchProviderWithListWithType implements IResourceProvider {
|
public static class SearchProviderWithListWithType implements IResourceProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends IBaseResource> getResourceType() {
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
|
@ -1047,15 +1112,13 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Search(type = Patient.class)
|
||||||
@Search(type=Patient.class)
|
|
||||||
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
|
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class SystemHistoryProvider {
|
public static class SystemHistoryProvider {
|
||||||
|
|
||||||
@History
|
@History
|
||||||
|
@ -1140,48 +1203,52 @@ public class ServerCapabilityStatementProviderR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ProfiledPatientProvider implements IResourceProvider {
|
public static class ProfiledPatientProvider implements IResourceProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends IBaseResource> getResourceType() {
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
return PatientSubSub2.class;
|
return PatientSubSub2.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Search
|
@Search
|
||||||
public List<PatientSubSub2> find() {
|
public List<PatientSubSub2> find() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MultipleProfilesPatientProvider implements IResourceProvider {
|
public static class MultipleProfilesPatientProvider implements IResourceProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends IBaseResource> getResourceType() {
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
return PatientSubSub.class;
|
return PatientSubSub.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Read(type = PatientTripleSub.class)
|
@Read(type = PatientTripleSub.class)
|
||||||
public PatientTripleSub read(@IdParam IdType theId) {
|
public PatientTripleSub read(@IdParam IdType theId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String PATIENT_SUB = "PatientSub";
|
@ResourceDef(id = PATIENT_SUB)
|
||||||
public static final String PATIENT_SUB_SUB = "PatientSubSub";
|
public static class PatientSub extends Patient {
|
||||||
public static final String PATIENT_SUB_SUB_2 = "PatientSubSub2";
|
}
|
||||||
public static final String PATIENT_TRIPLE_SUB = "PatientTripleSub";
|
|
||||||
|
|
||||||
@ResourceDef(id = PATIENT_SUB)
|
@ResourceDef(id = PATIENT_SUB_SUB)
|
||||||
public static class PatientSub extends Patient {}
|
public static class PatientSubSub extends PatientSub {
|
||||||
|
}
|
||||||
|
|
||||||
@ResourceDef(id = PATIENT_SUB_SUB)
|
@ResourceDef(id = PATIENT_SUB_SUB_2)
|
||||||
public static class PatientSubSub extends PatientSub {}
|
public static class PatientSubSub2 extends PatientSub {
|
||||||
|
}
|
||||||
|
|
||||||
@ResourceDef(id = PATIENT_SUB_SUB_2)
|
@ResourceDef(id = PATIENT_TRIPLE_SUB)
|
||||||
public static class PatientSubSub2 extends PatientSub {}
|
public static class PatientTripleSub extends PatientSubSub {
|
||||||
|
}
|
||||||
|
|
||||||
@ResourceDef(id = PATIENT_TRIPLE_SUB)
|
@AfterAll
|
||||||
public static class PatientTripleSub extends PatientSubSub {}
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue