Merge pull request #125 from jvitrifork/spring-pr
Added spring boot example application that can be used during test ef…
This commit is contained in:
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"files.exclude": {
|
||||||
|
"**/.classpath": true,
|
||||||
|
"**/.project": true,
|
||||||
|
"**/.settings": true,
|
||||||
|
"**/.factorypath": true
|
||||||
|
}
|
||||||
|
}
|
||||||
128
pom.xml
128
pom.xml
@@ -3,6 +3,8 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<!-- one-liner to take you to the cloud with settings form the application.yaml file: -->
|
||||||
|
<!-- 'mvn clean package com.google.cloud.tools:jib-maven-plugin:dockerBuild -Dimage=distroless-hapi && docker run -p 8080:8080 -e spring.batch.job.enabled=false distroless-hapi' -->
|
||||||
<!--
|
<!--
|
||||||
Note: HAPI projects use the "hapi-fhir" POM as their base to provide easy management.
|
Note: HAPI projects use the "hapi-fhir" POM as their base to provide easy management.
|
||||||
You do not need to use this in your own projects, so the "parent" tag and it's
|
You do not need to use this in your own projects, so the "parent" tag and it's
|
||||||
@@ -17,8 +19,13 @@
|
|||||||
|
|
||||||
<artifactId>hapi-fhir-jpaserver-starter</artifactId>
|
<artifactId>hapi-fhir-jpaserver-starter</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>8</java.version>
|
||||||
|
<spring.boot>2.3.3.RELEASE</spring.boot>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<prerequisites>
|
<prerequisites>
|
||||||
<maven>3.5.0</maven>
|
<maven>3.6.0</maven>
|
||||||
</prerequisites>
|
</prerequisites>
|
||||||
|
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
@@ -69,12 +76,6 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>javax.mail-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- This dependency includes the core HAPI-FHIR classes -->
|
<!-- This dependency includes the core HAPI-FHIR classes -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -118,7 +119,7 @@
|
|||||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>classes</classifier>
|
<classifier>classes</classifier>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- HAPI-FHIR uses Logback for logging support. The logback library is included automatically by Maven as a part of the hapi-fhir-base dependency, but you also need to include a logging library. Logback
|
<!-- HAPI-FHIR uses Logback for logging support. The logback library is included automatically by Maven as a part of the hapi-fhir-base dependency, but you also need to include a logging library. Logback
|
||||||
@@ -240,18 +241,7 @@
|
|||||||
<artifactId>jetty-webapp</artifactId>
|
<artifactId>jetty-webapp</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.helger</groupId>
|
|
||||||
<artifactId>ph-schematron</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<artifactId>Saxon-HE</artifactId>
|
|
||||||
<groupId>net.sf.saxon</groupId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
For some reason JavaDoc crashed during site generation unless we have this dependency
|
For some reason JavaDoc crashed during site generation unless we have this dependency
|
||||||
@@ -276,6 +266,34 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||||
|
<version>${spring.boot}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>5.6.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.6.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<version>${spring.boot}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -284,7 +302,22 @@
|
|||||||
<finalName>hapi-fhir-jpaserver</finalName>
|
<finalName>hapi-fhir-jpaserver</finalName>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<!-- The following is not required for the application to build, but allows you to test it by issuing "mvn jetty:run" from the command line. -->
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>ca.uhn.fhir.jpa.starter.Application</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!-- The following is not required for the application to build, but allows you to test it by issuing "mvn package jetty:run -Dspring.batch.job.enabled=false" from the command line. -->
|
||||||
|
<!--
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
@@ -296,14 +329,15 @@
|
|||||||
</webApp>
|
</webApp>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- Tell Maven which Java source version you want to use -->
|
<!-- Tell Maven which Java source version you want to use -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<release>8</release>
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
@@ -323,7 +357,7 @@
|
|||||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
||||||
</overlay>
|
</overlay>
|
||||||
</overlays>
|
</overlays>
|
||||||
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
@@ -438,9 +472,51 @@
|
|||||||
</ignoredResourcePatterns>
|
</ignoredResourcePatterns>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<!-- Package the war for your preference. Use the boot profile if you prefer a single jar/war
|
||||||
|
that can be started with and embedded application server. Default is jetty as it is assumed
|
||||||
|
that the main users of this project already have an app server.
|
||||||
|
Different profiles are needed as packing it for spring boot, makes the resulting war undeployable
|
||||||
|
due to a class shading issue between tomcat and jetty.
|
||||||
|
(the error is 'java.util.ServiceConfigurationError: org.apache.juli.logging.Log: org.eclipse.jetty.apache.jsp.JuliLog not a subtype')
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- example of how to start the server using spring boot-->
|
||||||
|
<!-- mvn clean package spring-boot:repackage -Pboot && java -jar target/hapi-fhir-jpaserver.war -->
|
||||||
|
|
||||||
|
<!-- Use the boot profile for development and debugging options when using your IDE -->
|
||||||
|
<profile>
|
||||||
|
<id>boot</id>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>2.3.3.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</profile>
|
||||||
|
<!-- examples of how to start the server using the default profile-->
|
||||||
|
<!-- mvn clean package jetty:run -Dspring.batch.job.enabled=false -->
|
||||||
|
<!-- java -jar -Dspring.batch.job.enabled=false jetty-runner.jar target/hapi-fhir-jpaserver.war -->
|
||||||
|
<profile>
|
||||||
|
<id>jetty</id>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>2.3.3.RELEASE</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
package ca.uhn.fhir.jpa.empi;
|
package ca.uhn.fhir.jpa.empi;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.empi.api.IEmpiSettings;
|
import ca.uhn.fhir.empi.api.IEmpiSettings;
|
||||||
import ca.uhn.fhir.empi.rules.config.EmpiRuleValidator;
|
import ca.uhn.fhir.empi.rules.config.EmpiRuleValidator;
|
||||||
import ca.uhn.fhir.empi.rules.config.EmpiSettings;
|
import ca.uhn.fhir.empi.rules.config.EmpiSettings;
|
||||||
import ca.uhn.fhir.jpa.starter.HapiProperties;
|
import ca.uhn.fhir.jpa.empi.config.EmpiConsumerConfig;
|
||||||
|
import ca.uhn.fhir.jpa.empi.config.EmpiSubmitterConfig;
|
||||||
|
import ca.uhn.fhir.jpa.starter.AppProperties;
|
||||||
|
import ca.uhn.fhir.rest.server.util.ISearchParamRetriever;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.core.io.DefaultResourceLoader;
|
import org.springframework.core.io.DefaultResourceLoader;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
@@ -18,14 +25,21 @@ import java.io.IOException;
|
|||||||
* in 5.1.0 picks this up even if EMPI is disabled currently.
|
* in 5.1.0 picks this up even if EMPI is disabled currently.
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Conditional(EmpiConfigCondition.class)
|
||||||
|
@Import({EmpiConsumerConfig.class, EmpiSubmitterConfig.class})
|
||||||
public class EmpiConfig {
|
public class EmpiConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
IEmpiSettings empiSettings(EmpiRuleValidator theEmpiRuleValidator) throws IOException {
|
EmpiRuleValidator empiRuleValidator(FhirContext theFhirContext, ISearchParamRetriever theSearchParamRetriever) {
|
||||||
|
return new EmpiRuleValidator(theFhirContext, theSearchParamRetriever);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
IEmpiSettings empiSettings(@Autowired EmpiRuleValidator theEmpiRuleValidator, AppProperties appProperties) throws IOException {
|
||||||
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
|
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||||
Resource resource = resourceLoader.getResource("empi-rules.json");
|
Resource resource = resourceLoader.getResource("empi-rules.json");
|
||||||
String json = IOUtils.toString(resource.getInputStream(), Charsets.UTF_8);
|
String json = IOUtils.toString(resource.getInputStream(), Charsets.UTF_8);
|
||||||
return new EmpiSettings(theEmpiRuleValidator).setEnabled(HapiProperties.getEmpiEnabled()).setScriptText(json);
|
return new EmpiSettings(theEmpiRuleValidator).setEnabled(appProperties.getEmpi_enabled()).setScriptText(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/main/java/ca/uhn/fhir/jpa/empi/EmpiConfigCondition.java
Normal file
13
src/main/java/ca/uhn/fhir/jpa/empi/EmpiConfigCondition.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package ca.uhn.fhir.jpa.empi;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Condition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
public class EmpiConfigCondition implements Condition {
|
||||||
|
@Override
|
||||||
|
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
|
||||||
|
String property = conditionContext.getEnvironment().getProperty("hapi.fhir.empi_enabled");
|
||||||
|
return Boolean.parseBoolean(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
669
src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java
Normal file
669
src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java
Normal file
@@ -0,0 +1,669 @@
|
|||||||
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
|
||||||
|
@ConfigurationProperties(prefix = "hapi.fhir")
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties
|
||||||
|
public class AppProperties {
|
||||||
|
|
||||||
|
private Boolean empi_enabled = false;
|
||||||
|
private Boolean allow_cascading_deletes = false;
|
||||||
|
private Boolean allow_contains_searches = true;
|
||||||
|
private Boolean allow_external_references = false;
|
||||||
|
private Boolean allow_multiple_delete = false;
|
||||||
|
private Boolean allow_override_default_search_params = true;
|
||||||
|
private Boolean allow_placeholder_references = true;
|
||||||
|
private Boolean auto_create_placeholder_reference_targets = true;
|
||||||
|
private Boolean enable_index_missing_fields = false;
|
||||||
|
private Boolean enforce_referential_integrity_on_delete = true;
|
||||||
|
private Boolean enforce_referential_integrity_on_write = true;
|
||||||
|
private Boolean etag_support_enabled = true;
|
||||||
|
private Boolean expunge_enabled = true;
|
||||||
|
private Boolean fhirpath_interceptor_enabled = false;
|
||||||
|
private Boolean filter_search_enabled = true;
|
||||||
|
private Boolean graphql_enabled = false;
|
||||||
|
private Boolean binary_storage_enabled = false;
|
||||||
|
private Boolean bulk_export_enabled = false;
|
||||||
|
private Boolean default_pretty_print = true;
|
||||||
|
private Integer default_page_size = 20;
|
||||||
|
private Integer max_binary_size = null;
|
||||||
|
private Integer max_page_size = Integer.MAX_VALUE;
|
||||||
|
private Integer defer_indexing_for_codesystems_of_size = 100;
|
||||||
|
private Long retain_cached_searches_mins = 60L;
|
||||||
|
private Long reuse_cached_search_results_millis = 60000L;
|
||||||
|
private String server_address = null;
|
||||||
|
private EncodingEnum default_encoding = EncodingEnum.JSON;
|
||||||
|
private FhirVersionEnum fhir_version = FhirVersionEnum.R4;
|
||||||
|
private ClientIdStrategyEnum client_id_strategy = ClientIdStrategyEnum.ALPHANUMERIC;
|
||||||
|
private List<String> supported_resource_types = new ArrayList<>();
|
||||||
|
private List<Bundle.BundleType> allowed_bundle_types = null;
|
||||||
|
|
||||||
|
private Validation validation = new Validation();
|
||||||
|
private List<Tester> tester = ImmutableList.of(new Tester());
|
||||||
|
private Logger logger = new Logger();
|
||||||
|
private Subscription subscription = new Subscription();
|
||||||
|
private Cors cors = null;
|
||||||
|
private Partitioning partitioning = null;
|
||||||
|
private List<ImplementationGuide> implementationGuides = null;
|
||||||
|
|
||||||
|
public Integer getDefer_indexing_for_codesystems_of_size() {
|
||||||
|
return defer_indexing_for_codesystems_of_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefer_indexing_for_codesystems_of_size(Integer defer_indexing_for_codesystems_of_size) {
|
||||||
|
this.defer_indexing_for_codesystems_of_size = defer_indexing_for_codesystems_of_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ImplementationGuide> getImplementationGuides() {
|
||||||
|
return implementationGuides;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImplementationGuides(List<ImplementationGuide> implementationGuides) {
|
||||||
|
this.implementationGuides = implementationGuides;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Partitioning getPartitioning() {
|
||||||
|
return partitioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPartitioning(Partitioning partitioning) {
|
||||||
|
this.partitioning = partitioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEmpi_enabled() {
|
||||||
|
return empi_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmpi_enabled(Boolean empi_enabled) {
|
||||||
|
this.empi_enabled = empi_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Cors getCors() {
|
||||||
|
return cors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCors(Cors cors) {
|
||||||
|
this.cors = cors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Bundle.BundleType> getAllowed_bundle_types() {
|
||||||
|
return allowed_bundle_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowed_bundle_types(List<Bundle.BundleType> allowed_bundle_types) {
|
||||||
|
this.allowed_bundle_types = allowed_bundle_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServer_address() {
|
||||||
|
return server_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServer_address(String server_address) {
|
||||||
|
this.server_address = server_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subscription getSubscription() {
|
||||||
|
return subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getDefault_pretty_print() {
|
||||||
|
return default_pretty_print;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefault_pretty_print(Boolean default_pretty_print) {
|
||||||
|
this.default_pretty_print = default_pretty_print;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubscription(Subscription subscription) {
|
||||||
|
this.subscription = subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Validation getValidation() {
|
||||||
|
return validation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidation(Validation validation) {
|
||||||
|
this.validation = validation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSupported_resource_types() {
|
||||||
|
return supported_resource_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupported_resource_types(List<String> supported_resource_types) {
|
||||||
|
this.supported_resource_types = supported_resource_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Logger getLogger() {
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogger(Logger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientIdStrategyEnum getClient_id_strategy() {
|
||||||
|
return client_id_strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient_id_strategy(
|
||||||
|
ClientIdStrategyEnum client_id_strategy) {
|
||||||
|
this.client_id_strategy = client_id_strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_cascading_deletes() {
|
||||||
|
return allow_cascading_deletes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_cascading_deletes(Boolean allow_cascading_deletes) {
|
||||||
|
this.allow_cascading_deletes = allow_cascading_deletes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_contains_searches() {
|
||||||
|
return allow_contains_searches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_contains_searches(Boolean allow_contains_searches) {
|
||||||
|
this.allow_contains_searches = allow_contains_searches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_external_references() {
|
||||||
|
return allow_external_references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_external_references(Boolean allow_external_references) {
|
||||||
|
this.allow_external_references = allow_external_references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_multiple_delete() {
|
||||||
|
return allow_multiple_delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_multiple_delete(Boolean allow_multiple_delete) {
|
||||||
|
this.allow_multiple_delete = allow_multiple_delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_override_default_search_params() {
|
||||||
|
return allow_override_default_search_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_override_default_search_params(
|
||||||
|
Boolean allow_override_default_search_params) {
|
||||||
|
this.allow_override_default_search_params = allow_override_default_search_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_placeholder_references() {
|
||||||
|
return allow_placeholder_references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_placeholder_references(Boolean allow_placeholder_references) {
|
||||||
|
this.allow_placeholder_references = allow_placeholder_references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAuto_create_placeholder_reference_targets() {
|
||||||
|
return auto_create_placeholder_reference_targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuto_create_placeholder_reference_targets(
|
||||||
|
Boolean auto_create_placeholder_reference_targets) {
|
||||||
|
this.auto_create_placeholder_reference_targets = auto_create_placeholder_reference_targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDefault_page_size() {
|
||||||
|
return default_page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefault_page_size(Integer default_page_size) {
|
||||||
|
this.default_page_size = default_page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEnable_index_missing_fields() {
|
||||||
|
return enable_index_missing_fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnable_index_missing_fields(Boolean enable_index_missing_fields) {
|
||||||
|
this.enable_index_missing_fields = enable_index_missing_fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEnforce_referential_integrity_on_delete() {
|
||||||
|
return enforce_referential_integrity_on_delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnforce_referential_integrity_on_delete(
|
||||||
|
Boolean enforce_referential_integrity_on_delete) {
|
||||||
|
this.enforce_referential_integrity_on_delete = enforce_referential_integrity_on_delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEnforce_referential_integrity_on_write() {
|
||||||
|
return enforce_referential_integrity_on_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnforce_referential_integrity_on_write(
|
||||||
|
Boolean enforce_referential_integrity_on_write) {
|
||||||
|
this.enforce_referential_integrity_on_write = enforce_referential_integrity_on_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEtag_support_enabled() {
|
||||||
|
return etag_support_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEtag_support_enabled(Boolean etag_support_enabled) {
|
||||||
|
this.etag_support_enabled = etag_support_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getExpunge_enabled() {
|
||||||
|
return expunge_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpunge_enabled(Boolean expunge_enabled) {
|
||||||
|
this.expunge_enabled = expunge_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFhirpath_interceptor_enabled() {
|
||||||
|
return fhirpath_interceptor_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFhirpath_interceptor_enabled(Boolean fhirpath_interceptor_enabled) {
|
||||||
|
this.fhirpath_interceptor_enabled = fhirpath_interceptor_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFilter_search_enabled() {
|
||||||
|
return filter_search_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilter_search_enabled(Boolean filter_search_enabled) {
|
||||||
|
this.filter_search_enabled = filter_search_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getGraphql_enabled() {
|
||||||
|
return graphql_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraphql_enabled(Boolean graphql_enabled) {
|
||||||
|
this.graphql_enabled = graphql_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getBinary_storage_enabled() {
|
||||||
|
return binary_storage_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBinary_storage_enabled(Boolean binary_storage_enabled) {
|
||||||
|
this.binary_storage_enabled = binary_storage_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getBulk_export_enabled() {
|
||||||
|
return bulk_export_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBulk_export_enabled(Boolean bulk_export_enabled) {
|
||||||
|
this.bulk_export_enabled = bulk_export_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EncodingEnum getDefault_encoding() {
|
||||||
|
return default_encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefault_encoding(EncodingEnum default_encoding) {
|
||||||
|
this.default_encoding = default_encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FhirVersionEnum getFhir_version() {
|
||||||
|
return fhir_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFhir_version(FhirVersionEnum fhir_version) {
|
||||||
|
this.fhir_version = fhir_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMax_binary_size() {
|
||||||
|
return max_binary_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax_binary_size(Integer max_binary_size) {
|
||||||
|
this.max_binary_size = max_binary_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMax_page_size() {
|
||||||
|
return max_page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax_page_size(Integer max_page_size) {
|
||||||
|
this.max_page_size = max_page_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getRetain_cached_searches_mins() {
|
||||||
|
return retain_cached_searches_mins;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRetain_cached_searches_mins(Long retain_cached_searches_mins) {
|
||||||
|
this.retain_cached_searches_mins = retain_cached_searches_mins;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getReuse_cached_search_results_millis() {
|
||||||
|
return reuse_cached_search_results_millis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReuse_cached_search_results_millis(Long reuse_cached_search_results_millis) {
|
||||||
|
this.reuse_cached_search_results_millis = reuse_cached_search_results_millis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tester> getTester() {
|
||||||
|
return tester;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTester(List<Tester> tester) {
|
||||||
|
this.tester = tester;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Cors {
|
||||||
|
private Boolean allow_Credentials = true;
|
||||||
|
private List<String> allowed_origin = ImmutableList.of("*");
|
||||||
|
|
||||||
|
public List<String> getAllowed_origin() {
|
||||||
|
return allowed_origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowed_origin(List<String> allowed_origin) {
|
||||||
|
this.allowed_origin = allowed_origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow_Credentials() {
|
||||||
|
return allow_Credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow_Credentials(Boolean allow_Credentials) {
|
||||||
|
this.allow_Credentials = allow_Credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Logger {
|
||||||
|
|
||||||
|
private String name = "fhirtest.access";
|
||||||
|
private String error_format = "ERROR - ${requestVerb} ${requestUrl}";
|
||||||
|
private String format = "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]";
|
||||||
|
private Boolean log_exceptions = true;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getError_format() {
|
||||||
|
return error_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError_format(String error_format) {
|
||||||
|
this.error_format = error_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormat() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFormat(String format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getLog_exceptions() {
|
||||||
|
return log_exceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLog_exceptions(Boolean log_exceptions) {
|
||||||
|
this.log_exceptions = log_exceptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class Tester {
|
||||||
|
|
||||||
|
private String id = "home";
|
||||||
|
private String name = "Local Tester";
|
||||||
|
private String server_address = "http://localhost:8080/fhir";
|
||||||
|
private Boolean refuse_to_fetch_third_party_urls = true;
|
||||||
|
private FhirVersionEnum fhir_version = FhirVersionEnum.R4;
|
||||||
|
|
||||||
|
public FhirVersionEnum getFhir_version() {
|
||||||
|
return fhir_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFhir_version(FhirVersionEnum fhir_version) {
|
||||||
|
this.fhir_version = fhir_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServer_address() {
|
||||||
|
return server_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServer_address(String server_address) {
|
||||||
|
this.server_address = server_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getRefuse_to_fetch_third_party_urls() {
|
||||||
|
return refuse_to_fetch_third_party_urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRefuse_to_fetch_third_party_urls(Boolean refuse_to_fetch_third_party_urls) {
|
||||||
|
this.refuse_to_fetch_third_party_urls = refuse_to_fetch_third_party_urls;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ImplementationGuide
|
||||||
|
{
|
||||||
|
private String url;
|
||||||
|
private String name;
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Validation {
|
||||||
|
|
||||||
|
private Boolean requests_enabled = false;
|
||||||
|
private Boolean responses_enabled = false;
|
||||||
|
|
||||||
|
public Boolean getRequests_enabled() {
|
||||||
|
return requests_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequests_enabled(Boolean requests_enabled) {
|
||||||
|
this.requests_enabled = requests_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getResponses_enabled() {
|
||||||
|
return responses_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponses_enabled(Boolean responses_enabled) {
|
||||||
|
this.responses_enabled = responses_enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Partitioning {
|
||||||
|
|
||||||
|
private Boolean partitioning_include_in_search_hashes = false;
|
||||||
|
|
||||||
|
|
||||||
|
public Boolean getPartitioning_include_in_search_hashes() {
|
||||||
|
return partitioning_include_in_search_hashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPartitioning_include_in_search_hashes(Boolean partitioning_include_in_search_hashes) {
|
||||||
|
this.partitioning_include_in_search_hashes = partitioning_include_in_search_hashes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Subscription {
|
||||||
|
|
||||||
|
public Boolean getResthook_enabled() {
|
||||||
|
return resthook_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResthook_enabled(Boolean resthook_enabled) {
|
||||||
|
this.resthook_enabled = resthook_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getWebsocket_enabled() {
|
||||||
|
return websocket_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWebsocket_enabled(Boolean websocket_enabled) {
|
||||||
|
this.websocket_enabled = websocket_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean resthook_enabled = false;
|
||||||
|
private Boolean websocket_enabled = false;
|
||||||
|
private Email email = null;
|
||||||
|
|
||||||
|
public Email getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(Email email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class Email {
|
||||||
|
public String getFrom() {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFrom(String from) {
|
||||||
|
this.from = from;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(Integer port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAuth() {
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuth(Boolean auth) {
|
||||||
|
this.auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getStartTlsEnable() {
|
||||||
|
return startTlsEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTlsEnable(Boolean startTlsEnable) {
|
||||||
|
this.startTlsEnable = startTlsEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getStartTlsRequired() {
|
||||||
|
return startTlsRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTlsRequired(Boolean startTlsRequired) {
|
||||||
|
this.startTlsRequired = startTlsRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getQuitWait() {
|
||||||
|
return quitWait;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuitWait(Boolean quitWait) {
|
||||||
|
this.quitWait = quitWait;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String from;
|
||||||
|
private String host;
|
||||||
|
private Integer port = 25;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private Boolean auth = false;
|
||||||
|
private Boolean startTlsEnable = false;
|
||||||
|
private Boolean startTlsRequired = false;
|
||||||
|
private Boolean quitWait = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/main/java/ca/uhn/fhir/jpa/starter/Application.java
Normal file
76
src/main/java/ca/uhn/fhir/jpa/starter/Application.java
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.empi.EmpiConfig;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||||
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
|
||||||
|
@ServletComponentScan(basePackageClasses = {
|
||||||
|
JpaRestfulServer.class}, basePackages = "ca.uhn.fhir.jpa.starter")
|
||||||
|
@SpringBootApplication(exclude = {ElasticsearchRestClientAutoConfiguration.class}, scanBasePackages = {"ca.uhn.fhir.jpa.starter"})
|
||||||
|
@Import({SubscriptionSubmitterConfig.class, SubscriptionProcessorConfig.class, SubscriptionChannelConfig.class, WebsocketDispatcherConfig.class, EmpiConfig.class})
|
||||||
|
public class Application extends SpringBootServletInitializer {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.setProperty("spring.batch.job.enabled", "false");
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
|
||||||
|
//Server is now accessible at eg. http://localhost:8080/hapi-fhir-jpaserver/fhir/metadata
|
||||||
|
//UI is now accessible at http://localhost:8080/hapi-fhir-jpaserver/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpringApplicationBuilder configure(
|
||||||
|
SpringApplicationBuilder builder) {
|
||||||
|
return builder.sources(Application.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AutowireCapableBeanFactory beanFactory;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServletRegistrationBean hapiServletRegistration() {
|
||||||
|
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
|
||||||
|
JpaRestfulServer jpaRestfulServer = new JpaRestfulServer();
|
||||||
|
beanFactory.autowireBean(jpaRestfulServer);
|
||||||
|
servletRegistrationBean.setServlet(jpaRestfulServer);
|
||||||
|
servletRegistrationBean.addUrlMappings("/hapi-fhir-jpaserver/fhir/*");
|
||||||
|
servletRegistrationBean.setLoadOnStartup(1);
|
||||||
|
|
||||||
|
return servletRegistrationBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServletRegistrationBean overlayRegistrationBean() {
|
||||||
|
|
||||||
|
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
|
||||||
|
annotationConfigWebApplicationContext.register(FhirTesterConfig.class);
|
||||||
|
|
||||||
|
DispatcherServlet dispatcherServlet = new DispatcherServlet(
|
||||||
|
annotationConfigWebApplicationContext);
|
||||||
|
dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
|
||||||
|
dispatcherServlet.setContextConfigLocation(FhirTesterConfig.class.getName());
|
||||||
|
|
||||||
|
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
|
||||||
|
registrationBean.setServlet(dispatcherServlet);
|
||||||
|
registrationBean.addUrlMappings("/hapi-fhir-jpaserver/*", "/*");
|
||||||
|
registrationBean.setLoadOnStartup(1);
|
||||||
|
return registrationBean;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package ca.uhn.fhir.jpa.starter;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
|
||||||
import ca.uhn.fhir.jpa.empi.EmpiConfig;
|
|
||||||
import ca.uhn.fhir.jpa.empi.config.EmpiConsumerConfig;
|
|
||||||
import ca.uhn.fhir.jpa.empi.config.EmpiSubmitterConfig;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig;
|
|
||||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
|
||||||
|
|
||||||
public class ApplicationContext extends AnnotationConfigWebApplicationContext {
|
|
||||||
|
|
||||||
public ApplicationContext() {
|
|
||||||
FhirVersionEnum fhirVersion = HapiProperties.getFhirVersion();
|
|
||||||
if (fhirVersion == FhirVersionEnum.DSTU2) {
|
|
||||||
register(FhirServerConfigDstu2.class, FhirServerConfigCommon.class);
|
|
||||||
} else if (fhirVersion == FhirVersionEnum.DSTU3) {
|
|
||||||
register(FhirServerConfigDstu3.class, FhirServerConfigCommon.class);
|
|
||||||
} else if (fhirVersion == FhirVersionEnum.R4) {
|
|
||||||
register(FhirServerConfigR4.class, FhirServerConfigCommon.class);
|
|
||||||
} else if (fhirVersion == FhirVersionEnum.R5) {
|
|
||||||
register(FhirServerConfigR5.class, FhirServerConfigCommon.class);
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HapiProperties.getSubscriptionWebsocketEnabled()) {
|
|
||||||
register(WebsocketDispatcherConfig.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HapiProperties.getSubscriptionEmailEnabled()
|
|
||||||
|| HapiProperties.getSubscriptionRestHookEnabled()
|
|
||||||
|| HapiProperties.getSubscriptionWebsocketEnabled()) {
|
|
||||||
register(SubscriptionSubmitterConfig.class);
|
|
||||||
register(SubscriptionProcessorConfig.class);
|
|
||||||
register(SubscriptionChannelConfig.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HapiProperties.getEmpiEnabled()) {
|
|
||||||
register(EmpiSubmitterConfig.class);
|
|
||||||
register(EmpiConsumerConfig.class);
|
|
||||||
register(EmpiConfig.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -10,52 +10,95 @@ import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
|
|||||||
import ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor;
|
import ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor;
|
||||||
import ca.uhn.fhir.jpa.bulk.provider.BulkDataExportProvider;
|
import ca.uhn.fhir.jpa.bulk.provider.BulkDataExportProvider;
|
||||||
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
|
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
|
||||||
|
import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
|
||||||
|
import ca.uhn.fhir.jpa.packages.PackageInstallationSpec;
|
||||||
import ca.uhn.fhir.jpa.partition.PartitionManagementProvider;
|
import ca.uhn.fhir.jpa.partition.PartitionManagementProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
|
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
|
||||||
|
import ca.uhn.fhir.jpa.provider.IJpaSystemProvider;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
|
||||||
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
|
||||||
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
|
|
||||||
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
|
||||||
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
|
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
|
||||||
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
|
|
||||||
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
|
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
|
||||||
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
|
|
||||||
import ca.uhn.fhir.jpa.provider.r5.JpaConformanceProviderR5;
|
import ca.uhn.fhir.jpa.provider.r5.JpaConformanceProviderR5;
|
||||||
import ca.uhn.fhir.jpa.provider.r5.JpaSystemProviderR5;
|
|
||||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
||||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||||
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
|
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
|
||||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||||
|
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||||
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.CorsInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.*;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.FhirPathFilterInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
||||||
import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy;
|
import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy;
|
||||||
import ca.uhn.fhir.validation.IValidatorModule;
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||||
import org.hl7.fhir.dstu3.model.Bundle;
|
import com.google.common.base.Strings;
|
||||||
import org.hl7.fhir.dstu3.model.Meta;
|
|
||||||
import org.hl7.fhir.r4.model.Bundle.BundleType;
|
import org.hl7.fhir.r4.model.Bundle.BundleType;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Optional;
|
||||||
import java.util.TreeSet;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class BaseJpaRestfulServer extends RestfulServer {
|
public class BaseJpaRestfulServer extends RestfulServer {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DaoRegistry daoRegistry;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DaoConfig daoConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ISearchParamRegistry searchParamRegistry;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IFhirSystemDao fhirSystemDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ResourceProviderFactory resourceProviders;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IJpaSystemProvider jpaSystemProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IInterceptorBroadcaster interceptorBroadcaster;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DatabaseBackedPagingProvider databaseBackedPagingProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IInterceptorService interceptorService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IValidatorModule validatorModule;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Optional<GraphQLProvider> graphQLProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
BulkDataExportProvider bulkDataExportProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
PartitionManagementProvider partitionManagementProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
BinaryStorageInterceptor binaryStorageInterceptor;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IPackageInstallerSvc packageInstallerSvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AppProperties appProperties;
|
||||||
|
|
||||||
|
public BaseJpaRestfulServer() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -67,47 +110,19 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
* Create a FhirContext object that uses the version of FHIR
|
* Create a FhirContext object that uses the version of FHIR
|
||||||
* specified in the properties file.
|
* specified in the properties file.
|
||||||
*/
|
*/
|
||||||
ApplicationContext appCtx = (ApplicationContext) getServletContext()
|
|
||||||
.getAttribute("org.springframework.web.context.WebApplicationContext.ROOT");
|
|
||||||
// Customize supported resource types
|
// Customize supported resource types
|
||||||
Set<String> supportedResourceTypes = HapiProperties.getSupportedResourceTypes();
|
List<String> supportedResourceTypes = appProperties.getSupported_resource_types();
|
||||||
|
|
||||||
if (!supportedResourceTypes.isEmpty() && !supportedResourceTypes.contains("SearchParameter")) {
|
if (!supportedResourceTypes.isEmpty() && !supportedResourceTypes.contains("SearchParameter")) {
|
||||||
supportedResourceTypes.add("SearchParameter");
|
supportedResourceTypes.add("SearchParameter");
|
||||||
}
|
|
||||||
|
|
||||||
if (!supportedResourceTypes.isEmpty()) {
|
|
||||||
DaoRegistry daoRegistry = appCtx.getBean(DaoRegistry.class);
|
|
||||||
daoRegistry.setSupportedResourceTypes(supportedResourceTypes);
|
daoRegistry.setSupportedResourceTypes(supportedResourceTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
setFhirContext(fhirSystemDao.getContext());
|
||||||
* ResourceProviders are fetched from the Spring context
|
|
||||||
*/
|
|
||||||
FhirVersionEnum fhirVersion = HapiProperties.getFhirVersion();
|
|
||||||
ResourceProviderFactory resourceProviders;
|
|
||||||
Object systemProvider;
|
|
||||||
if (fhirVersion == FhirVersionEnum.DSTU2) {
|
|
||||||
resourceProviders = appCtx.getBean("myResourceProvidersDstu2", ResourceProviderFactory.class);
|
|
||||||
systemProvider = appCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class);
|
|
||||||
} else if (fhirVersion == FhirVersionEnum.DSTU3) {
|
|
||||||
resourceProviders = appCtx.getBean("myResourceProvidersDstu3", ResourceProviderFactory.class);
|
|
||||||
systemProvider = appCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class);
|
|
||||||
} else if (fhirVersion == FhirVersionEnum.R4) {
|
|
||||||
resourceProviders = appCtx.getBean("myResourceProvidersR4", ResourceProviderFactory.class);
|
|
||||||
systemProvider = appCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class);
|
|
||||||
} else if (fhirVersion == FhirVersionEnum.R5) {
|
|
||||||
resourceProviders = appCtx.getBean("myResourceProvidersR5", ResourceProviderFactory.class);
|
|
||||||
systemProvider = appCtx.getBean("mySystemProviderR5", JpaSystemProviderR5.class);
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
setFhirContext(appCtx.getBean(FhirContext.class));
|
|
||||||
|
|
||||||
registerProviders(resourceProviders.createProviders());
|
registerProviders(resourceProviders.createProviders());
|
||||||
registerProvider(systemProvider);
|
registerProvider(jpaSystemProvider);
|
||||||
|
|
||||||
|
FhirVersionEnum fhirVersion = fhirSystemDao.getContext().getVersion().getVersion();
|
||||||
/*
|
/*
|
||||||
* The conformance provider exports the supported resources, search parameters, etc for
|
* The conformance provider exports the supported resources, search parameters, etc for
|
||||||
* this server. The JPA version adds resourceProviders counts to the exported statement, so it
|
* this server. The JPA version adds resourceProviders counts to the exported statement, so it
|
||||||
@@ -116,27 +131,31 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
* You can also create your own subclass of the conformance provider if you need to
|
* You can also create your own subclass of the conformance provider if you need to
|
||||||
* provide further customization of your server's CapabilityStatement
|
* provide further customization of your server's CapabilityStatement
|
||||||
*/
|
*/
|
||||||
DaoConfig daoConfig = appCtx.getBean(DaoConfig.class);
|
|
||||||
ISearchParamRegistry searchParamRegistry = appCtx.getBean(ISearchParamRegistry.class);
|
|
||||||
if (fhirVersion == FhirVersionEnum.DSTU2) {
|
if (fhirVersion == FhirVersionEnum.DSTU2) {
|
||||||
IFhirSystemDao<ca.uhn.fhir.model.dstu2.resource.Bundle, MetaDt> systemDao = appCtx.getBean("mySystemDaoDstu2", IFhirSystemDao.class);
|
|
||||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao, daoConfig);
|
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, fhirSystemDao,
|
||||||
|
daoConfig);
|
||||||
confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server");
|
confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server");
|
||||||
setServerConformanceProvider(confProvider);
|
setServerConformanceProvider(confProvider);
|
||||||
} else {
|
} else {
|
||||||
if (fhirVersion == FhirVersionEnum.DSTU3) {
|
if (fhirVersion == FhirVersionEnum.DSTU3) {
|
||||||
IFhirSystemDao<Bundle, Meta> systemDao = appCtx.getBean("mySystemDaoDstu3", IFhirSystemDao.class);
|
|
||||||
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, systemDao, daoConfig, searchParamRegistry);
|
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, fhirSystemDao,
|
||||||
|
daoConfig, searchParamRegistry);
|
||||||
confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server");
|
confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server");
|
||||||
setServerConformanceProvider(confProvider);
|
setServerConformanceProvider(confProvider);
|
||||||
} else if (fhirVersion == FhirVersionEnum.R4) {
|
} else if (fhirVersion == FhirVersionEnum.R4) {
|
||||||
IFhirSystemDao<org.hl7.fhir.r4.model.Bundle, org.hl7.fhir.r4.model.Meta> systemDao = appCtx.getBean("mySystemDaoR4", IFhirSystemDao.class);
|
|
||||||
JpaConformanceProviderR4 confProvider = new JpaConformanceProviderR4(this, systemDao, daoConfig, searchParamRegistry);
|
JpaConformanceProviderR4 confProvider = new JpaConformanceProviderR4(this, fhirSystemDao,
|
||||||
|
daoConfig, searchParamRegistry);
|
||||||
confProvider.setImplementationDescription("HAPI FHIR R4 Server");
|
confProvider.setImplementationDescription("HAPI FHIR R4 Server");
|
||||||
setServerConformanceProvider(confProvider);
|
setServerConformanceProvider(confProvider);
|
||||||
} else if (fhirVersion == FhirVersionEnum.R5) {
|
} else if (fhirVersion == FhirVersionEnum.R5) {
|
||||||
IFhirSystemDao<org.hl7.fhir.r5.model.Bundle, org.hl7.fhir.r5.model.Meta> systemDao = appCtx.getBean("mySystemDaoR5", IFhirSystemDao.class);
|
|
||||||
JpaConformanceProviderR5 confProvider = new JpaConformanceProviderR5(this, systemDao, daoConfig, searchParamRegistry);
|
JpaConformanceProviderR5 confProvider = new JpaConformanceProviderR5(this, fhirSystemDao,
|
||||||
|
daoConfig, searchParamRegistry);
|
||||||
confProvider.setImplementationDescription("HAPI FHIR R5 Server");
|
confProvider.setImplementationDescription("HAPI FHIR R5 Server");
|
||||||
setServerConformanceProvider(confProvider);
|
setServerConformanceProvider(confProvider);
|
||||||
} else {
|
} else {
|
||||||
@@ -147,7 +166,10 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
/*
|
/*
|
||||||
* ETag Support
|
* ETag Support
|
||||||
*/
|
*/
|
||||||
setETagSupport(HapiProperties.getEtagSupport());
|
|
||||||
|
if (appProperties.getEtag_support_enabled() == false)
|
||||||
|
setETagSupport(ETagSupportEnum.DISABLED);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This server tries to dynamically generate narratives
|
* This server tries to dynamically generate narratives
|
||||||
@@ -158,12 +180,12 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
/*
|
/*
|
||||||
* Default to JSON and pretty printing
|
* Default to JSON and pretty printing
|
||||||
*/
|
*/
|
||||||
setDefaultPrettyPrint(HapiProperties.getDefaultPrettyPrint());
|
setDefaultPrettyPrint(appProperties.getDefault_pretty_print());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default encoding
|
* Default encoding
|
||||||
*/
|
*/
|
||||||
setDefaultResponseEncoding(HapiProperties.getDefaultEncoding());
|
setDefaultResponseEncoding(appProperties.getDefault_encoding());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This configures the server to page search results to and from
|
* This configures the server to page search results to and from
|
||||||
@@ -171,7 +193,8 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
* a performance hit when performing searches that return lots of results,
|
* a performance hit when performing searches that return lots of results,
|
||||||
* but makes the server much more scalable.
|
* but makes the server much more scalable.
|
||||||
*/
|
*/
|
||||||
setPagingProvider(appCtx.getBean(DatabaseBackedPagingProvider.class));
|
|
||||||
|
setPagingProvider(databaseBackedPagingProvider);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This interceptor formats the output using nice colourful
|
* This interceptor formats the output using nice colourful
|
||||||
@@ -181,7 +204,7 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
ResponseHighlighterInterceptor responseHighlighterInterceptor = new ResponseHighlighterInterceptor();
|
ResponseHighlighterInterceptor responseHighlighterInterceptor = new ResponseHighlighterInterceptor();
|
||||||
this.registerInterceptor(responseHighlighterInterceptor);
|
this.registerInterceptor(responseHighlighterInterceptor);
|
||||||
|
|
||||||
if (HapiProperties.isFhirPathFilterInterceptorEnabled()) {
|
if (appProperties.getFhirpath_interceptor_enabled()) {
|
||||||
registerInterceptor(new FhirPathFilterInterceptor());
|
registerInterceptor(new FhirPathFilterInterceptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,10 +212,10 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
* Add some logging for each request
|
* Add some logging for each request
|
||||||
*/
|
*/
|
||||||
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
||||||
loggingInterceptor.setLoggerName(HapiProperties.getLoggerName());
|
loggingInterceptor.setLoggerName(appProperties.getLogger().getName());
|
||||||
loggingInterceptor.setMessageFormat(HapiProperties.getLoggerFormat());
|
loggingInterceptor.setMessageFormat(appProperties.getLogger().getFormat());
|
||||||
loggingInterceptor.setErrorMessageFormat(HapiProperties.getLoggerErrorFormat());
|
loggingInterceptor.setErrorMessageFormat(appProperties.getLogger().getError_format());
|
||||||
loggingInterceptor.setLogExceptions(HapiProperties.getLoggerLogExceptions());
|
loggingInterceptor.setLogExceptions(appProperties.getLogger().getLog_exceptions());
|
||||||
this.registerInterceptor(loggingInterceptor);
|
this.registerInterceptor(loggingInterceptor);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -201,8 +224,8 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
* this doesn't always work. If you are setting links in your search bundles that
|
* this doesn't always work. If you are setting links in your search bundles that
|
||||||
* just refer to "localhost", you might want to use a server address strategy:
|
* just refer to "localhost", you might want to use a server address strategy:
|
||||||
*/
|
*/
|
||||||
String serverAddress = HapiProperties.getServerAddress();
|
String serverAddress = appProperties.getServer_address();
|
||||||
if (serverAddress != null && serverAddress.length() > 0) {
|
if (!Strings.isNullOrEmpty(serverAddress)) {
|
||||||
setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress));
|
setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,21 +237,21 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
* with this feature.
|
* with this feature.
|
||||||
*/
|
*/
|
||||||
if (false) { // <-- DISABLED RIGHT NOW
|
if (false) { // <-- DISABLED RIGHT NOW
|
||||||
registerProvider(appCtx.getBean(TerminologyUploaderProvider.class));
|
//registerProvider(appCtx.getBean(TerminologyUploaderProvider.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you want to enable the $trigger-subscription operation to allow
|
// If you want to enable the $trigger-subscription operation to allow
|
||||||
// manual triggering of a subscription delivery, enable this provider
|
// manual triggering of a subscription delivery, enable this provider
|
||||||
if (false) { // <-- DISABLED RIGHT NOW
|
if (false) { // <-- DISABLED RIGHT NOW
|
||||||
SubscriptionTriggeringProvider retriggeringProvider = appCtx
|
/* SubscriptionTriggeringProvider retriggeringProvider = appCtx
|
||||||
.getBean(SubscriptionTriggeringProvider.class);
|
.getBean(SubscriptionTriggeringProvider.class);
|
||||||
registerProvider(retriggeringProvider);
|
registerProvider(retriggeringProvider);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define your CORS configuration. This is an example
|
// Define your CORS configuration. This is an example
|
||||||
// showing a typical setup. You should customize this
|
// showing a typical setup. You should customize this
|
||||||
// to your specific needs
|
// to your specific needs
|
||||||
if (HapiProperties.getCorsEnabled()) {
|
if (appProperties.getCors() != null) {
|
||||||
CorsConfiguration config = new CorsConfiguration();
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
config.addAllowedHeader(HttpHeaders.ORIGIN);
|
config.addAllowedHeader(HttpHeaders.ORIGIN);
|
||||||
config.addAllowedHeader(HttpHeaders.ACCEPT);
|
config.addAllowedHeader(HttpHeaders.ACCEPT);
|
||||||
@@ -238,17 +261,15 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
config.addAllowedHeader("x-fhir-starter");
|
config.addAllowedHeader("x-fhir-starter");
|
||||||
config.addAllowedHeader("X-Requested-With");
|
config.addAllowedHeader("X-Requested-With");
|
||||||
config.addAllowedHeader("Prefer");
|
config.addAllowedHeader("Prefer");
|
||||||
String allAllowedCORSOrigins = HapiProperties.getCorsAllowedOrigin();
|
List<String> allAllowedCORSOrigins = appProperties.getCors().getAllowed_origin();
|
||||||
Arrays.stream(allAllowedCORSOrigins.split(",")).forEach(o -> {
|
allAllowedCORSOrigins.forEach(config::addAllowedOrigin);
|
||||||
config.addAllowedOrigin(o);
|
|
||||||
});
|
|
||||||
config.addAllowedOrigin(HapiProperties.getCorsAllowedOrigin());
|
|
||||||
|
|
||||||
config.addExposedHeader("Location");
|
config.addExposedHeader("Location");
|
||||||
config.addExposedHeader("Content-Location");
|
config.addExposedHeader("Content-Location");
|
||||||
config.setAllowedMethods(
|
config.setAllowedMethods(
|
||||||
Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD"));
|
Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD"));
|
||||||
config.setAllowCredentials(HapiProperties.getCorsAllowedCredentials());
|
config.setAllowCredentials(appProperties.getCors().getAllow_Credentials());
|
||||||
|
|
||||||
// Create the interceptor and register it
|
// Create the interceptor and register it
|
||||||
CorsInterceptor interceptor = new CorsInterceptor(config);
|
CorsInterceptor interceptor = new CorsInterceptor(config);
|
||||||
@@ -257,39 +278,35 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
|
|
||||||
// If subscriptions are enabled, we want to register the interceptor that
|
// If subscriptions are enabled, we want to register the interceptor that
|
||||||
// will activate them and match results against them
|
// will activate them and match results against them
|
||||||
if (HapiProperties.getSubscriptionWebsocketEnabled() ||
|
if (appProperties.getSubscription() != null) {
|
||||||
HapiProperties.getSubscriptionEmailEnabled() ||
|
|
||||||
HapiProperties.getSubscriptionRestHookEnabled()) {
|
|
||||||
// Subscription debug logging
|
// Subscription debug logging
|
||||||
IInterceptorService interceptorService = appCtx.getBean(IInterceptorService.class);
|
|
||||||
interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor());
|
interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cascading deletes
|
// Cascading deletes
|
||||||
DaoRegistry daoRegistry = appCtx.getBean(DaoRegistry.class);
|
|
||||||
IInterceptorBroadcaster interceptorBroadcaster = appCtx.getBean(IInterceptorBroadcaster.class);
|
|
||||||
if (HapiProperties.getAllowCascadingDeletes()) {
|
if (appProperties.getAllow_cascading_deletes()) {
|
||||||
CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor(ctx, daoRegistry, interceptorBroadcaster);
|
CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor(ctx,
|
||||||
|
daoRegistry, interceptorBroadcaster);
|
||||||
getInterceptorService().registerInterceptor(cascadingDeleteInterceptor);
|
getInterceptorService().registerInterceptor(cascadingDeleteInterceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary Storage
|
// Binary Storage
|
||||||
if (HapiProperties.isBinaryStorageEnabled()) {
|
if (appProperties.getBinary_storage_enabled()) {
|
||||||
BinaryStorageInterceptor binaryStorageInterceptor = appCtx
|
|
||||||
.getBean(BinaryStorageInterceptor.class);
|
|
||||||
getInterceptorService().registerInterceptor(binaryStorageInterceptor);
|
getInterceptorService().registerInterceptor(binaryStorageInterceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
IValidatorModule validatorModule = appCtx.getBean(IValidatorModule.class);
|
|
||||||
if (validatorModule != null) {
|
if (validatorModule != null) {
|
||||||
if (HapiProperties.getValidateRequestsEnabled()) {
|
if (appProperties.getValidation().getRequests_enabled()) {
|
||||||
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
|
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
|
||||||
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
||||||
interceptor.setValidatorModules(Collections.singletonList(validatorModule));
|
interceptor.setValidatorModules(Collections.singletonList(validatorModule));
|
||||||
registerInterceptor(interceptor);
|
registerInterceptor(interceptor);
|
||||||
}
|
}
|
||||||
if (HapiProperties.getValidateResponsesEnabled()) {
|
if (appProperties.getValidation().getResponses_enabled()) {
|
||||||
ResponseValidatingInterceptor interceptor = new ResponseValidatingInterceptor();
|
ResponseValidatingInterceptor interceptor = new ResponseValidatingInterceptor();
|
||||||
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
||||||
interceptor.setValidatorModules(Collections.singletonList(validatorModule));
|
interceptor.setValidatorModules(Collections.singletonList(validatorModule));
|
||||||
@@ -298,40 +315,46 @@ public class BaseJpaRestfulServer extends RestfulServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GraphQL
|
// GraphQL
|
||||||
if (HapiProperties.getGraphqlEnabled()) {
|
if (appProperties.getGraphql_enabled()) {
|
||||||
if (fhirVersion.isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
|
if (fhirVersion.isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
|
||||||
registerProvider(appCtx.getBean(GraphQLProvider.class));
|
registerProvider(graphQLProvider.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HapiProperties.getAllowedBundleTypes().isEmpty()) {
|
if (appProperties.getAllowed_bundle_types() != null) {
|
||||||
String allowedBundleTypesString = HapiProperties.getAllowedBundleTypes();
|
daoConfig.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet()));
|
||||||
Set<String> allowedBundleTypes = new HashSet<>();
|
|
||||||
Arrays.stream(allowedBundleTypesString.split(",")).forEach(o -> {
|
|
||||||
BundleType type = BundleType.valueOf(o);
|
|
||||||
allowedBundleTypes.add(type.toCode());
|
|
||||||
});
|
|
||||||
DaoConfig config = daoConfig;
|
|
||||||
config.setBundleTypesAllowedForStorage(
|
|
||||||
Collections.unmodifiableSet(new TreeSet<>(allowedBundleTypes)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
daoConfig.setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size());
|
||||||
|
|
||||||
// Bulk Export
|
// Bulk Export
|
||||||
if (HapiProperties.getBulkExportEnabled()) {
|
if (appProperties.getBulk_export_enabled()) {
|
||||||
registerProvider(appCtx.getBean(BulkDataExportProvider.class));
|
registerProvider(bulkDataExportProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Partitioning
|
// Partitioning
|
||||||
if (HapiProperties.getPartitioningMultitenancyEnabled()) {
|
if (appProperties.getPartitioning() != null) {
|
||||||
registerInterceptor(new RequestTenantPartitionInterceptor());
|
registerInterceptor(new RequestTenantPartitionInterceptor());
|
||||||
setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
||||||
registerProviders(appCtx.getBean(PartitionManagementProvider.class));
|
registerProviders(partitionManagementProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HapiProperties.getClientIdStrategy() == DaoConfig.ClientIdStrategyEnum.ANY) {
|
if (appProperties.getClient_id_strategy() == DaoConfig.ClientIdStrategyEnum.ANY) {
|
||||||
daoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID);
|
daoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID);
|
||||||
daoConfig.setResourceClientIdStrategy(HapiProperties.getClientIdStrategy());
|
daoConfig.setResourceClientIdStrategy(appProperties.getClient_id_strategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appProperties.getImplementationGuides() != null) {
|
||||||
|
List<AppProperties.ImplementationGuide> guides = appProperties.getImplementationGuides();
|
||||||
|
for (AppProperties.ImplementationGuide guide : guides) {
|
||||||
|
packageInstallerSvc.install(new PackageInstallationSpec()
|
||||||
|
.setPackageUrl(guide.getUrl())
|
||||||
|
.setName(guide.getName())
|
||||||
|
.setVersion(guide.getVersion())
|
||||||
|
.setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
92
src/main/java/ca/uhn/fhir/jpa/starter/EnvironmentHelper.java
Normal file
92
src/main/java/ca/uhn/fhir/jpa/starter/EnvironmentHelper.java
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
|
import org.springframework.core.env.CompositePropertySource;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.EnumerablePropertySource;
|
||||||
|
import org.springframework.core.env.PropertySource;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class EnvironmentHelper {
|
||||||
|
|
||||||
|
public static Properties getHibernateProperties(ConfigurableEnvironment environment) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
if (environment.getProperty("spring.jpa.properties", String.class) == null) {
|
||||||
|
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
|
||||||
|
properties.put("hibernate.search.model_mapping", "ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory");
|
||||||
|
properties.put("hibernate.format_sql", "false");
|
||||||
|
properties.put("hibernate.show_sql", "false");
|
||||||
|
properties.put("hibernate.hbm2ddl.auto", "update");
|
||||||
|
properties.put("hibernate.jdbc.batch_size", "20");
|
||||||
|
properties.put("hibernate.cache.use_query_cache", "false");
|
||||||
|
properties.put("hibernate.cache.use_second_level_cache", "false");
|
||||||
|
properties.put("hibernate.cache.use_structured_entries", "false");
|
||||||
|
properties.put("hibernate.cache.use_minimal_puts", "false");
|
||||||
|
properties.put("hibernate.search.default.directory_provider", "filesystem");
|
||||||
|
properties.put("hibernate.search.default.indexBase", "target/lucenefiles");
|
||||||
|
properties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
|
||||||
|
} else {
|
||||||
|
Arrays.asList(environment.getProperty("spring.jpa.properties", String.class).split(" ")).stream().forEach(s ->
|
||||||
|
{
|
||||||
|
String[] values = s.split("=");
|
||||||
|
properties.put(values[0], values[1]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getPropertiesStartingWith(ConfigurableEnvironment aEnv,
|
||||||
|
String aKeyPrefix) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
Map<String, Object> map = getAllProperties(aEnv);
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
|
||||||
|
if (key.startsWith(aKeyPrefix)) {
|
||||||
|
result.put(key, entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getAllProperties(ConfigurableEnvironment aEnv) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
aEnv.getPropertySources().forEach(ps -> addAll(result, getAllProperties(ps)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> getAllProperties(PropertySource<?> aPropSource) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
if (aPropSource instanceof CompositePropertySource) {
|
||||||
|
CompositePropertySource cps = (CompositePropertySource) aPropSource;
|
||||||
|
cps.getPropertySources().forEach(ps -> addAll(result, getAllProperties(ps)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aPropSource instanceof EnumerablePropertySource<?>) {
|
||||||
|
EnumerablePropertySource<?> ps = (EnumerablePropertySource<?>) aPropSource;
|
||||||
|
Arrays.asList(ps.getPropertyNames()).forEach(key -> result.put(key, ps.getProperty(key)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addAll(Map<String, Object> aBase, Map<String, Object> aToBeAdded) {
|
||||||
|
for (Map.Entry<String, Object> entry : aToBeAdded.entrySet()) {
|
||||||
|
if (aBase.containsKey(entry.getKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
aBase.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,17 +8,14 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
|||||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory;
|
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory;
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.JavaMailEmailSender;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.JavaMailEmailSender;
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import com.google.common.base.Strings;
|
||||||
import org.hl7.fhir.dstu2.model.Subscription;
|
import org.hl7.fhir.dstu2.model.Subscription;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
import org.thymeleaf.util.Validate;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.util.Optional;
|
||||||
import java.sql.Driver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the primary configuration file for the example server
|
* This is the primary configuration file for the example server
|
||||||
@@ -29,57 +26,34 @@ public class FhirServerConfigCommon {
|
|||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
|
||||||
|
|
||||||
private Boolean enableIndexMissingFields = HapiProperties.getEnableIndexMissingFields();
|
|
||||||
private Boolean autoCreatePlaceholderReferenceTargets = HapiProperties.getAutoCreatePlaceholderReferenceTargets();
|
|
||||||
private Boolean enforceReferentialIntegrityOnWrite = HapiProperties.getEnforceReferentialIntegrityOnWrite();
|
|
||||||
private Boolean enforceReferentialIntegrityOnDelete = HapiProperties.getEnforceReferentialIntegrityOnDelete();
|
|
||||||
private Boolean allowContainsSearches = HapiProperties.getAllowContainsSearches();
|
|
||||||
private Boolean allowMultipleDelete = HapiProperties.getAllowMultipleDelete();
|
|
||||||
private Boolean allowExternalReferences = HapiProperties.getAllowExternalReferences();
|
|
||||||
private Boolean expungeEnabled = HapiProperties.getExpungeEnabled();
|
|
||||||
private Boolean allowPlaceholderReferences = HapiProperties.getAllowPlaceholderReferences();
|
|
||||||
private Boolean subscriptionRestHookEnabled = HapiProperties.getSubscriptionRestHookEnabled();
|
|
||||||
private Boolean subscriptionEmailEnabled = HapiProperties.getSubscriptionEmailEnabled();
|
|
||||||
private Boolean allowOverrideDefaultSearchParams = HapiProperties.getAllowOverrideDefaultSearchParams();
|
|
||||||
private String emailFrom = HapiProperties.getEmailFrom();
|
|
||||||
private Boolean emailEnabled = HapiProperties.getEmailEnabled();
|
|
||||||
private String emailHost = HapiProperties.getEmailHost();
|
|
||||||
private Integer emailPort = HapiProperties.getEmailPort();
|
|
||||||
private String emailUsername = HapiProperties.getEmailUsername();
|
|
||||||
private String emailPassword = HapiProperties.getEmailPassword();
|
|
||||||
private Boolean emailAuth = HapiProperties.getEmailAuth();
|
|
||||||
private Boolean emailStartTlsEnable = HapiProperties.getEmailStartTlsEnable();
|
|
||||||
private Boolean emailStartTlsRequired = HapiProperties.getEmailStartTlsRequired();
|
|
||||||
private Boolean emailQuitWait = HapiProperties.getEmailQuitWait();
|
|
||||||
@Autowired
|
|
||||||
private ApplicationContext myAppCtx;
|
|
||||||
|
|
||||||
public FhirServerConfigCommon() {
|
public FhirServerConfigCommon(AppProperties appProperties) {
|
||||||
ourLog.info("Server configured to " + (this.allowContainsSearches ? "allow" : "deny") + " contains searches");
|
ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny") + " contains searches");
|
||||||
ourLog.info("Server configured to " + (this.allowMultipleDelete ? "allow" : "deny") + " multiple deletes");
|
ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny") + " multiple deletes");
|
||||||
ourLog.info("Server configured to " + (this.allowExternalReferences ? "allow" : "deny") + " external references");
|
ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny") + " external references");
|
||||||
ourLog.info("Server configured to " + (this.expungeEnabled ? "enable" : "disable") + " expunges");
|
ourLog.info("Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges");
|
||||||
ourLog.info("Server configured to " + (this.allowPlaceholderReferences ? "allow" : "deny") + " placeholder references");
|
ourLog.info("Server configured to " + (appProperties.getAllow_placeholder_references() ? "allow" : "deny") + " placeholder references");
|
||||||
ourLog.info("Server configured to " + (this.allowOverrideDefaultSearchParams ? "allow" : "deny") + " overriding default search params");
|
ourLog.info("Server configured to " + (appProperties.getAllow_override_default_search_params() ? "allow" : "deny") + " overriding default search params");
|
||||||
|
|
||||||
if (this.emailEnabled) {
|
if (appProperties.getSubscription().getEmail() != null) {
|
||||||
ourLog.info("Server is configured to enable email with host '" + this.emailHost + "' and port " + this.emailPort.toString());
|
AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail();
|
||||||
ourLog.info("Server will use '" + this.emailFrom + "' as the from email address");
|
ourLog.info("Server is configured to enable email with host '" + email.getHost() + "' and port " + email.getPort());
|
||||||
|
ourLog.info("Server will use '" + email.getFrom() + "' as the from email address");
|
||||||
|
|
||||||
if (this.emailUsername != null && this.emailUsername.length() > 0) {
|
if (!Strings.isNullOrEmpty(email.getUsername())) {
|
||||||
ourLog.info("Server is configured to use username '" + this.emailUsername + "' for email");
|
ourLog.info("Server is configured to use username '" + email.getUsername() + "' for email");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.emailPassword != null && this.emailPassword.length() > 0) {
|
if (!Strings.isNullOrEmpty(email.getPassword())) {
|
||||||
ourLog.info("Server is configured to use a password for email");
|
ourLog.info("Server is configured to use a password for email");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.subscriptionRestHookEnabled) {
|
if (appProperties.getSubscription().getResthook_enabled()) {
|
||||||
ourLog.info("REST-hook subscriptions enabled");
|
ourLog.info("REST-hook subscriptions enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.subscriptionEmailEnabled) {
|
if (appProperties.getSubscription().getEmail() != null) {
|
||||||
ourLog.info("Email subscriptions enabled");
|
ourLog.info("Email subscriptions enabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,56 +62,60 @@ public class FhirServerConfigCommon {
|
|||||||
* Configure FHIR properties around the the JPA server via this bean
|
* Configure FHIR properties around the the JPA server via this bean
|
||||||
*/
|
*/
|
||||||
@Bean()
|
@Bean()
|
||||||
public DaoConfig daoConfig() {
|
public DaoConfig daoConfig(AppProperties appProperties) {
|
||||||
DaoConfig retVal = new DaoConfig();
|
DaoConfig retVal = new DaoConfig();
|
||||||
|
|
||||||
retVal.setIndexMissingFields(this.enableIndexMissingFields ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
|
retVal.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
|
||||||
retVal.setAutoCreatePlaceholderReferenceTargets(this.autoCreatePlaceholderReferenceTargets);
|
retVal.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets());
|
||||||
retVal.setEnforceReferentialIntegrityOnWrite(this.enforceReferentialIntegrityOnWrite);
|
retVal.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write());
|
||||||
retVal.setEnforceReferentialIntegrityOnDelete(this.enforceReferentialIntegrityOnDelete);
|
retVal.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete());
|
||||||
retVal.setAllowContainsSearches(this.allowContainsSearches);
|
retVal.setAllowContainsSearches(appProperties.getAllow_contains_searches());
|
||||||
retVal.setAllowMultipleDelete(this.allowMultipleDelete);
|
retVal.setAllowMultipleDelete(appProperties.getAllow_multiple_delete());
|
||||||
retVal.setAllowExternalReferences(this.allowExternalReferences);
|
retVal.setAllowExternalReferences(appProperties.getAllow_external_references());
|
||||||
retVal.setExpungeEnabled(this.expungeEnabled);
|
retVal.setExpungeEnabled(appProperties.getExpunge_enabled());
|
||||||
retVal.setAutoCreatePlaceholderReferenceTargets(this.allowPlaceholderReferences);
|
retVal.setAutoCreatePlaceholderReferenceTargets(appProperties.getAllow_placeholder_references());
|
||||||
retVal.setEmailFromAddress(this.emailFrom);
|
if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null)
|
||||||
|
retVal.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom());
|
||||||
|
|
||||||
Integer maxFetchSize = HapiProperties.getMaximumFetchSize();
|
Integer maxFetchSize = appProperties.getMax_page_size();
|
||||||
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
|
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
|
||||||
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
|
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
|
||||||
|
|
||||||
Long reuseCachedSearchResultsMillis = HapiProperties.getReuseCachedSearchResultsMillis();
|
Long reuseCachedSearchResultsMillis = appProperties.getReuse_cached_search_results_millis();
|
||||||
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
|
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
|
||||||
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
|
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
|
||||||
|
|
||||||
Long retainCachedSearchesMinutes = HapiProperties.getExpireSearchResultsAfterMins();
|
|
||||||
|
Long retainCachedSearchesMinutes = appProperties.getRetain_cached_searches_mins();
|
||||||
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
|
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
|
||||||
|
|
||||||
|
if(appProperties.getSubscription() != null) {
|
||||||
// Subscriptions are enabled by channel type
|
// Subscriptions are enabled by channel type
|
||||||
if (HapiProperties.getSubscriptionRestHookEnabled()) {
|
if (appProperties.getSubscription().getResthook_enabled()) {
|
||||||
ourLog.info("Enabling REST-hook subscriptions");
|
ourLog.info("Enabling REST-hook subscriptions");
|
||||||
retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK);
|
retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK);
|
||||||
}
|
}
|
||||||
if (HapiProperties.getSubscriptionEmailEnabled()) {
|
if (appProperties.getSubscription().getEmail() != null) {
|
||||||
ourLog.info("Enabling email subscriptions");
|
ourLog.info("Enabling email subscriptions");
|
||||||
retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL);
|
retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL);
|
||||||
}
|
}
|
||||||
if (HapiProperties.getSubscriptionWebsocketEnabled()) {
|
if (appProperties.getSubscription().getWebsocket_enabled()) {
|
||||||
ourLog.info("Enabling websocket subscriptions");
|
ourLog.info("Enabling websocket subscriptions");
|
||||||
retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.WEBSOCKET);
|
retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.WEBSOCKET);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
retVal.setFilterParameterEnabled(HapiProperties.getFilterSearchEnabled());
|
retVal.setFilterParameterEnabled(appProperties.getFilter_search_enabled());
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PartitionSettings partitionSettings() {
|
public PartitionSettings partitionSettings(AppProperties appProperties) {
|
||||||
PartitionSettings retVal = new PartitionSettings();
|
PartitionSettings retVal = new PartitionSettings();
|
||||||
|
|
||||||
// Partitioning
|
// Partitioning
|
||||||
if (HapiProperties.getPartitioningMultitenancyEnabled()) {
|
if (appProperties.getPartitioning() != null) {
|
||||||
retVal.setPartitioningEnabled(true);
|
retVal.setPartitioningEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,19 +124,20 @@ public class FhirServerConfigCommon {
|
|||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ModelConfig modelConfig() {
|
public ModelConfig modelConfig(AppProperties appProperties) {
|
||||||
ModelConfig modelConfig = new ModelConfig();
|
ModelConfig modelConfig = new ModelConfig();
|
||||||
modelConfig.setAllowContainsSearches(this.allowContainsSearches);
|
modelConfig.setAllowContainsSearches(appProperties.getAllow_contains_searches());
|
||||||
modelConfig.setAllowExternalReferences(this.allowExternalReferences);
|
modelConfig.setAllowExternalReferences(appProperties.getAllow_external_references());
|
||||||
modelConfig.setDefaultSearchParamsCanBeOverridden(this.allowOverrideDefaultSearchParams);
|
modelConfig.setDefaultSearchParamsCanBeOverridden(appProperties.getAllow_override_default_search_params());
|
||||||
modelConfig.setEmailFromAddress(this.emailFrom);
|
if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null)
|
||||||
|
modelConfig.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom());
|
||||||
|
|
||||||
// You can enable these if you want to support Subscriptions from your server
|
// You can enable these if you want to support Subscriptions from your server
|
||||||
if (this.subscriptionRestHookEnabled) {
|
if (appProperties.getSubscription() != null && appProperties.getSubscription().getResthook_enabled() != null) {
|
||||||
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.subscriptionEmailEnabled) {
|
if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) {
|
||||||
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +150,7 @@ public class FhirServerConfigCommon {
|
|||||||
* <p>
|
* <p>
|
||||||
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
||||||
*/
|
*/
|
||||||
@Bean(destroyMethod = "close")
|
/*@Bean(destroyMethod = "close")
|
||||||
public BasicDataSource dataSource() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
public BasicDataSource dataSource() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||||
BasicDataSource retVal = new BasicDataSource();
|
BasicDataSource retVal = new BasicDataSource();
|
||||||
Driver driver = (Driver) Class.forName(HapiProperties.getDataSourceDriver()).getConstructor().newInstance();
|
Driver driver = (Driver) Class.forName(HapiProperties.getDataSourceDriver()).getConstructor().newInstance();
|
||||||
@@ -181,38 +160,37 @@ public class FhirServerConfigCommon {
|
|||||||
retVal.setPassword(HapiProperties.getDataSourcePassword());
|
retVal.setPassword(HapiProperties.getDataSourcePassword());
|
||||||
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
|
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Bean
|
@Bean
|
||||||
public IBinaryStorageSvc binaryStorageSvc() {
|
public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) {
|
||||||
DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
|
DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
|
||||||
|
|
||||||
if (HapiProperties.getMaxBinarySize() != null) {
|
if (appProperties.getMax_binary_size() != null) {
|
||||||
binaryStorageSvc.setMaximumBinarySize(HapiProperties.getMaxBinarySize());
|
binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
return binaryStorageSvc;
|
return binaryStorageSvc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean()
|
@Bean()
|
||||||
public IEmailSender emailSender() {
|
public IEmailSender emailSender(AppProperties appProperties, Optional<SubscriptionDeliveryHandlerFactory> subscriptionDeliveryHandlerFactory) {
|
||||||
if (this.emailEnabled) {
|
if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) {
|
||||||
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
||||||
|
|
||||||
retVal.setSmtpServerHostname(this.emailHost);
|
AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail();
|
||||||
retVal.setSmtpServerPort(this.emailPort);
|
retVal.setSmtpServerHostname(email.getHost());
|
||||||
retVal.setSmtpServerUsername(this.emailUsername);
|
retVal.setSmtpServerPort(email.getPort());
|
||||||
retVal.setSmtpServerPassword(this.emailPassword);
|
retVal.setSmtpServerUsername(email.getUsername());
|
||||||
retVal.setAuth(this.emailAuth);
|
retVal.setSmtpServerPassword(email.getPassword());
|
||||||
retVal.setStartTlsEnable(this.emailStartTlsEnable);
|
retVal.setAuth(email.getAuth());
|
||||||
retVal.setStartTlsRequired(this.emailStartTlsRequired);
|
retVal.setStartTlsEnable(email.getStartTlsEnable());
|
||||||
retVal.setQuitWait(this.emailQuitWait);
|
retVal.setStartTlsRequired(email.getStartTlsRequired());
|
||||||
|
retVal.setQuitWait(email.getQuitWait());
|
||||||
SubscriptionDeliveryHandlerFactory subscriptionDeliveryHandlerFactory = myAppCtx.getBean(SubscriptionDeliveryHandlerFactory.class);
|
|
||||||
Validate.notNull(subscriptionDeliveryHandlerFactory, "No subscription delivery handler");
|
|
||||||
subscriptionDeliveryHandlerFactory.setEmailSender(retVal);
|
|
||||||
|
|
||||||
|
if(subscriptionDeliveryHandlerFactory.isPresent())
|
||||||
|
subscriptionDeliveryHandlerFactory.get().setEmailSender(retVal);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,20 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Profile("dstu2")
|
||||||
public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
|
public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -24,14 +31,20 @@ public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
|
|||||||
* the default/max page sizes for search results. You can set these however
|
* the default/max page sizes for search results. You can set these however
|
||||||
* you want, although very large page sizes will require a lot of RAM.
|
* you want, although very large page sizes will require a lot of RAM.
|
||||||
*/
|
*/
|
||||||
|
@Autowired
|
||||||
|
AppProperties appProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
||||||
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
||||||
pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
|
pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
|
||||||
pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
|
pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
|
||||||
return pagingProvider;
|
return pagingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurableEnvironment configurableEnvironment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean()
|
@Bean()
|
||||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||||
@@ -43,8 +56,7 @@ public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
||||||
}
|
}
|
||||||
|
retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
|
||||||
retVal.setJpaProperties(HapiProperties.getJpaProperties());
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,4 +68,5 @@ public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
|
||||||
@@ -14,6 +16,7 @@ import javax.persistence.EntityManagerFactory;
|
|||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Profile("dstu3")
|
||||||
public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
|
public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -24,14 +27,20 @@ public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
|
|||||||
* the default/max page sizes for search results. You can set these however
|
* the default/max page sizes for search results. You can set these however
|
||||||
* you want, although very large page sizes will require a lot of RAM.
|
* you want, although very large page sizes will require a lot of RAM.
|
||||||
*/
|
*/
|
||||||
|
@Autowired
|
||||||
|
AppProperties appProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
||||||
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
||||||
pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
|
pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
|
||||||
pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
|
pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
|
||||||
return pagingProvider;
|
return pagingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurableEnvironment configurableEnvironment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean
|
@Bean
|
||||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||||
@@ -44,7 +53,7 @@ public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
|
|||||||
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal.setJpaProperties(HapiProperties.getJpaProperties());
|
retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,19 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Profile("r4")
|
||||||
public class FhirServerConfigR4 extends BaseJavaConfigR4 {
|
public class FhirServerConfigR4 extends BaseJavaConfigR4 {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -24,14 +30,20 @@ public class FhirServerConfigR4 extends BaseJavaConfigR4 {
|
|||||||
* the default/max page sizes for search results. You can set these however
|
* the default/max page sizes for search results. You can set these however
|
||||||
* you want, although very large page sizes will require a lot of RAM.
|
* you want, although very large page sizes will require a lot of RAM.
|
||||||
*/
|
*/
|
||||||
|
@Autowired
|
||||||
|
AppProperties appProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
||||||
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
||||||
pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
|
pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
|
||||||
pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
|
pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
|
||||||
return pagingProvider;
|
return pagingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurableEnvironment configurableEnvironment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean()
|
@Bean()
|
||||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||||
@@ -44,7 +56,7 @@ public class FhirServerConfigR4 extends BaseJavaConfigR4 {
|
|||||||
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal.setJpaProperties(HapiProperties.getJpaProperties());
|
retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
|
||||||
@@ -14,6 +16,7 @@ import javax.persistence.EntityManagerFactory;
|
|||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Profile("r5")
|
||||||
public class FhirServerConfigR5 extends BaseJavaConfigR5 {
|
public class FhirServerConfigR5 extends BaseJavaConfigR5 {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -24,14 +27,20 @@ public class FhirServerConfigR5 extends BaseJavaConfigR5 {
|
|||||||
* the default/max page sizes for search results. You can set these however
|
* the default/max page sizes for search results. You can set these however
|
||||||
* you want, although very large page sizes will require a lot of RAM.
|
* you want, although very large page sizes will require a lot of RAM.
|
||||||
*/
|
*/
|
||||||
|
@Autowired
|
||||||
|
AppProperties appProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
|
||||||
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
|
||||||
pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
|
pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
|
||||||
pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
|
pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
|
||||||
return pagingProvider;
|
return pagingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConfigurableEnvironment configurableEnvironment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Bean()
|
@Bean()
|
||||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||||
@@ -44,7 +53,7 @@ public class FhirServerConfigR5 extends BaseJavaConfigR5 {
|
|||||||
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal.setJpaProperties(HapiProperties.getJpaProperties());
|
retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package ca.uhn.fhir.jpa.starter;
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.to.FhirTesterMvcConfig;
|
import ca.uhn.fhir.to.FhirTesterMvcConfig;
|
||||||
import ca.uhn.fhir.to.TesterConfig;
|
import ca.uhn.fhir.to.TesterConfig;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
/**
|
/**
|
||||||
@@ -35,15 +34,19 @@ public class FhirTesterConfig {
|
|||||||
* you might want to use that instead of using the variable.
|
* you might want to use that instead of using the variable.
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public TesterConfig testerConfig() {
|
public TesterConfig testerConfig(AppProperties appProperties) {
|
||||||
TesterConfig retVal = new TesterConfig();
|
TesterConfig retVal = new TesterConfig();
|
||||||
|
appProperties.getTester().stream().forEach(t -> {
|
||||||
retVal
|
retVal
|
||||||
.addServer()
|
.addServer()
|
||||||
.withId(HapiProperties.getServerId())
|
.withId(t.getId())
|
||||||
.withFhirVersion(HapiProperties.getFhirVersion())
|
.withFhirVersion(t.getFhir_version())
|
||||||
.withBaseUrl(HapiProperties.getServerAddress())
|
.withBaseUrl(t.getServer_address())
|
||||||
.withName(HapiProperties.getServerName());
|
.withName(t.getName());
|
||||||
retVal.setRefuseToFetchThirdPartyUrls(HapiProperties.getTesterConfigRefustToFetchThirdPartyUrls());
|
retVal.setRefuseToFetchThirdPartyUrls(
|
||||||
|
t.getRefuse_to_fetch_third_party_urls());
|
||||||
|
|
||||||
|
});
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,535 +0,0 @@
|
|||||||
package ca.uhn.fhir.jpa.starter;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
|
||||||
import ca.uhn.fhir.jpa.search.elastic.ElasticsearchHibernatePropertiesBuilder;
|
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
|
||||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.hibernate.search.elasticsearch.cfg.ElasticsearchIndexStatus;
|
|
||||||
import org.hibernate.search.elasticsearch.cfg.IndexSchemaManagementStrategy;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
|
||||||
|
|
||||||
public class HapiProperties {
|
|
||||||
static final String ENABLE_INDEX_MISSING_FIELDS = "enable_index_missing_fields";
|
|
||||||
static final String AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS = "auto_create_placeholder_reference_targets";
|
|
||||||
static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE = "enforce_referential_integrity_on_write";
|
|
||||||
static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE = "enforce_referential_integrity_on_delete";
|
|
||||||
static final String BINARY_STORAGE_ENABLED = "binary_storage.enabled";
|
|
||||||
static final String ALLOW_EXTERNAL_REFERENCES = "allow_external_references";
|
|
||||||
static final String ALLOW_MULTIPLE_DELETE = "allow_multiple_delete";
|
|
||||||
static final String ALLOW_PLACEHOLDER_REFERENCES = "allow_placeholder_references";
|
|
||||||
static final String REUSE_CACHED_SEARCH_RESULTS_MILLIS = "reuse_cached_search_results_millis";
|
|
||||||
static final String DATASOURCE_DRIVER = "datasource.driver";
|
|
||||||
static final String DATASOURCE_MAX_POOL_SIZE = "datasource.max_pool_size";
|
|
||||||
static final String DATASOURCE_PASSWORD = "datasource.password";
|
|
||||||
static final String DATASOURCE_URL = "datasource.url";
|
|
||||||
static final String DATASOURCE_USERNAME = "datasource.username";
|
|
||||||
static final String DEFAULT_ENCODING = "default_encoding";
|
|
||||||
static final String DEFAULT_PAGE_SIZE = "default_page_size";
|
|
||||||
static final String DEFAULT_PRETTY_PRINT = "default_pretty_print";
|
|
||||||
static final String ETAG_SUPPORT = "etag_support";
|
|
||||||
static final String FHIR_VERSION = "fhir_version";
|
|
||||||
static final String ALLOW_CASCADING_DELETES = "allow_cascading_deletes";
|
|
||||||
static final String HAPI_PROPERTIES = "hapi.properties";
|
|
||||||
static final String LOGGER_ERROR_FORMAT = "logger.error_format";
|
|
||||||
static final String LOGGER_FORMAT = "logger.format";
|
|
||||||
static final String LOGGER_LOG_EXCEPTIONS = "logger.log_exceptions";
|
|
||||||
static final String LOGGER_NAME = "logger.name";
|
|
||||||
static final String MAX_FETCH_SIZE = "max_fetch_size";
|
|
||||||
static final String MAX_PAGE_SIZE = "max_page_size";
|
|
||||||
static final String SERVER_ADDRESS = "server_address";
|
|
||||||
static final String SERVER_ID = "server.id";
|
|
||||||
static final String SERVER_NAME = "server.name";
|
|
||||||
static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled";
|
|
||||||
static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled";
|
|
||||||
static final String SUBSCRIPTION_WEBSOCKET_ENABLED = "subscription.websocket.enabled";
|
|
||||||
static final String EMPI_ENABLED = "empi.enabled";
|
|
||||||
static final String PARTITIONING_ENABLED = "partitioning.enabled";
|
|
||||||
static final String PARTITIONING_CROSS_PARTITION_REFERENCE_MODE = "partitioning.cross_partition_reference_mode";
|
|
||||||
static final String ALLOWED_BUNDLE_TYPES = "allowed_bundle_types";
|
|
||||||
static final String TEST_PORT = "test.port";
|
|
||||||
static final String TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS = "tester.config.refuse_to_fetch_third_party_urls";
|
|
||||||
static final String CORS_ENABLED = "cors.enabled";
|
|
||||||
static final String CORS_ALLOWED_ORIGIN = "cors.allowed_origin";
|
|
||||||
static final String CORS_ALLOW_CREDENTIALS = "cors.allowCredentials";
|
|
||||||
static final String ALLOW_CONTAINS_SEARCHES = "allow_contains_searches";
|
|
||||||
static final String ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS = "allow_override_default_search_params";
|
|
||||||
static final String EMAIL_FROM = "email.from";
|
|
||||||
static final String VALIDATE_REQUESTS_ENABLED = "validation.requests.enabled";
|
|
||||||
static final String VALIDATE_RESPONSES_ENABLED = "validation.responses.enabled";
|
|
||||||
static final String FILTER_SEARCH_ENABLED = "filter_search.enabled";
|
|
||||||
static final String GRAPHQL_ENABLED = "graphql.enabled";
|
|
||||||
static final String BULK_EXPORT_ENABLED = "bulk.export.enabled";
|
|
||||||
static final String EXPIRE_SEARCH_RESULTS_AFTER_MINS = "retain_cached_searches_mins";
|
|
||||||
static final String MAX_BINARY_SIZE = "max_binary_size";
|
|
||||||
static final String PARTITIONING_MULTITENANCY_ENABLED = "partitioning.multitenancy.enabled";
|
|
||||||
private static final String PARTITIONING_INCLUDE_PARTITION_IN_SEARCH_HASHES = "partitioning.partitioning_include_in_search_hashes";
|
|
||||||
static final String CLIENT_ID_STRATEGY = "daoconfig.client_id_strategy";
|
|
||||||
private static Properties ourProperties;
|
|
||||||
|
|
||||||
public static boolean isElasticSearchEnabled() {
|
|
||||||
return HapiProperties.getPropertyBoolean("elasticsearch.enabled", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Force the configuration to be reloaded
|
|
||||||
*/
|
|
||||||
public static void forceReload() {
|
|
||||||
ourProperties = null;
|
|
||||||
getProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is mostly here for unit tests. Use the actual properties file
|
|
||||||
* to set values
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
public static void setProperty(String theKey, String theValue) {
|
|
||||||
getProperties().setProperty(theKey, theValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Properties getJpaProperties() {
|
|
||||||
Properties retVal = loadProperties();
|
|
||||||
|
|
||||||
if (isElasticSearchEnabled()) {
|
|
||||||
ElasticsearchHibernatePropertiesBuilder builder = new ElasticsearchHibernatePropertiesBuilder();
|
|
||||||
builder.setRequiredIndexStatus(getPropertyEnum("elasticsearch.required_index_status", ElasticsearchIndexStatus.class, ElasticsearchIndexStatus.YELLOW));
|
|
||||||
builder.setRestUrl(getProperty("elasticsearch.rest_url"));
|
|
||||||
builder.setUsername(getProperty("elasticsearch.username"));
|
|
||||||
builder.setPassword(getProperty("elasticsearch.password"));
|
|
||||||
builder.setIndexSchemaManagementStrategy(getPropertyEnum("elasticsearch.schema_management_strategy", IndexSchemaManagementStrategy.class, IndexSchemaManagementStrategy.CREATE));
|
|
||||||
builder.setDebugRefreshAfterWrite(getPropertyBoolean("elasticsearch.debug.refresh_after_write", false));
|
|
||||||
builder.setDebugPrettyPrintJsonLog(getPropertyBoolean("elasticsearch.debug.pretty_print_json_log", false));
|
|
||||||
builder.apply(retVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Properties getProperties() {
|
|
||||||
if (ourProperties == null) {
|
|
||||||
Properties properties = loadProperties();
|
|
||||||
HapiProperties.ourProperties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ourProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static Properties loadProperties() {
|
|
||||||
// Load the configurable properties file
|
|
||||||
Properties properties;
|
|
||||||
try (InputStream in = HapiProperties.class.getClassLoader().getResourceAsStream(HAPI_PROPERTIES)) {
|
|
||||||
properties = new Properties();
|
|
||||||
properties.load(in);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ConfigurationException("Could not load HAPI properties", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties overrideProps = loadOverrideProperties();
|
|
||||||
if (overrideProps != null) {
|
|
||||||
properties.putAll(overrideProps);
|
|
||||||
}
|
|
||||||
properties.putAll(System.getenv().entrySet()
|
|
||||||
.stream()
|
|
||||||
.filter(e -> e.getValue() != null && properties.containsKey(e.getKey()))
|
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a configuration file path is explicitly specified via -Dhapi.properties=<path>, the properties there will
|
|
||||||
* be used to override the entries in the default hapi.properties file (currently under WEB-INF/classes)
|
|
||||||
*
|
|
||||||
* @return properties loaded from the explicitly specified configuraiton file if there is one, or null otherwise.
|
|
||||||
*/
|
|
||||||
private static Properties loadOverrideProperties() {
|
|
||||||
String confFile = System.getProperty(HAPI_PROPERTIES);
|
|
||||||
if (confFile != null) {
|
|
||||||
try {
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.load(new FileInputStream(confFile));
|
|
||||||
return props;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ConfigurationException("Could not load HAPI properties file: " + confFile, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getProperty(String propertyName) {
|
|
||||||
String env = "HAPI_" + propertyName.toUpperCase(Locale.US);
|
|
||||||
env = env.replace(".", "_");
|
|
||||||
env = env.replace("-", "_");
|
|
||||||
|
|
||||||
String propertyValue = System.getenv(env);
|
|
||||||
if (propertyValue != null) {
|
|
||||||
return propertyValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties properties = HapiProperties.getProperties();
|
|
||||||
if (properties != null) {
|
|
||||||
propertyValue = properties.getProperty(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return propertyValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getProperty(String propertyName, String defaultValue) {
|
|
||||||
String value = getProperty(propertyName);
|
|
||||||
|
|
||||||
if (value != null && value.length() > 0) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Boolean getBooleanProperty(String propertyName, Boolean defaultValue) {
|
|
||||||
String value = HapiProperties.getProperty(propertyName);
|
|
||||||
|
|
||||||
if (value == null || value.length() == 0) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Boolean.parseBoolean(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean getBooleanProperty(String propertyName, boolean defaultValue) {
|
|
||||||
return getBooleanProperty(propertyName, Boolean.valueOf(defaultValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Integer getIntegerProperty(String propertyName, Integer defaultValue) {
|
|
||||||
String value = HapiProperties.getProperty(propertyName);
|
|
||||||
|
|
||||||
if (value == null || value.length() == 0) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Integer.parseInt(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FhirVersionEnum getFhirVersion() {
|
|
||||||
String fhirVersionString = HapiProperties.getProperty(FHIR_VERSION);
|
|
||||||
|
|
||||||
if (fhirVersionString != null && fhirVersionString.length() > 0) {
|
|
||||||
return FhirVersionEnum.valueOf(fhirVersionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FhirVersionEnum.DSTU3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isBinaryStorageEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(BINARY_STORAGE_ENABLED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ETagSupportEnum getEtagSupport() {
|
|
||||||
String etagSupportString = HapiProperties.getProperty(ETAG_SUPPORT);
|
|
||||||
|
|
||||||
if (etagSupportString != null && etagSupportString.length() > 0) {
|
|
||||||
return ETagSupportEnum.valueOf(etagSupportString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ETagSupportEnum.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DaoConfig.ClientIdStrategyEnum getClientIdStrategy() {
|
|
||||||
String idStrategy = HapiProperties.getProperty(CLIENT_ID_STRATEGY);
|
|
||||||
|
|
||||||
if (idStrategy != null && idStrategy.length() > 0) {
|
|
||||||
return DaoConfig.ClientIdStrategyEnum.valueOf(idStrategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DaoConfig.ClientIdStrategyEnum.ALPHANUMERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EncodingEnum getDefaultEncoding() {
|
|
||||||
String defaultEncodingString = HapiProperties.getProperty(DEFAULT_ENCODING);
|
|
||||||
|
|
||||||
if (defaultEncodingString != null && defaultEncodingString.length() > 0) {
|
|
||||||
return EncodingEnum.valueOf(defaultEncodingString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EncodingEnum.JSON;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getDefaultPrettyPrint() {
|
|
||||||
return HapiProperties.getBooleanProperty(DEFAULT_PRETTY_PRINT, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getServerAddress() {
|
|
||||||
return HapiProperties.getProperty(SERVER_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer getDefaultPageSize() {
|
|
||||||
return HapiProperties.getIntegerProperty(DEFAULT_PAGE_SIZE, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer getMaximumPageSize() {
|
|
||||||
return HapiProperties.getIntegerProperty(MAX_PAGE_SIZE, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer getMaximumFetchSize() {
|
|
||||||
return HapiProperties.getIntegerProperty(MAX_FETCH_SIZE, Integer.MAX_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getLoggerName() {
|
|
||||||
return HapiProperties.getProperty(LOGGER_NAME, "fhirtest.access");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getLoggerFormat() {
|
|
||||||
return HapiProperties.getProperty(LOGGER_FORMAT, "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getLoggerErrorFormat() {
|
|
||||||
return HapiProperties.getProperty(LOGGER_ERROR_FORMAT, "ERROR - ${requestVerb} ${requestUrl}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getLoggerLogExceptions() {
|
|
||||||
return HapiProperties.getBooleanProperty(LOGGER_LOG_EXCEPTIONS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDataSourceDriver() {
|
|
||||||
return HapiProperties.getProperty(DATASOURCE_DRIVER, "org.apache.derby.jdbc.EmbeddedDriver");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer getDataSourceMaxPoolSize() {
|
|
||||||
return HapiProperties.getIntegerProperty(DATASOURCE_MAX_POOL_SIZE, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDataSourceUrl() {
|
|
||||||
return HapiProperties.getProperty(DATASOURCE_URL, "jdbc:derby:directory:target/jpaserver_derby_files;create=true");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDataSourceUsername() {
|
|
||||||
return HapiProperties.getProperty(DATASOURCE_USERNAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDataSourcePassword() {
|
|
||||||
return HapiProperties.getProperty(DATASOURCE_PASSWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getAllowMultipleDelete() {
|
|
||||||
return HapiProperties.getBooleanProperty(ALLOW_MULTIPLE_DELETE, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getAllowCascadingDeletes() {
|
|
||||||
return HapiProperties.getBooleanProperty(ALLOW_CASCADING_DELETES, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getAllowExternalReferences() {
|
|
||||||
return HapiProperties.getBooleanProperty(ALLOW_EXTERNAL_REFERENCES, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getExpungeEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty("expunge_enabled", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getTesterConfigRefustToFetchThirdPartyUrls() {
|
|
||||||
return HapiProperties.getBooleanProperty(TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getCorsEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(CORS_ENABLED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCorsAllowedOrigin() {
|
|
||||||
return HapiProperties.getProperty(CORS_ALLOWED_ORIGIN, "*");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAllowedBundleTypes() {
|
|
||||||
return HapiProperties.getProperty(ALLOWED_BUNDLE_TYPES, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static Set<String> getSupportedResourceTypes() {
|
|
||||||
String[] types = defaultString(getProperty("supported_resource_types")).split(",");
|
|
||||||
return Arrays.stream(types)
|
|
||||||
.map(StringUtils::trim)
|
|
||||||
.filter(StringUtils::isNotBlank)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getServerName() {
|
|
||||||
return HapiProperties.getProperty(SERVER_NAME, "Local Tester");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getServerId() {
|
|
||||||
return HapiProperties.getProperty(SERVER_ID, "home");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getAllowPlaceholderReferences() {
|
|
||||||
return HapiProperties.getBooleanProperty(ALLOW_PLACEHOLDER_REFERENCES, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getSubscriptionEmailEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(SUBSCRIPTION_EMAIL_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getSubscriptionRestHookEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(SUBSCRIPTION_RESTHOOK_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getSubscriptionWebsocketEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(SUBSCRIPTION_WEBSOCKET_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getEmpiEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(EMPI_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getPartitioningEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(PARTITIONING_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String getPartitioningCrossPartitionReferenceMode() {
|
|
||||||
return HapiProperties.getProperty(PARTITIONING_CROSS_PARTITION_REFERENCE_MODE, "NOT_ALLOWED");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getIncludePartitionInSearchHashes() {
|
|
||||||
return HapiProperties.getBooleanProperty(PARTITIONING_INCLUDE_PARTITION_IN_SEARCH_HASHES, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getAllowContainsSearches() {
|
|
||||||
return HapiProperties.getBooleanProperty(ALLOW_CONTAINS_SEARCHES, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getAllowOverrideDefaultSearchParams() {
|
|
||||||
return HapiProperties.getBooleanProperty(ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getEmailFrom() {
|
|
||||||
return HapiProperties.getProperty(EMAIL_FROM, "some@test.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getEmailEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty("email.enabled", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getEmailHost() {
|
|
||||||
return HapiProperties.getProperty("email.host");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer getEmailPort() {
|
|
||||||
return HapiProperties.getIntegerProperty("email.port", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getEmailUsername() {
|
|
||||||
return HapiProperties.getProperty("email.username");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getEmailPassword() {
|
|
||||||
return HapiProperties.getProperty("email.password");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defaults from https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html
|
|
||||||
public static Boolean getEmailAuth() {
|
|
||||||
return HapiProperties.getBooleanProperty("email.auth", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getEmailStartTlsEnable() {
|
|
||||||
return HapiProperties.getBooleanProperty("email.starttls.enable", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getEmailStartTlsRequired() {
|
|
||||||
return HapiProperties.getBooleanProperty("email.starttls.required", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getEmailQuitWait() {
|
|
||||||
return HapiProperties.getBooleanProperty("email.quitwait", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long getReuseCachedSearchResultsMillis() {
|
|
||||||
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
|
|
||||||
return Long.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Long getExpireSearchResultsAfterMins() {
|
|
||||||
String value = HapiProperties.getProperty(EXPIRE_SEARCH_RESULTS_AFTER_MINS, "60");
|
|
||||||
return Long.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Boolean getCorsAllowedCredentials() {
|
|
||||||
return HapiProperties.getBooleanProperty(CORS_ALLOW_CREDENTIALS, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getValidateRequestsEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(VALIDATE_REQUESTS_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getValidateResponsesEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(VALIDATE_RESPONSES_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getFilterSearchEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(FILTER_SEARCH_ENABLED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getGraphqlEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(GRAPHQL_ENABLED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getEnforceReferentialIntegrityOnDelete() {
|
|
||||||
return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getEnforceReferentialIntegrityOnWrite() {
|
|
||||||
return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getAutoCreatePlaceholderReferenceTargets() {
|
|
||||||
return HapiProperties.getBooleanProperty(AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getEnableIndexMissingFields() {
|
|
||||||
return HapiProperties.getBooleanProperty(ENABLE_INDEX_MISSING_FIELDS, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Integer getMaxBinarySize() {
|
|
||||||
return getIntegerProperty(MAX_BINARY_SIZE, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean getPropertyBoolean(String thePropertyName, boolean theDefaultValue) {
|
|
||||||
String value = getProperty(thePropertyName, Boolean.toString(theDefaultValue));
|
|
||||||
return Boolean.parseBoolean(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T extends Enum> T getPropertyEnum(String thePropertyName, Class<T> theEnumType, T theDefaultValue) {
|
|
||||||
String value = getProperty(thePropertyName, theDefaultValue.name());
|
|
||||||
return (T) Enum.valueOf(theEnumType, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getBulkExportEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(BULK_EXPORT_ENABLED, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFhirPathFilterInterceptorEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty("fhirpath_interceptor.enabled", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getPartitioningMultitenancyEnabled() {
|
|
||||||
return HapiProperties.getBooleanProperty(PARTITIONING_MULTITENANCY_ENABLED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,11 +1,22 @@
|
|||||||
package ca.uhn.fhir.jpa.starter;
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
@Import(AppProperties.class)
|
||||||
public class JpaRestfulServer extends BaseJpaRestfulServer {
|
public class JpaRestfulServer extends BaseJpaRestfulServer {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AppProperties appProperties;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public JpaRestfulServer() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initialize() throws ServletException {
|
protected void initialize() throws ServletException {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
|
|||||||
129
src/main/resources/application.yaml
Normal file
129
src/main/resources/application.yaml
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: 'jdbc:h2:file:./target/database/h2'
|
||||||
|
username: sa
|
||||||
|
password: null
|
||||||
|
driverClassName: org.h2.Driver
|
||||||
|
max-active: 15
|
||||||
|
profiles:
|
||||||
|
### This is the FHIR version. Choose between, dstu2, dstu3, r4 or r5
|
||||||
|
active: r4
|
||||||
|
jpa:
|
||||||
|
properties:
|
||||||
|
hibernate.dialect: org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.search.model_mapping: ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory
|
||||||
|
hibernate.format_sql: false
|
||||||
|
hibernate.show_sql: false
|
||||||
|
hibernate.hbm2ddl.auto: update
|
||||||
|
hibernate.jdbc.batch_size: 20
|
||||||
|
hibernate.cache.use_query_cache: false
|
||||||
|
hibernate.cache.use_second_level_cache: false
|
||||||
|
hibernate.cache.use_structured_entries: false
|
||||||
|
hibernate.cache.use_minimal_puts: false
|
||||||
|
hibernate.search.default.directory_provider: filesystem
|
||||||
|
hibernate.search.default.indexBase: target/lucenefiles
|
||||||
|
hibernate.search.lucene_version: LUCENE_CURRENT
|
||||||
|
|
||||||
|
hapi:
|
||||||
|
fhir:
|
||||||
|
defer_indexing_for_codesystems_of_size: 101
|
||||||
|
# implementationguides:
|
||||||
|
# -
|
||||||
|
# url: https://build.fhir.org/ig/hl7dk/dk-medcom/branches/corrections/package.tgz
|
||||||
|
# name: dk.fhir.ig.medcom-core
|
||||||
|
# version: 0.8.0
|
||||||
|
# -
|
||||||
|
# name: hl7.fhir.uv.ips
|
||||||
|
# version: 0.3.0
|
||||||
|
|
||||||
|
#supported_resource_types:
|
||||||
|
# - Patient
|
||||||
|
# - Observation
|
||||||
|
# allow_cascading_deletes: true
|
||||||
|
# allow_contains_searches: true
|
||||||
|
# allow_external_references: true
|
||||||
|
# allow_multiple_delete: true
|
||||||
|
# allow_override_default_search_params: true
|
||||||
|
# allow_placeholder_references: true
|
||||||
|
# auto_create_placeholder_reference_targets: false
|
||||||
|
# default_encoding: JSON
|
||||||
|
# default_pretty_print: true
|
||||||
|
# default_page_size: 20
|
||||||
|
# enable_index_missing_fields: false
|
||||||
|
# enforce_referential_integrity_on_delete: false
|
||||||
|
# enforce_referential_integrity_on_write: false
|
||||||
|
# etag_support_enabled: true
|
||||||
|
# expunge_enabled: true
|
||||||
|
# daoconfig_client_id_strategy: null
|
||||||
|
# fhirpath_interceptor_enabled: false
|
||||||
|
# filter_search_enabled: true
|
||||||
|
# graphql_enabled: true
|
||||||
|
#partitioning:
|
||||||
|
# cross_partition_reference_mode: true
|
||||||
|
# multitenancy_enabled: true
|
||||||
|
# partitioning_include_in_search_hashes: true
|
||||||
|
#cors:
|
||||||
|
# allow_Credentials: true
|
||||||
|
# Supports multiple, comma separated allowed origin entries
|
||||||
|
# cors.allowed_origin=http://localhost:8080,https://localhost:8080,https://fhirtest.uhn.ca
|
||||||
|
# allowed_origin:
|
||||||
|
# - '*'
|
||||||
|
|
||||||
|
# logger:
|
||||||
|
# error_format: 'ERROR - ${requestVerb} ${requestUrl}'
|
||||||
|
# format: >-
|
||||||
|
# Path[${servletPath}] Source[${requestHeader.x-forwarded-for}]
|
||||||
|
# Operation[${operationType} ${operationName} ${idOrResourceName}]
|
||||||
|
# UA[${requestHeader.user-agent}] Params[${requestParameters}]
|
||||||
|
# ResponseEncoding[${responseEncodingNoDefault}]
|
||||||
|
# log_exceptions: true
|
||||||
|
# name: fhirtest.access
|
||||||
|
# max_binary_size: 104857600
|
||||||
|
# max_page_size: 200
|
||||||
|
# retain_cached_searches_mins: 60
|
||||||
|
# reuse_cached_search_results_millis: 60000
|
||||||
|
tester:
|
||||||
|
-
|
||||||
|
id: home
|
||||||
|
name: Local Tester
|
||||||
|
server_address: 'http://localhost:8080/hapi-fhir-jpaserver/fhir'
|
||||||
|
refuse_to_fetch_third_party_urls: false
|
||||||
|
fhir_version: R4
|
||||||
|
-
|
||||||
|
id: global
|
||||||
|
name: Global Tester
|
||||||
|
server_address: "http://hapi.fhir.org/baseR4"
|
||||||
|
refuse_to_fetch_third_party_urls: false
|
||||||
|
fhir_version: R4
|
||||||
|
# validation:
|
||||||
|
# requests_enabled: true
|
||||||
|
# responses_enabled: true
|
||||||
|
# binary_storage_enabled: true
|
||||||
|
# bulk_export_enabled: true
|
||||||
|
# partitioning_multitenancy_enabled:
|
||||||
|
# subscription:
|
||||||
|
# resthook_enabled: false
|
||||||
|
# websocket_enabled: false
|
||||||
|
# email:
|
||||||
|
# from: some@test.com
|
||||||
|
# host: google.com
|
||||||
|
# port:
|
||||||
|
# username:
|
||||||
|
# password:
|
||||||
|
# auth:
|
||||||
|
# startTlsEnable:
|
||||||
|
# startTlsRequired:
|
||||||
|
# quitWait:
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#elasticsearch:
|
||||||
|
# debug:
|
||||||
|
# pretty_print_json_log: false
|
||||||
|
# refresh_after_write: false
|
||||||
|
# enabled: false
|
||||||
|
# password: SomePassword
|
||||||
|
# required_index_status: YELLOW
|
||||||
|
# rest_url: 'http://localhost:9200'
|
||||||
|
# schema_management_strategy: CREATE
|
||||||
|
# username: SomeUsername
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
# Adjust this to set the version of FHIR supported by this server. See
|
|
||||||
# FhirVersionEnum for a list of available constants. Example values include
|
|
||||||
# DSTU2, DSTU3, R4.
|
|
||||||
fhir_version=R4
|
|
||||||
|
|
||||||
# This is the address that the FHIR server will report as its own address.
|
|
||||||
# If this server will be deployed (for example) to an internet accessible
|
|
||||||
# server, put the DNS name of that server here.
|
|
||||||
#
|
|
||||||
# Note that this is also the address that the hapi-fhir-testpage-overlay
|
|
||||||
# (the web UI similar to the one at http://hapi.fhir.org) will use to
|
|
||||||
# connect internally to the FHIR server, so this also needs to be a name
|
|
||||||
# accessible from the server itself.
|
|
||||||
server_address=http://localhost:8080/hapi-fhir-jpaserver/fhir/
|
|
||||||
|
|
||||||
enable_index_missing_fields=false
|
|
||||||
auto_create_placeholder_reference_targets=false
|
|
||||||
enforce_referential_integrity_on_write=false
|
|
||||||
enforce_referential_integrity_on_delete=false
|
|
||||||
default_encoding=JSON
|
|
||||||
etag_support=ENABLED
|
|
||||||
reuse_cached_search_results_millis=60000
|
|
||||||
retain_cached_searches_mins=60
|
|
||||||
default_page_size=20
|
|
||||||
max_page_size=200
|
|
||||||
allow_override_default_search_params=true
|
|
||||||
allow_contains_searches=true
|
|
||||||
allow_multiple_delete=true
|
|
||||||
allow_external_references=true
|
|
||||||
allow_cascading_deletes=true
|
|
||||||
allow_placeholder_references=true
|
|
||||||
expunge_enabled=true
|
|
||||||
persistence_unit_name=HAPI_PU
|
|
||||||
logger.name=fhirtest.access
|
|
||||||
logger.format=Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]
|
|
||||||
logger.error_format=ERROR - ${requestVerb} ${requestUrl}
|
|
||||||
logger.log_exceptions=true
|
|
||||||
datasource.driver=org.h2.Driver
|
|
||||||
datasource.url=jdbc:h2:file:./target/database/h2
|
|
||||||
datasource.username=
|
|
||||||
datasource.password=
|
|
||||||
server.name=Local Tester
|
|
||||||
server.id=home
|
|
||||||
test.port=
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Binary Storage (104857600 = 100mb)
|
|
||||||
###################################################
|
|
||||||
max_binary_size=104857600
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Validation
|
|
||||||
###################################################
|
|
||||||
# Should all incoming requests be validated
|
|
||||||
validation.requests.enabled=false
|
|
||||||
# Should outgoing responses be validated
|
|
||||||
validation.responses.enabled=false
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Search Features
|
|
||||||
###################################################
|
|
||||||
filter_search.enabled=true
|
|
||||||
graphql.enabled=true
|
|
||||||
# See FhirPathFilterInterceptor
|
|
||||||
fhirpath_interceptor.enabled=false
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Supported Resources
|
|
||||||
###################################################
|
|
||||||
# Enable the following property if you want to customize the
|
|
||||||
# list of resources that is supported by the server (i.e. to
|
|
||||||
# disable specific resources)
|
|
||||||
#supported_resource_types=Patient,Observation,Encounter
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Database Settings
|
|
||||||
###################################################
|
|
||||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
|
||||||
hibernate.search.model_mapping=ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory
|
|
||||||
hibernate.format_sql=false
|
|
||||||
hibernate.show_sql=false
|
|
||||||
hibernate.hbm2ddl.auto=update
|
|
||||||
hibernate.jdbc.batch_size=20
|
|
||||||
hibernate.cache.use_query_cache=false
|
|
||||||
hibernate.cache.use_second_level_cache=false
|
|
||||||
hibernate.cache.use_structured_entries=false
|
|
||||||
hibernate.cache.use_minimal_puts=false
|
|
||||||
hibernate.search.default.directory_provider=filesystem
|
|
||||||
hibernate.search.default.indexBase=target/lucenefiles
|
|
||||||
hibernate.search.lucene_version=LUCENE_CURRENT
|
|
||||||
tester.config.refuse_to_fetch_third_party_urls=false
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
# ElasticSearch
|
|
||||||
# Note that using ElasticSearch is disabled by
|
|
||||||
# default and the server will use Lucene instead.
|
|
||||||
##################################################
|
|
||||||
elasticsearch.enabled=false
|
|
||||||
elasticsearch.rest_url=http://localhost:9200
|
|
||||||
elasticsearch.username=SomeUsername
|
|
||||||
elasticsearch.password=SomePassword
|
|
||||||
elasticsearch.required_index_status=YELLOW
|
|
||||||
elasticsearch.schema_management_strategy=CREATE
|
|
||||||
# Immediately refresh indexes after every write. This is very bad for
|
|
||||||
# performance, but can be helpful for testing.
|
|
||||||
elasticsearch.debug.refresh_after_write=false
|
|
||||||
elasticsearch.debug.pretty_print_json_log=false
|
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
# Binary Storage Operations
|
|
||||||
##################################################
|
|
||||||
binary_storage.enabled=true
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
# Bulk Data Specification
|
|
||||||
##################################################
|
|
||||||
bulk.export.enabled=true
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
# CORS Settings
|
|
||||||
##################################################
|
|
||||||
cors.enabled=true
|
|
||||||
cors.allowCredentials=true
|
|
||||||
# Supports multiple, comma separated allowed origin entries
|
|
||||||
# cors.allowed_origin=http://localhost:8080,https://localhost:8080,https://fhirtest.uhn.ca
|
|
||||||
cors.allowed_origin=*
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
# Allowed Bundle Types for persistence (defaults are: COLLECTION,DOCUMENT,MESSAGE)
|
|
||||||
##################################################
|
|
||||||
#allowed_bundle_types=COLLECTION,DOCUMENT,MESSAGE,TRANSACTION,TRANSACTIONRESPONSE,BATCH,BATCHRESPONSE,HISTORY,SEARCHSET
|
|
||||||
|
|
||||||
##################################################
|
|
||||||
# Subscriptions
|
|
||||||
##################################################
|
|
||||||
|
|
||||||
# Enable REST Hook Subscription Channel
|
|
||||||
subscription.resthook.enabled=false
|
|
||||||
|
|
||||||
# Enable Email Subscription Channel
|
|
||||||
subscription.email.enabled=false
|
|
||||||
email.enabled=false
|
|
||||||
email.from=some@test.com
|
|
||||||
email.host=
|
|
||||||
email.port=0
|
|
||||||
email.username=
|
|
||||||
email.password=
|
|
||||||
|
|
||||||
# Enable Websocket Subscription Channel
|
|
||||||
subscription.websocket.enabled=false
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# EMPI
|
|
||||||
###################################################
|
|
||||||
empi.enabled=false
|
|
||||||
|
|
||||||
###################################################
|
|
||||||
# Partitioning And Multitenancy
|
|
||||||
###################################################
|
|
||||||
partitioning.enabled=false
|
|
||||||
partitioning.cross_partition_reference_mode=NOT_ALLOWED
|
|
||||||
partitioning.partitioning_include_in_search_hashes=true
|
|
||||||
partitioning.multitenancy.enabled=false
|
|
||||||
|
|
||||||
#daoconfig.client_id_strategy=ANY
|
|
||||||
|
|
||||||
@@ -9,24 +9,6 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="EMPI_TROUBLESHOOTING" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
|
||||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>DEBUG</level></filter>
|
|
||||||
<file>${smile.basedir}/log/empi-troubleshooting.log</file>
|
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
|
||||||
<fileNamePattern>${smile.basedir}/log/empi-troubleshooting.log.%i.gz</fileNamePattern>
|
|
||||||
<minIndex>1</minIndex>
|
|
||||||
<maxIndex>9</maxIndex>
|
|
||||||
</rollingPolicy>
|
|
||||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
|
||||||
<maxFileSize>5MB</maxFileSize>
|
|
||||||
</triggeringPolicy>
|
|
||||||
<encoder>
|
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n${log.stackfilter.pattern}</pattern>
|
|
||||||
</encoder>
|
|
||||||
</appender>
|
|
||||||
<logger name="ca.uhn.fhir.log.empi_troubleshooting" level="TRACE">
|
|
||||||
<appender-ref ref="EMPI_TROUBLESHOOTING"/>
|
|
||||||
</logger>
|
|
||||||
|
|
||||||
<root level="INFO">
|
<root level="INFO">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
<web-app
|
|
||||||
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
|
||||||
metadata-complete="false"
|
|
||||||
version="3.1">
|
|
||||||
|
|
||||||
<listener>
|
|
||||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
<context-param>
|
|
||||||
<param-name>contextClass</param-name>
|
|
||||||
<param-value>
|
|
||||||
ca.uhn.fhir.jpa.starter.ApplicationContext
|
|
||||||
</param-value>
|
|
||||||
</context-param>
|
|
||||||
<context-param>
|
|
||||||
<param-name>contextConfigLocation</param-name>
|
|
||||||
<param-value>
|
|
||||||
</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- Servlets -->
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>spring</servlet-name>
|
|
||||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
|
||||||
<init-param>
|
|
||||||
<param-name>contextClass</param-name>
|
|
||||||
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
|
|
||||||
</init-param>
|
|
||||||
<init-param>
|
|
||||||
<param-name>contextConfigLocation</param-name>
|
|
||||||
<param-value>
|
|
||||||
ca.uhn.fhir.jpa.starter.FhirTesterConfig
|
|
||||||
</param-value>
|
|
||||||
</init-param>
|
|
||||||
<load-on-startup>2</load-on-startup>
|
|
||||||
</servlet>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>spring</servlet-name>
|
|
||||||
<url-pattern>/</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>fhirServlet</servlet-name>
|
|
||||||
<servlet-class>ca.uhn.fhir.jpa.starter.JpaRestfulServer</servlet-class>
|
|
||||||
<load-on-startup>1</load-on-startup>
|
|
||||||
</servlet>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>fhirServlet</servlet-name>
|
|
||||||
<url-pattern>/fhir/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
</web-app>
|
|
||||||
20
src/test/java/ca/uhn/fhir/jpa/starter/Demo.java
Normal file
20
src/test/java/ca/uhn/fhir/jpa/starter/Demo.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
|
||||||
|
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||||
|
|
||||||
|
@ServletComponentScan(basePackageClasses = {JpaRestfulServer.class})
|
||||||
|
@SpringBootApplication(exclude = ElasticsearchRestClientAutoConfiguration.class)
|
||||||
|
public class Demo {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
System.setProperty("spring.profiles.active", "r4");
|
||||||
|
System.setProperty("spring.batch.job.enabled", "false");
|
||||||
|
SpringApplication.run(Demo.class, args);
|
||||||
|
|
||||||
|
//Server is now accessible at eg. http://localhost:8080/metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,79 +5,53 @@ import ca.uhn.fhir.model.dstu2.resource.Patient;
|
|||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import java.nio.file.Paths;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
|
||||||
|
{
|
||||||
|
"spring.batch.job.enabled=false",
|
||||||
|
"spring.profiles.active=dstu2",
|
||||||
|
"spring.datasource.url=jdbc:h2:mem:dbr2"
|
||||||
|
})
|
||||||
public class ExampleServerDstu2IT {
|
public class ExampleServerDstu2IT {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
|
||||||
private static IGenericClient ourClient;
|
private IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx;
|
private FhirContext ourCtx;
|
||||||
private static int ourPort;
|
|
||||||
private static Server ourServer;
|
|
||||||
|
|
||||||
static {
|
@LocalServerPort
|
||||||
HapiProperties.forceReload();
|
private int port;
|
||||||
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU2");
|
|
||||||
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr2");
|
|
||||||
ourCtx = FhirContext.forDstu2();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndRead() {
|
void testCreateAndRead() {
|
||||||
ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
|
|
||||||
String methodName = "testCreateResourceConditional";
|
String methodName = "testCreateResourceConditional";
|
||||||
|
|
||||||
Patient pt = new Patient();
|
Patient pt = new Patient();
|
||||||
pt.addName().addFamily(methodName);
|
pt.addName().addFamily(methodName);
|
||||||
IIdType id = ourClient.create().resource(pt).execute().getId();
|
IIdType id = ourClient.create().resource(pt).execute().getId();
|
||||||
|
|
||||||
Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
|
Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
|
||||||
assertEquals(methodName, pt2.getName().get(0).getFamily().get(0).getValue());
|
assertEquals(methodName, pt2.getName().get(0).getFamily().get(0).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void afterClass() throws Exception {
|
|
||||||
ourServer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeEach
|
||||||
public static void beforeClass() throws Exception {
|
void beforeEach() {
|
||||||
String path = Paths.get("").toAbsolutePath().toString();
|
|
||||||
|
|
||||||
ourLog.info("Project base path is: {}", path);
|
|
||||||
|
|
||||||
ourServer = new Server(0);
|
|
||||||
|
|
||||||
WebAppContext webAppContext = new WebAppContext();
|
|
||||||
webAppContext.setContextPath("/hapi-fhir-jpaserver");
|
|
||||||
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
|
|
||||||
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
|
|
||||||
webAppContext.setParentLoaderPriority(true);
|
|
||||||
|
|
||||||
ourServer.setHandler(webAppContext);
|
|
||||||
ourServer.start();
|
|
||||||
|
|
||||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
|
||||||
|
|
||||||
|
ourCtx = FhirContext.forDstu2();
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
|
String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) throws Exception {
|
|
||||||
ourPort = 8080;
|
|
||||||
beforeClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
@@ -18,39 +15,44 @@ import org.hl7.fhir.dstu3.model.Observation;
|
|||||||
import org.hl7.fhir.dstu3.model.Patient;
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
import org.hl7.fhir.dstu3.model.Subscription;
|
import org.hl7.fhir.dstu3.model.Subscription;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static ca.uhn.fhir.util.TestUtil.waitForSize;
|
import static ca.uhn.fhir.util.TestUtil.waitForSize;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
|
||||||
|
{
|
||||||
|
"spring.batch.job.enabled=false",
|
||||||
|
"spring.profiles.active=dstu3",
|
||||||
|
"spring.datasource.url=jdbc:h2:mem:dbr3",
|
||||||
|
"hapi.fhir.subscription.websocket_enabled=true",
|
||||||
|
"hapi.fhir.allow_external_references=true",
|
||||||
|
"hapi.fhir.allow_placeholder_references=true",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
public class ExampleServerDstu3IT {
|
public class ExampleServerDstu3IT {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu3IT.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
|
||||||
private static IGenericClient ourClient;
|
private IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx;
|
private FhirContext ourCtx;
|
||||||
private static int ourPort;
|
|
||||||
private static Server ourServer;
|
|
||||||
|
|
||||||
static {
|
@LocalServerPort
|
||||||
HapiProperties.forceReload();
|
private int port;
|
||||||
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3");
|
|
||||||
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr3");
|
|
||||||
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
|
|
||||||
HapiProperties.setProperty(HapiProperties.ALLOW_EXTERNAL_REFERENCES, "true");
|
|
||||||
HapiProperties.setProperty(HapiProperties.ALLOW_PLACEHOLDER_REFERENCES, "true");
|
|
||||||
ourCtx = FhirContext.forDstu3();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndRead() {
|
public void testCreateAndRead() {
|
||||||
ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
|
|
||||||
String methodName = "testCreateResourceConditional";
|
String methodName = "testCreateResourceConditional";
|
||||||
|
|
||||||
Patient pt = new Patient();
|
Patient pt = new Patient();
|
||||||
@@ -90,7 +92,7 @@ public class ExampleServerDstu3IT {
|
|||||||
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
|
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
|
||||||
|
|
||||||
myWebSocketClient.start();
|
myWebSocketClient.start();
|
||||||
URI echoUri = new URI("ws://localhost:" + ourPort + "/hapi-fhir-jpaserver/websocket");
|
URI echoUri = new URI("ws://localhost:" + port + "/hapi-fhir-jpaserver/websocket");
|
||||||
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
||||||
ourLog.info("Connecting to : {}", echoUri);
|
ourLog.info("Connecting to : {}", echoUri);
|
||||||
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
|
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
|
||||||
@@ -119,39 +121,15 @@ public class ExampleServerDstu3IT {
|
|||||||
ourClient.delete().resourceById(mySubscriptionId).execute();
|
ourClient.delete().resourceById(mySubscriptionId).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
@BeforeEach
|
||||||
public static void afterClass() throws Exception {
|
void beforeEach() {
|
||||||
ourServer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void beforeClass() throws Exception {
|
|
||||||
String path = Paths.get("").toAbsolutePath().toString();
|
|
||||||
|
|
||||||
ourLog.info("Project base path is: {}", path);
|
|
||||||
|
|
||||||
ourServer = new Server(0);
|
|
||||||
|
|
||||||
WebAppContext webAppContext = new WebAppContext();
|
|
||||||
webAppContext.setContextPath("/hapi-fhir-jpaserver");
|
|
||||||
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
|
|
||||||
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
|
|
||||||
webAppContext.setParentLoaderPriority(true);
|
|
||||||
|
|
||||||
ourServer.setHandler(webAppContext);
|
|
||||||
ourServer.start();
|
|
||||||
|
|
||||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
|
||||||
|
|
||||||
|
ourCtx = FhirContext.forDstu3();
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
|
String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) throws Exception {
|
|
||||||
ourPort = 8080;
|
|
||||||
beforeClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,26 +7,20 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
|
||||||
import ca.uhn.fhir.util.BundleUtil;
|
import ca.uhn.fhir.util.BundleUtil;
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
import org.hl7.fhir.r4.model.*;
|
||||||
import org.hl7.fhir.r4.model.Observation;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
|
||||||
import org.hl7.fhir.r4.model.Person;
|
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
|
||||||
import org.hl7.fhir.r4.model.Subscription;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -38,26 +32,30 @@ import static org.awaitility.Awaitility.await;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
|
||||||
|
{
|
||||||
|
"spring.batch.job.enabled=false",
|
||||||
|
"spring.profiles.active=r4",
|
||||||
|
"spring.datasource.url=jdbc:h2:mem:dbr4",
|
||||||
|
"hapi.fhir.subscription.websocket_enabled=true",
|
||||||
|
"hapi.fhir.empi_enabled=true",
|
||||||
|
//Override is currently required when using Empi as the construction of the Empi beans are ambiguous as they are constructed multiple places. This is evident when running in a spring boot environment
|
||||||
|
"spring.main.allow-bean-definition-overriding=true"
|
||||||
|
})
|
||||||
public class ExampleServerR4IT {
|
public class ExampleServerR4IT {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerR4IT.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
|
||||||
private static IGenericClient ourClient;
|
private IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx;
|
private FhirContext ourCtx;
|
||||||
private static int ourPort;
|
|
||||||
private static Server ourServer;
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
static {
|
|
||||||
HapiProperties.forceReload();
|
|
||||||
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr4");
|
|
||||||
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R4");
|
|
||||||
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
|
|
||||||
HapiProperties.setProperty(HapiProperties.EMPI_ENABLED, "true");
|
|
||||||
ourCtx = FhirContext.forR4();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndRead() {
|
void testCreateAndRead() {
|
||||||
ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
|
|
||||||
String methodName = "testCreateResourceConditional";
|
String methodName = "testCreateResourceConditional";
|
||||||
|
|
||||||
Patient pt = new Patient();
|
Patient pt = new Patient();
|
||||||
@@ -121,7 +119,7 @@ public class ExampleServerR4IT {
|
|||||||
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
|
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
|
||||||
|
|
||||||
myWebSocketClient.start();
|
myWebSocketClient.start();
|
||||||
URI echoUri = new URI("ws://localhost:" + ourPort + "/hapi-fhir-jpaserver/websocket");
|
URI echoUri = new URI("ws://localhost:" + port + "/hapi-fhir-jpaserver/websocket");
|
||||||
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
||||||
ourLog.info("Connecting to : {}", echoUri);
|
ourLog.info("Connecting to : {}", echoUri);
|
||||||
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
|
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
|
||||||
@@ -154,42 +152,15 @@ public class ExampleServerR4IT {
|
|||||||
return ourClient.search().forResource(Subscription.class).where(Subscription.STATUS.exactly().code("active")).cacheControl(new CacheControlDirective().setNoCache(true)).returnBundle(Bundle.class).execute().getEntry().size();
|
return ourClient.search().forResource(Subscription.class).where(Subscription.STATUS.exactly().code("active")).cacheControl(new CacheControlDirective().setNoCache(true)).returnBundle(Bundle.class).execute().getEntry().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void afterClass() throws Exception {
|
|
||||||
ourServer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeEach
|
||||||
public static void beforeClass() throws Exception {
|
void beforeEach() {
|
||||||
String path = Paths.get("").toAbsolutePath().toString();
|
|
||||||
|
|
||||||
ourLog.info("Project base path is: {}", path);
|
|
||||||
|
|
||||||
ourServer = new Server(0);
|
|
||||||
|
|
||||||
WebAppContext webAppContext = new WebAppContext();
|
|
||||||
webAppContext.setContextPath("/hapi-fhir-jpaserver");
|
|
||||||
webAppContext.setDisplayName("HAPI FHIR");
|
|
||||||
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
|
|
||||||
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
|
|
||||||
webAppContext.setParentLoaderPriority(true);
|
|
||||||
|
|
||||||
ourServer.setHandler(webAppContext);
|
|
||||||
ourServer.start();
|
|
||||||
|
|
||||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
|
||||||
|
|
||||||
|
ourCtx = FhirContext.forR4();
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
String ourServerBase = HapiProperties.getServerAddress();
|
String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
|
||||||
ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
|
|
||||||
|
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) throws Exception {
|
|
||||||
ourPort = 8080;
|
|
||||||
beforeClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package ca.uhn.fhir.jpa.starter;
|
package ca.uhn.fhir.jpa.starter;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.util.TestUtil.waitForSize;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
@@ -7,9 +11,9 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
import java.net.URI;
|
||||||
import org.eclipse.jetty.server.Server;
|
import java.util.concurrent.Future;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
@@ -20,38 +24,34 @@ import org.hl7.fhir.r5.model.Observation;
|
|||||||
import org.hl7.fhir.r5.model.Patient;
|
import org.hl7.fhir.r5.model.Patient;
|
||||||
import org.hl7.fhir.r5.model.Subscription;
|
import org.hl7.fhir.r5.model.Subscription;
|
||||||
import org.hl7.fhir.r5.model.SubscriptionTopic;
|
import org.hl7.fhir.r5.model.SubscriptionTopic;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
import java.net.URI;
|
@ExtendWith(SpringExtension.class)
|
||||||
import java.nio.file.Paths;
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
|
||||||
import java.util.concurrent.Future;
|
{
|
||||||
import java.util.concurrent.TimeUnit;
|
"spring.batch.job.enabled=false",
|
||||||
|
"spring.profiles.active=r5",
|
||||||
import static ca.uhn.fhir.util.TestUtil.waitForSize;
|
"spring.datasource.url=jdbc:h2:mem:dbr5",
|
||||||
import static org.awaitility.Awaitility.await;
|
"hapi.fhir.subscription.websocket_enabled=true"
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
})
|
||||||
|
|
||||||
public class ExampleServerR5IT {
|
public class ExampleServerR5IT {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerR5IT.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
|
||||||
private static IGenericClient ourClient;
|
private IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx;
|
private FhirContext ourCtx;
|
||||||
private static int ourPort;
|
|
||||||
private static Server ourServer;
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
static {
|
|
||||||
HapiProperties.forceReload();
|
|
||||||
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr5");
|
|
||||||
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R5");
|
|
||||||
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
|
|
||||||
ourCtx = FhirContext.forR5();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndRead() {
|
public void testCreateAndRead() {
|
||||||
ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
|
|
||||||
String methodName = "testCreateResourceConditional";
|
String methodName = "testCreateResourceConditional";
|
||||||
|
|
||||||
Patient pt = new Patient();
|
Patient pt = new Patient();
|
||||||
@@ -97,7 +97,7 @@ public class ExampleServerR5IT {
|
|||||||
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
|
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
|
||||||
|
|
||||||
myWebSocketClient.start();
|
myWebSocketClient.start();
|
||||||
URI echoUri = new URI("ws://localhost:" + ourPort + "/hapi-fhir-jpaserver/websocket");
|
URI echoUri = new URI("ws://localhost:" + port + "/hapi-fhir-jpaserver/websocket");
|
||||||
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
ClientUpgradeRequest request = new ClientUpgradeRequest();
|
||||||
ourLog.info("Connecting to : {}", echoUri);
|
ourLog.info("Connecting to : {}", echoUri);
|
||||||
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
|
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
|
||||||
@@ -123,41 +123,14 @@ public class ExampleServerR5IT {
|
|||||||
ourClient.delete().resourceById(mySubscriptionId).execute();
|
ourClient.delete().resourceById(mySubscriptionId).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
@BeforeEach
|
||||||
public static void afterClass() throws Exception {
|
void beforeEach() {
|
||||||
ourServer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void beforeClass() throws Exception {
|
|
||||||
String path = Paths.get("").toAbsolutePath().toString();
|
|
||||||
|
|
||||||
ourLog.info("Project base path is: {}", path);
|
|
||||||
|
|
||||||
ourServer = new Server(0);
|
|
||||||
|
|
||||||
WebAppContext webAppContext = new WebAppContext();
|
|
||||||
webAppContext.setContextPath("/hapi-fhir-jpaserver");
|
|
||||||
webAppContext.setDisplayName("HAPI FHIR");
|
|
||||||
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
|
|
||||||
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
|
|
||||||
webAppContext.setParentLoaderPriority(true);
|
|
||||||
|
|
||||||
ourServer.setHandler(webAppContext);
|
|
||||||
ourServer.start();
|
|
||||||
|
|
||||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
|
||||||
|
|
||||||
|
ourCtx = FhirContext.forR5();
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
|
String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
|
||||||
|
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) throws Exception {
|
|
||||||
ourPort = 8080;
|
|
||||||
beforeClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,44 +7,42 @@ import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
|||||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.UrlTenantSelectionInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.UrlTenantSelectionInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
import org.hl7.fhir.r4.model.*;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
|
||||||
import org.hl7.fhir.r4.model.CodeType;
|
|
||||||
import org.hl7.fhir.r4.model.IntegerType;
|
|
||||||
import org.hl7.fhir.r4.model.Parameters;
|
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import java.nio.file.Paths;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
|
||||||
|
{
|
||||||
|
"spring.batch.job.enabled=false",
|
||||||
|
"spring.profiles.active=r4",
|
||||||
|
"spring.datasource.url=jdbc:h2:mem:dbr4-mt",
|
||||||
|
"hapi.fhir.subscription.websocket_enabled=true",
|
||||||
|
"hapi.fhir.partitioning.partitioning_include_in_search_hashes=false"
|
||||||
|
|
||||||
|
})
|
||||||
public class MultitenantServerR4IT {
|
public class MultitenantServerR4IT {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MultitenantServerR4IT.class);
|
|
||||||
private static IGenericClient ourClient;
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
|
||||||
private static FhirContext ourCtx;
|
private IGenericClient ourClient;
|
||||||
private static int ourPort;
|
private FhirContext ourCtx;
|
||||||
private static Server ourServer;
|
|
||||||
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
private static UrlTenantSelectionInterceptor ourClientTenantInterceptor;
|
private static UrlTenantSelectionInterceptor ourClientTenantInterceptor;
|
||||||
|
|
||||||
static {
|
|
||||||
HapiProperties.forceReload();
|
|
||||||
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr4-mt");
|
|
||||||
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R4");
|
|
||||||
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
|
|
||||||
HapiProperties.setProperty(HapiProperties.PARTITIONING_ENABLED, "true");
|
|
||||||
HapiProperties.setProperty(HapiProperties.PARTITIONING_MULTITENANCY_ENABLED, "true");
|
|
||||||
ourCtx = FhirContext.forR4();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndReadInTenantA() {
|
public void testCreateAndReadInTenantA() {
|
||||||
ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
|
|
||||||
|
|
||||||
// Create tenant A
|
// Create tenant A
|
||||||
ourClientTenantInterceptor.setTenantId("DEFAULT");
|
ourClientTenantInterceptor.setTenantId("DEFAULT");
|
||||||
@@ -70,7 +68,7 @@ public class MultitenantServerR4IT {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndReadInTenantB() {
|
public void testCreateAndReadInTenantB() {
|
||||||
ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
|
|
||||||
|
|
||||||
// Create tenant A
|
// Create tenant A
|
||||||
ourClientTenantInterceptor.setTenantId("DEFAULT");
|
ourClientTenantInterceptor.setTenantId("DEFAULT");
|
||||||
@@ -94,45 +92,16 @@ public class MultitenantServerR4IT {
|
|||||||
assertEquals("Family B", pt2.getName().get(0).getFamily());
|
assertEquals("Family B", pt2.getName().get(0).getFamily());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
@BeforeEach
|
||||||
public static void afterClass() throws Exception {
|
void beforeEach() {
|
||||||
ourServer.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void beforeClass() throws Exception {
|
|
||||||
String path = Paths.get("").toAbsolutePath().toString();
|
|
||||||
|
|
||||||
ourLog.info("Project base path is: {}", path);
|
|
||||||
|
|
||||||
ourServer = new Server(0);
|
|
||||||
|
|
||||||
WebAppContext webAppContext = new WebAppContext();
|
|
||||||
webAppContext.setContextPath("/hapi-fhir-jpaserver");
|
|
||||||
webAppContext.setDisplayName("HAPI FHIR");
|
|
||||||
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
|
|
||||||
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
|
|
||||||
webAppContext.setParentLoaderPriority(true);
|
|
||||||
|
|
||||||
ourServer.setHandler(webAppContext);
|
|
||||||
ourServer.start();
|
|
||||||
|
|
||||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
|
||||||
|
|
||||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
|
||||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
|
||||||
String ourServerBase = HapiProperties.getServerAddress();
|
|
||||||
ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
|
|
||||||
|
|
||||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
|
||||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
|
||||||
|
|
||||||
ourClientTenantInterceptor = new UrlTenantSelectionInterceptor();
|
ourClientTenantInterceptor = new UrlTenantSelectionInterceptor();
|
||||||
|
ourCtx = FhirContext.forR4();
|
||||||
|
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||||
|
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||||
|
String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
|
||||||
|
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||||
|
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||||
ourClient.registerInterceptor(ourClientTenantInterceptor);
|
ourClient.registerInterceptor(ourClientTenantInterceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) throws Exception {
|
|
||||||
ourPort = 8080;
|
|
||||||
beforeClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
package ca.uhn.fhir.jpa.starter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides server ports
|
|
||||||
*/
|
|
||||||
public class RandomServerPortProvider {
|
|
||||||
|
|
||||||
private static List<Integer> ourPorts = new ArrayList<Integer>();
|
|
||||||
|
|
||||||
public static int findFreePort() {
|
|
||||||
ServerSocket server;
|
|
||||||
try {
|
|
||||||
server = new ServerSocket(0);
|
|
||||||
int port = server.getLocalPort();
|
|
||||||
ourPorts.add(port);
|
|
||||||
server.close();
|
|
||||||
Thread.sleep(500);
|
|
||||||
return port;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Integer> list() {
|
|
||||||
return ourPorts;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
104
src/test/resources/application-integrationtest.yaml
Normal file
104
src/test/resources/application-integrationtest.yaml
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: 'jdbc:h2:file:./target/database/h2'
|
||||||
|
username: sa
|
||||||
|
password: null
|
||||||
|
driverClassName: org.h2.Driver
|
||||||
|
max-active: 15
|
||||||
|
profiles:
|
||||||
|
### This is the FHIR version. Choose between, dstu2, dstu3, r4 or r5
|
||||||
|
active: r4
|
||||||
|
|
||||||
|
hapi:
|
||||||
|
fhir:
|
||||||
|
#supported_resource_types:
|
||||||
|
# - Patient
|
||||||
|
# - Observation
|
||||||
|
# allow_cascading_deletes: true
|
||||||
|
# allow_contains_searches: true
|
||||||
|
# allow_external_references: true
|
||||||
|
# allow_multiple_delete: true
|
||||||
|
# allow_override_default_search_params: true
|
||||||
|
# allow_placeholder_references: true
|
||||||
|
# auto_create_placeholder_reference_targets: false
|
||||||
|
# default_encoding: JSON
|
||||||
|
# default_pretty_print: true
|
||||||
|
# default_page_size: 20
|
||||||
|
# enable_index_missing_fields: false
|
||||||
|
# enforce_referential_integrity_on_delete: false
|
||||||
|
# enforce_referential_integrity_on_write: false
|
||||||
|
# etag_support_enabled: true
|
||||||
|
# expunge_enabled: true
|
||||||
|
# daoconfig_client_id_strategy: null
|
||||||
|
# fhirpath_interceptor_enabled: false
|
||||||
|
# filter_search_enabled: true
|
||||||
|
# graphql_enabled: true
|
||||||
|
#partitioning:
|
||||||
|
# cross_partition_reference_mode: true
|
||||||
|
# multitenancy_enabled: true
|
||||||
|
# partitioning_include_in_search_hashes: true
|
||||||
|
#cors:
|
||||||
|
# allow_Credentials: true
|
||||||
|
# Supports multiple, comma separated allowed origin entries
|
||||||
|
# cors.allowed_origin=http://localhost:8080,https://localhost:8080,https://fhirtest.uhn.ca
|
||||||
|
# allowed_origin:
|
||||||
|
# - '*'
|
||||||
|
|
||||||
|
# logger:
|
||||||
|
# error_format: 'ERROR - ${requestVerb} ${requestUrl}'
|
||||||
|
# format: >-
|
||||||
|
# Path[${servletPath}] Source[${requestHeader.x-forwarded-for}]
|
||||||
|
# Operation[${operationType} ${operationName} ${idOrResourceName}]
|
||||||
|
# UA[${requestHeader.user-agent}] Params[${requestParameters}]
|
||||||
|
# ResponseEncoding[${responseEncodingNoDefault}]
|
||||||
|
# log_exceptions: true
|
||||||
|
# name: fhirtest.access
|
||||||
|
# max_binary_size: 104857600
|
||||||
|
# max_page_size: 200
|
||||||
|
# retain_cached_searches_mins: 60
|
||||||
|
# reuse_cached_search_results_millis: 60000
|
||||||
|
tester:
|
||||||
|
-
|
||||||
|
id: home
|
||||||
|
name: Local Tester
|
||||||
|
server_address: 'http://localhost:8080/hapi-fhir-jpaserver/fhir'
|
||||||
|
refuse_to_fetch_third_party_urls: false
|
||||||
|
fhir_version: R4
|
||||||
|
-
|
||||||
|
id: global
|
||||||
|
name: Global Tester
|
||||||
|
server_address: "http://hapi.fhir.org/baseR4"
|
||||||
|
refuse_to_fetch_third_party_urls: false
|
||||||
|
fhir_version: R4
|
||||||
|
# validation:
|
||||||
|
# requests_enabled: true
|
||||||
|
# responses_enabled: true
|
||||||
|
# binary_storage_enabled: true
|
||||||
|
# bulk_export_enabled: true
|
||||||
|
# partitioning_multitenancy_enabled:
|
||||||
|
# subscription:
|
||||||
|
# resthook_enabled: false
|
||||||
|
# websocket_enabled: false
|
||||||
|
# email:
|
||||||
|
# from: some@test.com
|
||||||
|
# host: google.com
|
||||||
|
# port:
|
||||||
|
# username:
|
||||||
|
# password:
|
||||||
|
# auth:
|
||||||
|
# startTlsEnable:
|
||||||
|
# startTlsRequired:
|
||||||
|
# quitWait:
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
#elasticsearch:
|
||||||
|
# debug:
|
||||||
|
# pretty_print_json_log: false
|
||||||
|
# refresh_after_write: false
|
||||||
|
# enabled: false
|
||||||
|
# password: SomePassword
|
||||||
|
# required_index_status: YELLOW
|
||||||
|
# rest_url: 'http://localhost:9200'
|
||||||
|
# schema_management_strategy: CREATE
|
||||||
|
# username: SomeUsername
|
||||||
Reference in New Issue
Block a user