Merge remote-tracking branch 'remotes/origin/master' into ks-flyway
# Conflicts: # hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropIndexTask.java # hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/DropTableTask.java
This commit is contained in:
commit
bee993a0ec
|
@ -46,6 +46,7 @@ import ca.uhn.fhir.rest.api.server.IRestfulResponse;
|
|||
import ca.uhn.fhir.rest.server.*;
|
||||
import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* This is the conformance provider for the jax rs servers. It requires all providers to be registered during startup because the conformance profile is generated during the postconstruct phase.
|
||||
|
@ -119,7 +120,8 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
return;
|
||||
}
|
||||
|
||||
for (Entry<Class<? extends IResourceProvider>, IResourceProvider> provider : getProviders().entrySet()) {
|
||||
ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> providers = getProviders();
|
||||
for (Entry<Class<? extends IResourceProvider>, IResourceProvider> provider : providers.entrySet()) {
|
||||
addProvider(provider.getValue(), provider.getKey());
|
||||
}
|
||||
List<BaseMethodBinding<?>> serverBindings = new ArrayList<BaseMethodBinding<?>>();
|
||||
|
@ -128,6 +130,7 @@ public abstract class AbstractJaxRsConformanceProvider extends AbstractJaxRsProv
|
|||
}
|
||||
serverConfiguration.setServerBindings(serverBindings);
|
||||
serverConfiguration.setResourceBindings(new LinkedList<ResourceBinding>(myResourceNameToBinding.values()));
|
||||
serverConfiguration.computeSharedSupertypeForResourcePerName(providers.values());
|
||||
HardcodedServerAddressStrategy hardcodedServerAddressStrategy = new HardcodedServerAddressStrategy();
|
||||
hardcodedServerAddressStrategy.setValue(getBaseForServer());
|
||||
serverConfiguration.setServerAddressStrategy(hardcodedServerAddressStrategy);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ca.uhn.fhir.jaxrs.server;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider;
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsMockPatientRestProviderDstu3;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
@ -20,6 +19,8 @@ import static org.junit.Assert.*;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProviderDstu3;
|
||||
|
||||
public class AbstractJaxRsConformanceProviderDstu3Test {
|
||||
|
||||
private static final String BASEURI = "http://basiuri";
|
||||
|
@ -46,7 +47,7 @@ public class AbstractJaxRsConformanceProviderDstu3Test {
|
|||
@Test
|
||||
public void testConformance() throws Exception {
|
||||
providers.put(AbstractJaxRsConformanceProvider.class, provider);
|
||||
providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider());
|
||||
providers.put(TestJaxRsDummyPatientProviderDstu3.class, new TestJaxRsDummyPatientProviderDstu3());
|
||||
Response response = createConformanceProvider(providers).conformance();
|
||||
System.out.println(response);
|
||||
}
|
||||
|
@ -54,7 +55,7 @@ public class AbstractJaxRsConformanceProviderDstu3Test {
|
|||
@Test
|
||||
public void testConformanceUsingOptions() throws Exception {
|
||||
providers.put(AbstractJaxRsConformanceProvider.class, provider);
|
||||
providers.put(TestJaxRsDummyPatientProvider.class, new TestJaxRsDummyPatientProvider());
|
||||
providers.put(TestJaxRsDummyPatientProviderDstu3.class, new TestJaxRsDummyPatientProviderDstu3());
|
||||
Response response = createConformanceProvider(providers).conformanceUsingOptions();
|
||||
System.out.println(response);
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ package ca.uhn.fhir.jpa.migrate.taskdef;
|
|||
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
|
||||
import ca.uhn.fhir.jpa.migrate.JdbcUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class DropIndexTask extends BaseTableTask<DropIndexTask> {
|
||||
|
||||
|
@ -63,10 +63,12 @@ public class DropIndexTask extends BaseTableTask<DropIndexTask> {
|
|||
boolean isUnique = JdbcUtils.isIndexUnique(getConnectionProperties(), getTableName(), myIndexName);
|
||||
String uniquenessString = isUnique ? "unique" : "non-unique";
|
||||
|
||||
Optional<String> sql = createDropIndexSql(getConnectionProperties(), getTableName(), myIndexName, getDriverType());
|
||||
if (sql.isPresent()) {
|
||||
logInfo(ourLog, "Dropping {} index {} on table {}", uniquenessString, myIndexName, getTableName());
|
||||
executeSql(getTableName(), sql.get());
|
||||
List<String> sqls = createDropIndexSql(getConnectionProperties(), getTableName(), myIndexName, getDriverType());
|
||||
if (!sqls.isEmpty()) {
|
||||
logInfo("Dropping {} index {} on table {}", uniquenessString, myIndexName, getTableName());
|
||||
}
|
||||
for (@Language("SQL") String sql : sqls) {
|
||||
executeSql(getTableName(), sql);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,35 +77,36 @@ public class DropIndexTask extends BaseTableTask<DropIndexTask> {
|
|||
return this;
|
||||
}
|
||||
|
||||
static Optional<String> createDropIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theIndexName, DriverTypeEnum theDriverType) throws SQLException {
|
||||
static List<String> createDropIndexSql(DriverTypeEnum.ConnectionProperties theConnectionProperties, String theTableName, String theIndexName, DriverTypeEnum theDriverType) throws SQLException {
|
||||
Validate.notBlank(theIndexName, "theIndexName must not be blank");
|
||||
Validate.notBlank(theTableName, "theTableName must not be blank");
|
||||
|
||||
if (!JdbcUtils.getIndexNames(theConnectionProperties, theTableName).contains(theIndexName)) {
|
||||
return Optional.empty();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
boolean isUnique = JdbcUtils.isIndexUnique(theConnectionProperties, theTableName, theIndexName);
|
||||
|
||||
String sql = null;
|
||||
List<String> sql = new ArrayList<>();
|
||||
|
||||
if (isUnique) {
|
||||
// Drop constraint
|
||||
switch (theDriverType) {
|
||||
case MYSQL_5_7:
|
||||
case MARIADB_10_1:
|
||||
sql = "alter table " + theTableName + " drop index " + theIndexName;
|
||||
sql.add("alter table " + theTableName + " drop index " + theIndexName);
|
||||
break;
|
||||
case H2_EMBEDDED:
|
||||
case DERBY_EMBEDDED:
|
||||
sql = "drop index " + theIndexName;
|
||||
sql.add("drop index " + theIndexName);
|
||||
break;
|
||||
case POSTGRES_9_4:
|
||||
sql = "drop index " + theIndexName + " cascade";
|
||||
sql.add("alter table " + theTableName + " drop constraint if exists " + theIndexName + " cascade");
|
||||
sql.add("drop index if exists " + theIndexName + " cascade");
|
||||
break;
|
||||
case ORACLE_12C:
|
||||
case MSSQL_2012:
|
||||
sql = "alter table " + theTableName + " drop constraint " + theIndexName;
|
||||
sql.add("alter table " + theTableName + " drop constraint " + theIndexName);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -111,20 +114,20 @@ public class DropIndexTask extends BaseTableTask<DropIndexTask> {
|
|||
switch (theDriverType) {
|
||||
case MYSQL_5_7:
|
||||
case MARIADB_10_1:
|
||||
sql = "alter table " + theTableName + " drop index " + theIndexName;
|
||||
sql.add("alter table " + theTableName + " drop index " + theIndexName);
|
||||
break;
|
||||
case POSTGRES_9_4:
|
||||
case DERBY_EMBEDDED:
|
||||
case H2_EMBEDDED:
|
||||
case ORACLE_12C:
|
||||
sql = "drop index " + theIndexName;
|
||||
sql.add("drop index " + theIndexName);
|
||||
break;
|
||||
case MSSQL_2012:
|
||||
sql = "drop index " + theTableName + "." + theIndexName;
|
||||
sql.add("drop index " + theTableName + "." + theIndexName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Optional.of(sql);
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.migrate.taskdef;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.migrate.JdbcUtils;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -52,21 +53,24 @@ public class DropTableTask extends BaseTableTask<DropTableTask> {
|
|||
|
||||
for (String next : foreignKeys) {
|
||||
List<String> sql = DropForeignKeyTask.generateSql(getTableName(), next, getDriverType());
|
||||
for (String nextSql : sql) {
|
||||
for (@Language("SQL") String nextSql : sql) {
|
||||
executeSql(getTableName(), nextSql);
|
||||
}
|
||||
}
|
||||
|
||||
for (String nextIndex : indexNames) {
|
||||
Optional<String> sql = DropIndexTask.createDropIndexSql(getConnectionProperties(), getTableName(), nextIndex, getDriverType());
|
||||
if (sql.isPresent()) {
|
||||
logInfo(ourLog, "Dropping index {} on table {} in preparation for table delete", nextIndex, getTableName());
|
||||
executeSql(getTableName(), sql.get());
|
||||
List<String> sqls = DropIndexTask.createDropIndexSql(getConnectionProperties(), getTableName(), nextIndex, getDriverType());
|
||||
if (!sqls.isEmpty()) {
|
||||
logInfo("Dropping index {} on table {} in preparation for table delete", nextIndex, getTableName());
|
||||
}
|
||||
for (@Language("SQL") String sql : sqls) {
|
||||
executeSql(getTableName(), sql);
|
||||
}
|
||||
}
|
||||
|
||||
logInfo(ourLog, "Dropping table: {}", getTableName());
|
||||
|
||||
@Language("SQL")
|
||||
String sql = "DROP TABLE " + getTableName();
|
||||
executeSql(getTableName(), sql);
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* When populating the StructureDefinition links in a capability statement,
|
||||
* it can be useful to know the lowest common superclass for the profiles in use for a given resource name.
|
||||
* This class finds this superclass, by incrementally computing the greatest common sequence of ancestor classes in the class hierarchies of registered resources.
|
||||
* For instance, given the following classes
|
||||
* MyPatient extends Patient
|
||||
* MyPatient2 extends MyPatient
|
||||
* MyPatient3 extends MyPatient
|
||||
* MyPatient4 extends MyPatient3
|
||||
* this class will find the common ancestor sequence "IBaseResource -> Patient -> MyPatient". MyPatient is the lowest common superclass in this hierarchy.
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class CommonResourceSupertypeScanner {
|
||||
|
||||
private List<Class<? extends IBaseResource>> greatestSharedAncestorsDescending;
|
||||
private boolean initialized;
|
||||
|
||||
/**
|
||||
* Recomputes the lowest common superclass by adding a new resource definition to the hierarchy.
|
||||
* @param resourceClass The resource class to add.
|
||||
*/
|
||||
public void register(Class<? extends IBaseResource> resourceClass) {
|
||||
List<Class<? extends IBaseResource>> resourceClassesInHierarchy = new LinkedList<>();
|
||||
Class<?> currentClass = resourceClass;
|
||||
while (IBaseResource.class.isAssignableFrom(currentClass)
|
||||
&& currentClass.getAnnotation(ResourceDef.class) != null) {
|
||||
resourceClassesInHierarchy.add((Class<? extends IBaseResource>)currentClass);
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
Collections.reverse(resourceClassesInHierarchy);
|
||||
if (initialized) {
|
||||
for (int i = 0; i < Math.min(resourceClassesInHierarchy.size(), greatestSharedAncestorsDescending.size()); i++) {
|
||||
if (greatestSharedAncestorsDescending.get(i) != resourceClassesInHierarchy.get(i)) {
|
||||
greatestSharedAncestorsDescending = greatestSharedAncestorsDescending.subList(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
greatestSharedAncestorsDescending = resourceClassesInHierarchy;
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The lowest common superclass of currently registered resources.
|
||||
*/
|
||||
public Optional<Class<? extends IBaseResource>> getLowestCommonSuperclass() {
|
||||
if (!initialized || greatestSharedAncestorsDescending.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.ofNullable(greatestSharedAncestorsDescending.get(greatestSharedAncestorsDescending.size() - 1));
|
||||
}
|
||||
|
||||
}
|
|
@ -208,6 +208,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
} catch (Exception e) {
|
||||
// fall through
|
||||
}
|
||||
result.computeSharedSupertypeForResourcePerName(getResourceProviders());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,11 +33,16 @@ import java.util.*;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import java.util.stream.Collectors;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
public class RestfulServerConfiguration {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestfulServerConfiguration.class);
|
||||
private Collection<ResourceBinding> resourceBindings;
|
||||
private List<BaseMethodBinding<?>> serverBindings;
|
||||
private Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype;
|
||||
private String implementationDescription;
|
||||
private String serverVersion = VersionUtil.getVersion();
|
||||
private String serverName = "HAPI FHIR";
|
||||
|
@ -88,6 +93,15 @@ public class RestfulServerConfiguration {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Map<String, Class<? extends IBaseResource>> getNameToSharedSupertype() {
|
||||
return resourceNameToSharedSupertype;
|
||||
}
|
||||
|
||||
public RestfulServerConfiguration setNameToSharedSupertype(Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype) {
|
||||
this.resourceNameToSharedSupertype = resourceNameToSharedSupertype;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the implementationDescription
|
||||
*
|
||||
|
@ -268,6 +282,34 @@ public class RestfulServerConfiguration {
|
|||
return resourceToMethods;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates {@link #resourceNameToSharedSupertype} by scanning the given resource providers. Only resource provider getResourceType values
|
||||
* are taken into account. {@link ProvidesResources} and method return types are deliberately ignored.
|
||||
*
|
||||
* Given a resource name, the common superclass for all getResourceType return values for that name's providers is the common superclass
|
||||
* for all returned/received resources with that name. Since {@link ProvidesResources} resources and method return types must also be
|
||||
* subclasses of this common supertype, they can't affect the result of this method.
|
||||
*/
|
||||
public void computeSharedSupertypeForResourcePerName(Collection<IResourceProvider> providers) {
|
||||
Map<String, CommonResourceSupertypeScanner> resourceNameToScanner = new HashMap<>();
|
||||
|
||||
List<Class<? extends IBaseResource>> providedResourceClasses = providers.stream()
|
||||
.map(provider -> provider.getResourceType())
|
||||
.collect(Collectors.toList());
|
||||
providedResourceClasses.stream()
|
||||
.forEach(resourceClass -> {
|
||||
RuntimeResourceDefinition baseDefinition = getFhirContext().getResourceDefinition(resourceClass).getBaseDefinition();
|
||||
CommonResourceSupertypeScanner scanner = resourceNameToScanner.computeIfAbsent(baseDefinition.getName(), key -> new CommonResourceSupertypeScanner());
|
||||
scanner.register(resourceClass);
|
||||
});
|
||||
|
||||
resourceNameToSharedSupertype = resourceNameToScanner.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().getLowestCommonSuperclass().isPresent())
|
||||
.collect(Collectors.toMap(
|
||||
entry -> entry.getKey(),
|
||||
entry -> entry.getValue().getLowestCommonSuperclass().get()));
|
||||
}
|
||||
|
||||
private String createOperationName(OperationMethodBinding theMethodBinding) {
|
||||
StringBuilder retVal = new StringBuilder();
|
||||
if (theMethodBinding.getResourceName() != null) {
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import java.util.List;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CommonResourceSupertypeScannerTest {
|
||||
|
||||
private final CommonResourceSupertypeScanner scanner = new CommonResourceSupertypeScanner();
|
||||
|
||||
@Test
|
||||
public void testBaseClass() {
|
||||
scanner.register(DemoPatient.class);
|
||||
|
||||
assertThat(scanner.getLowestCommonSuperclass().get(), is(DemoPatient.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubtype() {
|
||||
scanner.register(DemoPatient.class);
|
||||
scanner.register(DemoPatientTripleSub.class);
|
||||
|
||||
assertThat(scanner.getLowestCommonSuperclass().get(), is(DemoPatient.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHierarchyBranch() {
|
||||
scanner.register(DemoPatientSub.class);
|
||||
scanner.register(DemoPatientSubSub.class);
|
||||
scanner.register(DemoPatientSubSubTwo.class);
|
||||
scanner.register(DemoPatientTripleSub.class);
|
||||
|
||||
assertThat(scanner.getLowestCommonSuperclass().get(), is(DemoPatientSub.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupertypeNotRegistered() {
|
||||
scanner.register(DemoPatientTripleSub.class);
|
||||
scanner.register(DemoPatientSubSubTwo.class);
|
||||
|
||||
assertThat(scanner.getLowestCommonSuperclass().get(), is(DemoPatientSub.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlySubtype() {
|
||||
scanner.register(DemoPatientTripleSub.class);
|
||||
|
||||
assertThat(scanner.getLowestCommonSuperclass().get(), is(DemoPatientTripleSub.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
assertThat(scanner.getLowestCommonSuperclass().isPresent(), is(false));
|
||||
}
|
||||
|
||||
@ResourceDef(name = "Patient")
|
||||
private static class DemoPatient implements IBaseResource {
|
||||
|
||||
@Override
|
||||
public IBaseMetaType getMeta() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIdType getIdElement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseResource setId(String theId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseResource setId(IIdType theId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirVersionEnum getStructureFhirVersionEnum() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFormatComment() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFormatCommentsPre() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getFormatCommentsPost() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getUserData(String theName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserData(String theName, Object theValue) {
|
||||
}
|
||||
}
|
||||
|
||||
@ResourceDef(id = "subOne")
|
||||
private static class DemoPatientSub extends DemoPatient {}
|
||||
|
||||
@ResourceDef(id = "subSubOne")
|
||||
private static class DemoPatientSubSub extends DemoPatientSub {}
|
||||
|
||||
@ResourceDef(id = "subSubTwo")
|
||||
private static class DemoPatientSubSubTwo extends DemoPatientSub {}
|
||||
|
||||
@ResourceDef(id = "tripleSub")
|
||||
private static class DemoPatientTripleSub extends DemoPatientSubSub {}
|
||||
}
|
|
@ -34,6 +34,8 @@ import java.util.Map.Entry;
|
|||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Structures - DSTU2 (FHIR v1.0.0)
|
||||
|
@ -113,12 +115,12 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
}
|
||||
|
||||
private Map<String, List<BaseMethodBinding<?>>> collectMethodBindings(RequestDetails theRequestDetails) {
|
||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = new TreeMap<String, List<BaseMethodBinding<?>>>();
|
||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = new TreeMap<>();
|
||||
for (ResourceBinding next : getServerConfiguration(theRequestDetails).getResourceBindings()) {
|
||||
String resourceName = next.getResourceName();
|
||||
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
|
||||
if (resourceToMethods.containsKey(resourceName) == false) {
|
||||
resourceToMethods.put(resourceName, new ArrayList<BaseMethodBinding<?>>());
|
||||
resourceToMethods.put(resourceName, new ArrayList<>());
|
||||
}
|
||||
resourceToMethods.get(resourceName).add(nextMethodBinding);
|
||||
}
|
||||
|
@ -231,13 +233,21 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
Set<String> operationNames = new HashSet<>();
|
||||
|
||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = collectMethodBindings(theRequestDetails);
|
||||
Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype = serverConfiguration.getNameToSharedSupertype();
|
||||
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
|
||||
|
||||
if (nextEntry.getKey().isEmpty() == false) {
|
||||
Set<TypeRestfulInteraction> resourceOps = new HashSet<>();
|
||||
CapabilityStatementRestResourceComponent resource = rest.addResource();
|
||||
String resourceName = nextEntry.getKey();
|
||||
RuntimeResourceDefinition def = serverConfiguration.getFhirContext().getResourceDefinition(resourceName);
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
FhirContext context = serverConfiguration.getFhirContext();
|
||||
if (resourceNameToSharedSupertype.containsKey(resourceName)) {
|
||||
def = context.getResourceDefinition(resourceNameToSharedSupertype.get(resourceName));
|
||||
} else {
|
||||
def = context.getResourceDefinition(resourceName);
|
||||
}
|
||||
resource.getTypeElement().setValue(def.getName());
|
||||
resource.getProfile().setReference((def.getResourceProfile(serverBase)));
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.hl7.fhir.dstu3.hapi.rest.server;
|
|||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
|
@ -91,7 +92,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProviderWithExplicitChains());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -131,7 +132,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ConditionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -154,7 +155,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ProviderWithExtendedOperationReturningBundle());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -181,7 +182,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ProviderWithExtendedOperationReturningBundle());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs) {
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider() {
|
||||
};
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
|
@ -203,7 +204,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new InstanceHistoryProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -222,7 +223,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new MultiOptionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -255,7 +256,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new NonConditionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -280,7 +281,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new MultiTypePatientProvider(), new MultiTypeEncounterProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -348,7 +349,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -367,7 +368,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new PlainProviderWithExtendedOperationOnNoType());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs) {
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider() {
|
||||
@Override
|
||||
public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) {
|
||||
return super.getServerConformance(theRequest, createRequestDetails(rs));
|
||||
|
@ -407,7 +408,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ProviderWithRequiredAndOptional());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -437,7 +438,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new VreadProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -457,7 +458,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ReadProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -477,7 +478,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -517,7 +518,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new PatientResourceProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -550,7 +551,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProviderWithWhitelist());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -592,7 +593,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
}
|
||||
};
|
||||
rsNoType.registerProvider(new SearchProviderWithListNoType());
|
||||
ServerCapabilityStatementProvider scNoType = new ServerCapabilityStatementProvider(rsNoType);
|
||||
ServerCapabilityStatementProvider scNoType = new ServerCapabilityStatementProvider();
|
||||
rsNoType.setServerConformanceProvider(scNoType);
|
||||
rsNoType.init(createServletConfig());
|
||||
|
||||
|
@ -609,7 +610,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
}
|
||||
};
|
||||
rsWithType.registerProvider(new SearchProviderWithListWithType());
|
||||
ServerCapabilityStatementProvider scWithType = new ServerCapabilityStatementProvider(rsWithType);
|
||||
ServerCapabilityStatementProvider scWithType = new ServerCapabilityStatementProvider();
|
||||
rsWithType.setServerConformanceProvider(scWithType);
|
||||
rsWithType.init(createServletConfig());
|
||||
|
||||
|
@ -627,7 +628,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SystemHistoryProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -646,7 +647,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new TypeHistoryProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -665,7 +666,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new MultiOptionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -682,7 +683,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new NamedQueryPlainProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -726,7 +727,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new NamedQueryResourceProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -769,7 +770,7 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new TypeLevelOperationProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -791,6 +792,26 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
assertThat(opDef.getInstance(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProfiledResourceStructureDefinitionLinks() throws Exception {
|
||||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
||||
CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
|
||||
|
||||
List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource();
|
||||
CapabilityStatementRestResourceComponent patientResource = resources.stream()
|
||||
.filter(resource -> "Patient".equals(resource.getType()))
|
||||
.findFirst().get();
|
||||
assertThat(patientResource.getProfile().getReference(), containsString(PATIENT_SUB));
|
||||
}
|
||||
|
||||
private List<String> toOperationIdParts(List<CapabilityStatementRestOperationComponent> theOperation) {
|
||||
ArrayList<String> retVal = Lists.newArrayList();
|
||||
for (CapabilityStatementRestOperationComponent next : theOperation) {
|
||||
|
@ -1159,6 +1180,50 @@ public class ServerCapabilityStatementProviderDstu3Test {
|
|||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
public static class ProfiledPatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return PatientSubSub2.class;
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<PatientSubSub2> find() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultipleProfilesPatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return PatientSubSub.class;
|
||||
}
|
||||
|
||||
@Read(type = PatientTripleSub.class)
|
||||
public PatientTripleSub read(@IdParam IdType theId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB)
|
||||
public static class PatientSub extends Patient {}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB)
|
||||
public static class PatientSubSub extends PatientSub {}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB_2)
|
||||
public static class PatientSubSub2 extends PatientSub {}
|
||||
|
||||
@ResourceDef(id = PATIENT_TRIPLE_SUB)
|
||||
public static class PatientTripleSub extends PatientSubSub {}
|
||||
|
||||
private RequestDetails createRequestDetails(RestfulServer theServer) {
|
||||
ServletRequestDetails retVal = new ServletRequestDetails(null);
|
||||
retVal.setServer(theServer);
|
||||
|
|
|
@ -37,6 +37,8 @@ import java.util.Map.Entry;
|
|||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Structures - DSTU2 (FHIR v1.0.0)
|
||||
|
@ -115,7 +117,6 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private DateTimeType conformanceDate(RequestDetails theRequestDetails) {
|
||||
IPrimitiveType<Date> buildDate = getServerConfiguration(theRequestDetails).getConformanceDate();
|
||||
if (buildDate != null && buildDate.getValue() != null) {
|
||||
|
@ -180,13 +181,21 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
Set<String> operationNames = new HashSet<>();
|
||||
|
||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = configuration.collectMethodBindings();
|
||||
Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype = configuration.getNameToSharedSupertype();
|
||||
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
|
||||
|
||||
if (nextEntry.getKey().isEmpty() == false) {
|
||||
Set<TypeRestfulInteraction> resourceOps = new HashSet<>();
|
||||
CapabilityStatementRestResourceComponent resource = rest.addResource();
|
||||
String resourceName = nextEntry.getKey();
|
||||
RuntimeResourceDefinition def = configuration.getFhirContext().getResourceDefinition(resourceName);
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
FhirContext context = configuration.getFhirContext();
|
||||
if (resourceNameToSharedSupertype.containsKey(resourceName)) {
|
||||
def = context.getResourceDefinition(resourceNameToSharedSupertype.get(resourceName));
|
||||
} else {
|
||||
def = context.getResourceDefinition(resourceName);
|
||||
}
|
||||
resource.getTypeElement().setValue(def.getName());
|
||||
resource.getProfileElement().setValue((def.getResourceProfile(serverBase)));
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ import static org.junit.Assert.*;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
|
||||
public class ServerCapabilityStatementProviderR4Test {
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
|
@ -86,7 +88,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ConditionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -115,7 +117,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ProviderWithExtendedOperationReturningBundle());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -142,7 +144,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ProviderWithExtendedOperationReturningBundle());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs) {
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider() {
|
||||
};
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
|
@ -164,7 +166,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new InstanceHistoryProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -183,7 +185,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new MultiOptionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -216,7 +218,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new NonConditionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -239,7 +241,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new MultiTypePatientProvider(), new MultiTypeEncounterProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -307,7 +309,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -326,7 +328,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new PlainProviderWithExtendedOperationOnNoType());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs) {
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider() {
|
||||
@Override
|
||||
public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) {
|
||||
return super.getServerConformance(theRequest, createRequestDetails(rs));
|
||||
|
@ -366,7 +368,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ProviderWithRequiredAndOptional());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -396,7 +398,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new VreadProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -416,7 +418,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new ReadProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -436,7 +438,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -476,7 +478,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new PatientResourceProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -509,7 +511,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SearchProviderWithWhitelist());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -551,7 +553,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
}
|
||||
};
|
||||
rsNoType.registerProvider(new SearchProviderWithListNoType());
|
||||
ServerCapabilityStatementProvider scNoType = new ServerCapabilityStatementProvider(rsNoType);
|
||||
ServerCapabilityStatementProvider scNoType = new ServerCapabilityStatementProvider();
|
||||
rsNoType.setServerConformanceProvider(scNoType);
|
||||
rsNoType.init(createServletConfig());
|
||||
|
||||
|
@ -568,7 +570,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
}
|
||||
};
|
||||
rsWithType.registerProvider(new SearchProviderWithListWithType());
|
||||
ServerCapabilityStatementProvider scWithType = new ServerCapabilityStatementProvider(rsWithType);
|
||||
ServerCapabilityStatementProvider scWithType = new ServerCapabilityStatementProvider();
|
||||
rsWithType.setServerConformanceProvider(scWithType);
|
||||
rsWithType.init(createServletConfig());
|
||||
|
||||
|
@ -586,7 +588,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new SystemHistoryProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -605,7 +607,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new TypeHistoryProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -624,7 +626,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new MultiOptionalProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -641,7 +643,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new NamedQueryPlainProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -685,7 +687,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new NamedQueryResourceProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -728,7 +730,7 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setProviders(new TypeLevelOperationProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(rs);
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
@ -750,6 +752,26 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
assertThat(opDef.getInstance(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProfiledResourceStructureDefinitionLinks() throws Exception {
|
||||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
||||
CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
|
||||
|
||||
List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource();
|
||||
CapabilityStatementRestResourceComponent patientResource = resources.stream()
|
||||
.filter(resource -> "Patient".equals(resource.getType()))
|
||||
.findFirst().get();
|
||||
assertThat(patientResource.getProfile(), containsString(PATIENT_SUB));
|
||||
}
|
||||
|
||||
private List<String> toOperationIdParts(List<CapabilityStatementRestResourceOperationComponent> theOperation) {
|
||||
ArrayList<String> retVal = Lists.newArrayList();
|
||||
for (CapabilityStatementRestResourceOperationComponent next : theOperation) {
|
||||
|
@ -1108,4 +1130,48 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
|
||||
}
|
||||
|
||||
public static class ProfiledPatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return PatientSubSub2.class;
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<PatientSubSub2> find() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultipleProfilesPatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return PatientSubSub.class;
|
||||
}
|
||||
|
||||
@Read(type = PatientTripleSub.class)
|
||||
public PatientTripleSub read(@IdParam IdType theId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB)
|
||||
public static class PatientSub extends Patient {}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB)
|
||||
public static class PatientSubSub extends PatientSub {}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB_2)
|
||||
public static class PatientSubSub2 extends PatientSub {}
|
||||
|
||||
@ResourceDef(id = PATIENT_TRIPLE_SUB)
|
||||
public static class PatientTripleSub extends PatientSubSub {}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ import java.util.Map.Entry;
|
|||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Structures - DSTU2 (FHIR v1.0.0)
|
||||
|
@ -172,13 +174,20 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
Set<String> operationNames = new HashSet<>();
|
||||
|
||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = configuration.collectMethodBindings();
|
||||
Map<String, Class<? extends IBaseResource>> resourceNameToSharedSupertype = configuration.getNameToSharedSupertype();
|
||||
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
|
||||
|
||||
if (nextEntry.getKey().isEmpty() == false) {
|
||||
Set<TypeRestfulInteraction> resourceOps = new HashSet<>();
|
||||
CapabilityStatementRestResourceComponent resource = rest.addResource();
|
||||
String resourceName = nextEntry.getKey();
|
||||
RuntimeResourceDefinition def = configuration.getFhirContext().getResourceDefinition(resourceName);
|
||||
RuntimeResourceDefinition def;
|
||||
FhirContext context = configuration.getFhirContext();
|
||||
if (resourceNameToSharedSupertype.containsKey(resourceName)) {
|
||||
def = context.getResourceDefinition(resourceNameToSharedSupertype.get(resourceName));
|
||||
} else {
|
||||
def = context.getResourceDefinition(resourceName);
|
||||
}
|
||||
resource.getTypeElement().setValue(def.getName());
|
||||
resource.getProfileElement().setValue((def.getResourceProfile(serverBase)));
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import ca.uhn.fhir.rest.server.method.SearchMethodBinding;
|
|||
import ca.uhn.fhir.rest.server.method.SearchParameter;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -40,6 +39,8 @@ import static org.junit.Assert.*;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
|
||||
public class ServerCapabilityStatementProviderR5Test {
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
|
@ -748,6 +749,26 @@ public class ServerCapabilityStatementProviderR5Test {
|
|||
assertThat(opDef.getInstance(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProfiledResourceStructureDefinitionLinks() throws Exception {
|
||||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
|
||||
|
||||
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
|
||||
rs.setServerConformanceProvider(sc);
|
||||
|
||||
rs.init(createServletConfig());
|
||||
|
||||
CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
|
||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
|
||||
|
||||
List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource();
|
||||
CapabilityStatementRestResourceComponent patientResource = resources.stream()
|
||||
.filter(resource -> "Patient".equals(resource.getType()))
|
||||
.findFirst().get();
|
||||
assertThat(patientResource.getProfile(), containsString(PATIENT_SUB));
|
||||
}
|
||||
|
||||
private List<String> toOperationIdParts(List<CapabilityStatementRestResourceOperationComponent> theOperation) {
|
||||
ArrayList<String> retVal = Lists.newArrayList();
|
||||
for (CapabilityStatementRestResourceOperationComponent next : theOperation) {
|
||||
|
@ -1100,4 +1121,48 @@ public class ServerCapabilityStatementProviderR5Test {
|
|||
|
||||
}
|
||||
|
||||
public static class ProfiledPatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return PatientSubSub2.class;
|
||||
}
|
||||
|
||||
@Search
|
||||
public List<PatientSubSub2> find() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultipleProfilesPatientProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return PatientSubSub.class;
|
||||
}
|
||||
|
||||
@Read(type = PatientTripleSub.class)
|
||||
public PatientTripleSub read(@IdParam IdType theId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB)
|
||||
public static class PatientSub extends Patient {}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB)
|
||||
public static class PatientSubSub extends PatientSub {}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB_2)
|
||||
public static class PatientSubSub2 extends PatientSub {}
|
||||
|
||||
@ResourceDef(id = PATIENT_TRIPLE_SUB)
|
||||
public static class PatientTripleSub extends PatientSubSub {}
|
||||
|
||||
}
|
||||
|
|
8
pom.xml
8
pom.xml
|
@ -878,8 +878,7 @@
|
|||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<!--<version>6.2.2.jre8</version>-->
|
||||
<version>7.0.0.jre8</version>
|
||||
<version>7.4.1.jre8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
|
@ -958,7 +957,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<version>2.6.0</version>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
|
@ -1295,7 +1294,7 @@
|
|||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.6.jre7</version>
|
||||
<version>42.2.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
|
@ -1665,6 +1664,7 @@
|
|||
<runOrder>random</runOrder>
|
||||
<argLine>-Dfile.encoding=UTF-8 -Xmx1024m</argLine>
|
||||
<forkCount>1.0C</forkCount>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
<li>Hibernate Core (JPA): 5.4.2.Final -> 5.4.6.Final</li>
|
||||
<li>Hibernate Search (JPA): 5.11.1.Final -> 5.11.3.Final</li>
|
||||
<li>Jackson Databind (JPA): 2.9.9 -> 2.9.10 (CVE-2019-16335, CVE-2019-14540)</li>
|
||||
<li>Commons-DBCP2 (JPA): 2.6.0 -> 2.7.0</li>
|
||||
<li>Postgresql JDBC Driver (JPA): 42.2.6.jre7 -> 42.2.8</li>
|
||||
<li>MSSQL JDBC Driver (JPA): 7.0.0.jre8 -> 7.4.1.jre8</li>
|
||||
<li>Spring Boot (Boot): 2.1.1 -> 2.2.0</li>
|
||||
</ul>
|
||||
]]>
|
||||
|
@ -489,6 +492,11 @@
|
|||
The hapi-fhir-testpage-overlay has been updated to support R5 endpoints. Thanks to Dazhi Jiao
|
||||
for the pull request!
|
||||
</action>
|
||||
<action type="add" issue="1088">
|
||||
The CapabilityStatement generator will now determine supported profiles by navigating the complete
|
||||
hierarchy of supported resource types, instead of just using the root resource for each type.
|
||||
Thanks to Stig Døssing for the pull request!
|
||||
</action>
|
||||
</release>
|
||||
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue