Merge branch 'master' into rel_4_2_0
This commit is contained in:
102
README.md
102
README.md
@@ -4,19 +4,19 @@ This project is a complete starter project you can use to deploy a FHIR server u
|
|||||||
|
|
||||||
Note that this project is specifically intended for end users of the HAPI FHIR JPA server module (in other words, it helps you implement HAPI FHIR, it is not the source of the library itself). If you are looking for the main HAPI FHIR project, see here: https://github.com/jamesagnew/hapi-fhir
|
Note that this project is specifically intended for end users of the HAPI FHIR JPA server module (in other words, it helps you implement HAPI FHIR, it is not the source of the library itself). If you are looking for the main HAPI FHIR project, see here: https://github.com/jamesagnew/hapi-fhir
|
||||||
|
|
||||||
# Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
In order to use this sample, you should have:
|
In order to use this sample, you should have:
|
||||||
|
|
||||||
* [This project](https://github.com/hapifhir/hapi-fhir-jpaserver-starter) checked out. You may wish to create a GitHub Fork of the project and check that out instead so that you can customize the project and save the results to GitHub.
|
- [This project](https://github.com/hapifhir/hapi-fhir-jpaserver-starter) checked out. You may wish to create a GitHub Fork of the project and check that out instead so that you can customize the project and save the results to GitHub.
|
||||||
* Oracle Java (JDK) installed: Minimum JDK8 or newer.
|
- Oracle Java (JDK) installed: Minimum JDK8 or newer.
|
||||||
* Apache Maven build tool (newest version)
|
- Apache Maven build tool (newest version)
|
||||||
|
|
||||||
# Running Locally
|
## Running locally
|
||||||
|
|
||||||
The easiest way to run this server is to run it directly in Maven using a built-in Jetty server. To do this, change `src/main/resources/hapi.properties` `server_address` and `server.base` with the values commented out as *For Jetty, use this* and then execute the following command:
|
The easiest way to run this server is to run it directly in Maven using a built-in Jetty server. To do this, change `src/main/resources/hapi.properties` `server_address` and `server.base` with the values commented out as _For Jetty, use this_ and then execute the following command:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
mvn jetty:run
|
mvn jetty:run
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -25,30 +25,50 @@ Then, browse to the following link to use the server:
|
|||||||
[http://localhost:8080/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/)
|
[http://localhost:8080/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/)
|
||||||
|
|
||||||
If you need to run this server on a different port (using Maven), you can change the port in the run command as follows:
|
If you need to run this server on a different port (using Maven), you can change the port in the run command as follows:
|
||||||
```
|
|
||||||
|
```bash
|
||||||
mvn -Djetty.port=8888 jetty:run
|
mvn -Djetty.port=8888 jetty:run
|
||||||
```
|
```
|
||||||
|
|
||||||
And replacing 8888 with the port of your choice.
|
And replacing 8888 with the port of your choice.
|
||||||
|
|
||||||
# Configuration
|
## Configurations
|
||||||
|
|
||||||
Much of this HAPI starter project can be configured using the properties file in *src/main/resources/hapi.properties*. By default, this starter project is configured to use Derby as the database.
|
Much of this HAPI starter project can be configured using the properties file in _src/main/resources/hapi.properties_. By default, this starter project is configured to use Derby as the database.
|
||||||
|
|
||||||
## MySql
|
### MySql configuration
|
||||||
|
|
||||||
To configure the starter app to use MySQL, instead of the default Derby, update the hapi.properties file to have the following:
|
To configure the starter app to use MySQL, instead of the default Derby, update the hapi.properties file to have the following:
|
||||||
|
|
||||||
* datasource.driver=com.mysql.jdbc.Driver
|
- datasource.driver=com.mysql.jdbc.Driver
|
||||||
* datasource.url=jdbc:mysql://localhost:3306/hapi_dstu3
|
- datasource.url=jdbc:mysql://localhost:3306/hapi_dstu3
|
||||||
* hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
|
- hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
|
||||||
* datasource.username=admin
|
- datasource.username=admin
|
||||||
* datasource.password=admin
|
- datasource.password=admin
|
||||||
|
|
||||||
Because the integration tests within the project rely on the default Derby database configuration, it is important to either explicity skip the integration tests during the build process, i.e., `mvn install -DskipTests`, or delete the tests altogether. Failure to skip or delete the tests once you've configured MySQL for the datasource.driver, datasource.url, and hibernate.dialect as outlined above will result in build errors and compilation failure.
|
### PostgreSQL configuration
|
||||||
|
|
||||||
It is important to use MySQL5Dialect when using MySQL version 5+.
|
To configure the starter app to use PostgreSQL, instead of the default Derby, update the hapi.properties file to have the following:
|
||||||
|
|
||||||
# Customizing The Web Testpage UI
|
- datasource.driver=org.postgresql.Driver
|
||||||
|
- datasource.url=jdbc:postgresql://localhost:5432/hapi_dstu3
|
||||||
|
- hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect
|
||||||
|
- datasource.username=admin
|
||||||
|
- datasource.password=admin
|
||||||
|
|
||||||
|
Because the integration tests within the project rely on the default Derby database configuration, it is important to either explicity skip the integration tests during the build process, i.e., `mvn install -DskipTests`, or delete the tests altogether. Failure to skip or delete the tests once you've configured PostgreSQL for the datasource.driver, datasource.url, and hibernate.dialect as outlined above will result in build errors and compilation failure.
|
||||||
|
|
||||||
|
It is important to use PostgreSQL95Dialect when using PostgreSQL version 10+.
|
||||||
|
|
||||||
|
## Overriding application properties
|
||||||
|
|
||||||
|
You can override the properties that are loaded into the compiled web app (.war file) making a copy of the hapi.properties file on the file system, making changes to it, and then setting the JAVA_OPTS environment variable on the tomcat server to tell hapi-jpaserver-starter where the overriding properties file is. For example:
|
||||||
|
|
||||||
|
`-Dhapi.properties=/some/custom/directory/hapi.properties`
|
||||||
|
|
||||||
|
Note: This property name and the path is case-sensitive. "-DHAPI.PROPERTIES=XXX" will not work.
|
||||||
|
|
||||||
|
## Customizing The Web Testpage UI
|
||||||
|
|
||||||
The UI that comes with this server is an exact clone of the server available at [http://hapi.fhir.org](http://hapi.fhir.org). You may skin this UI if you'd like. For example, you might change the introductory text or replace the logo with your own.
|
The UI that comes with this server is an exact clone of the server available at [http://hapi.fhir.org](http://hapi.fhir.org). You may skin this UI if you'd like. For example, you might change the introductory text or replace the logo with your own.
|
||||||
|
|
||||||
@@ -56,7 +76,7 @@ The UI is customized using [Thymeleaf](https://www.thymeleaf.org/) template file
|
|||||||
|
|
||||||
Several template files that can be customized are found in the following directory: [https://github.com/hapifhir/hapi-fhir-jpaserver-starter/tree/master/src/main/webapp/WEB-INF/templates](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/tree/master/src/main/webapp/WEB-INF/templates)
|
Several template files that can be customized are found in the following directory: [https://github.com/hapifhir/hapi-fhir-jpaserver-starter/tree/master/src/main/webapp/WEB-INF/templates](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/tree/master/src/main/webapp/WEB-INF/templates)
|
||||||
|
|
||||||
# Deploying to a Container
|
## Deploying to a Container
|
||||||
|
|
||||||
Using the Maven-Embedded Jetty method above is convenient, but it is not a good solution if you want to leave the server running in the background.
|
Using the Maven-Embedded Jetty method above is convenient, but it is not a good solution if you want to leave the server running in the background.
|
||||||
|
|
||||||
@@ -66,7 +86,7 @@ Tomcat is very popular, so it is a good choice simply because you will be able t
|
|||||||
|
|
||||||
To deploy to a container, you should first build the project:
|
To deploy to a container, you should first build the project:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
mvn clean install
|
mvn clean install
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -76,25 +96,25 @@ Again, browse to the following link to use the server (note that the port 8080 m
|
|||||||
|
|
||||||
[http://localhost:8080/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/)
|
[http://localhost:8080/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/)
|
||||||
|
|
||||||
# Deploy with docker compose
|
## Deploy with docker compose
|
||||||
|
|
||||||
Docker compose is a simple option to build and deploy container. To deploy with docker compose, you should build the project
|
Docker compose is a simple option to build and deploy container. To deploy with docker compose, you should build the project
|
||||||
with ```mvn clean install``` and then bring up the containers with ```docker-compose up -d --build```. The server can be
|
with `mvn clean install` and then bring up the containers with `docker-compose up -d --build`. The server can be
|
||||||
reached at http://localhost:8080/hapi-fhir-jpaserver/.
|
reached at http://localhost:8080/hapi-fhir-jpaserver/.
|
||||||
|
|
||||||
In order to use another port, change the `ports` parameter
|
In order to use another port, change the `ports` parameter
|
||||||
inside ``docker-compose.yml`` to ```8888:8080```, where 8888 is a port of your choice.
|
inside `docker-compose.yml` to `8888:8080`, where 8888 is a port of your choice.
|
||||||
|
|
||||||
The docker compose set also includes my MySQL database, if you choose to use MySQL instead of derby, change the following
|
The docker compose set also includes my MySQL database, if you choose to use MySQL instead of derby, change the following
|
||||||
properties in hapi.properties:
|
properties in hapi.properties:
|
||||||
|
|
||||||
* datasource.driver=com.mysql.jdbc.Driver
|
- datasource.driver=com.mysql.jdbc.Driver
|
||||||
* datasource.url=jdbc:mysql://hapi-fhir-mysql:3306/hapi
|
- datasource.url=jdbc:mysql://hapi-fhir-mysql:3306/hapi
|
||||||
* hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
|
- hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
|
||||||
* datasource.username=admin
|
- datasource.username=admin
|
||||||
* datasource.password=admin
|
- datasource.password=admin
|
||||||
|
|
||||||
# Running hapi-fhir-jpaserver-example in Tomcat from IntelliJ
|
## Running hapi-fhir-jpaserver-example in Tomcat from IntelliJ
|
||||||
|
|
||||||
Install Tomcat.
|
Install Tomcat.
|
||||||
|
|
||||||
@@ -114,7 +134,7 @@ Add a Run Configuration for running hapi-fhir-jpaserver-example under Tomcat
|
|||||||
- Uncheck the "After launch" checkbox
|
- Uncheck the "After launch" checkbox
|
||||||
- On the "Deployment" tab, click the green +
|
- On the "Deployment" tab, click the green +
|
||||||
- Select "Artifact"
|
- Select "Artifact"
|
||||||
- Select "hapi-fhir-jpaserver-example:war"
|
- Select "hapi-fhir-jpaserver-example:war"
|
||||||
- In "Application context" type /hapi
|
- In "Application context" type /hapi
|
||||||
|
|
||||||
Run the configuration.
|
Run the configuration.
|
||||||
@@ -128,17 +148,17 @@ Point your browser (or fiddler, or what have you) to `http://localhost:8080/hapi
|
|||||||
|
|
||||||
It is important to use MySQL5Dialect when using MySQL version 5+.
|
It is important to use MySQL5Dialect when using MySQL version 5+.
|
||||||
|
|
||||||
# Enabling Subscriptions
|
## Enabling Subscriptions
|
||||||
|
|
||||||
The server may be configured with subscription support by enabling properties in the [hapi.properties](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/hapi.properties) file:
|
The server may be configured with subscription support by enabling properties in the [hapi.properties](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/hapi.properties) file:
|
||||||
|
|
||||||
* `subscription.resthook.enabled` - Enables REST Hook subscriptions, where the server will make an outgoing connection to a remote REST server
|
- `subscription.resthook.enabled` - Enables REST Hook subscriptions, where the server will make an outgoing connection to a remote REST server
|
||||||
|
|
||||||
* `subscription.email.enabled` - Enables email subscriptions. Note that you must also provide the connection details for a usable SMTP server.
|
- `subscription.email.enabled` - Enables email subscriptions. Note that you must also provide the connection details for a usable SMTP server.
|
||||||
|
|
||||||
* `subscription.websocket.enabled` - Enables websocket subscriptions. With this enabled, your server will accept incoming websocket connections on the following URL (this example uses the default context path and port, you may need to tweak depending on your deployment environment): [ws://localhost:8080/hapi-fhir-jpaserver/websocket](ws://localhost:8080/hapi-fhir-jpaserver/websocket)
|
- `subscription.websocket.enabled` - Enables websocket subscriptions. With this enabled, your server will accept incoming websocket connections on the following URL (this example uses the default context path and port, you may need to tweak depending on your deployment environment): [ws://localhost:8080/hapi-fhir-jpaserver/websocket](ws://localhost:8080/hapi-fhir-jpaserver/websocket)
|
||||||
|
|
||||||
# Using ElasticSearch
|
## Using Elasticsearch
|
||||||
|
|
||||||
By default, the server will use embedded lucene indexes for terminology and fulltext indexing purposes. You can switch this to using lucene by editing the properties in [hapi.properties](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/hapi.properties)
|
By default, the server will use embedded lucene indexes for terminology and fulltext indexing purposes. You can switch this to using lucene by editing the properties in [hapi.properties](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/hapi.properties)
|
||||||
|
|
||||||
@@ -151,4 +171,4 @@ elasticsearch.username=SomeUsername
|
|||||||
elasticsearch.password=SomePassword
|
elasticsearch.password=SomePassword
|
||||||
elasticsearch.required_index_status=YELLOW
|
elasticsearch.required_index_status=YELLOW
|
||||||
elasticsearch.schema_management_strategy=CREATE
|
elasticsearch.schema_management_strategy=CREATE
|
||||||
```
|
```
|
||||||
|
|||||||
16
pom.xml
16
pom.xml
@@ -1,5 +1,5 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-jpaserver-starter</artifactId>
|
<artifactId>hapi-fhir-jpaserver-starter</artifactId>
|
||||||
@@ -36,6 +36,12 @@
|
|||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>8.0.11</version>
|
<version>8.0.11</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.2.9</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Needed for Email subscriptions -->
|
<!-- Needed for Email subscriptions -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -213,8 +219,8 @@
|
|||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-webapp</artifactId>
|
<artifactId>jetty-webapp</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
<!--
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.helger</groupId>
|
<groupId>com.helger</groupId>
|
||||||
<artifactId>ph-schematron</artifactId>
|
<artifactId>ph-schematron</artifactId>
|
||||||
|
|||||||
430
pom.xml.orig
430
pom.xml.orig
@@ -1,430 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
contents below may be removed
|
|
||||||
if you are using this file as a basis for your own project.
|
|
||||||
-->
|
|
||||||
<parent>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir</artifactId>
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<version>4.1.0</version>
|
|
||||||
=======
|
|
||||||
<version>4.0.3</version>
|
|
||||||
>>>>>>> master
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>hapi-fhir-jpaserver-starter</artifactId>
|
|
||||||
|
|
||||||
<prerequisites>
|
|
||||||
<maven>3.5.0</maven>
|
|
||||||
</prerequisites>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
|
||||||
<artifactId>websocket-api</artifactId>
|
|
||||||
<version>${jetty_version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
|
||||||
<artifactId>websocket-client</artifactId>
|
|
||||||
<version>${jetty_version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>8.0.11</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Needed for Email subscriptions -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.mail</groupId>
|
|
||||||
<artifactId>javax.mail</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.activation</groupId>
|
|
||||||
<artifactId>activation</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>javax.mail-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- This dependency includes the core HAPI-FHIR classes -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-base</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- This dependency includes the JPA server itself, which is packaged separately from the rest of HAPI FHIR -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-jcl</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- This dependency is used for the "FHIR Tester" web app overlay -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>war</type>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<classifier>classes</classifier>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- HAPI-FHIR uses Logback for logging support. The logback library is included automatically by Maven as a part of the hapi-fhir-base dependency, but you also need to include a logging library. Logback
|
|
||||||
is used here, but log4j would also be fine. -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Needed for JEE/Servlet support -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.servlet</groupId>
|
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- If you are using HAPI narrative generation, you will need to include Thymeleaf as well. Otherwise the following can be omitted. -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.thymeleaf</groupId>
|
|
||||||
<artifactId>thymeleaf</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Used for CORS support -->
|
|
||||||
<!-- Spring Web is used to deploy the server to a web container. -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- You may not need this if you are deploying to an application server which provides database connection pools itself. -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-dbcp2</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- This example uses H2 embedded database. If you are using another database such as Mysql or Oracle, you may omit the following dependencies and replace them with an appropriate database client
|
|
||||||
dependency for your database platform. -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- webjars -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars</groupId>
|
|
||||||
<artifactId>bootstrap</artifactId>
|
|
||||||
<version>3.3.7</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars</groupId>
|
|
||||||
<artifactId>Eonasdan-bootstrap-datetimepicker</artifactId>
|
|
||||||
<version>4.17.43</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars</groupId>
|
|
||||||
<artifactId>font-awesome</artifactId>
|
|
||||||
<version>5.8.2</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars.bower</groupId>
|
|
||||||
<artifactId>awesome-bootstrap-checkbox</artifactId>
|
|
||||||
<version>1.0.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars</groupId>
|
|
||||||
<artifactId>jstimezonedetect</artifactId>
|
|
||||||
<version>1.0.6</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars</groupId>
|
|
||||||
<artifactId>select2</artifactId>
|
|
||||||
<version>4.0.3</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars.bower</groupId>
|
|
||||||
<artifactId>jquery</artifactId>
|
|
||||||
<version>3.3.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.webjars.bower</groupId>
|
|
||||||
<artifactId>moment</artifactId>
|
|
||||||
<version>2.15.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- The following dependencies are only needed for automated unit tests, you do not neccesarily need them to run the example. -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-servlets</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-servlet</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
|
||||||
<artifactId>websocket-server</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-server</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-util</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-webapp</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</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
|
|
||||||
-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.interceptor</groupId>
|
|
||||||
<artifactId>javax.interceptor-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-test-utilities</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<name>HAPI FHIR JPA Server - Starter Project</name>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>oss-snapshots</id>
|
|
||||||
<snapshots>
|
|
||||||
<enabled>false</enabled>
|
|
||||||
</snapshots>
|
|
||||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
|
|
||||||
<!-- Tells Maven to name the generated WAR file as hapi-fhir-jpaserver.war -->
|
|
||||||
<finalName>hapi-fhir-jpaserver</finalName>
|
|
||||||
|
|
||||||
<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.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
|
||||||
<version>9.4.8.v20180619</version>
|
|
||||||
<configuration>
|
|
||||||
<webApp>
|
|
||||||
<contextPath>/hapi-fhir-jpaserver</contextPath>
|
|
||||||
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
|
|
||||||
</webApp>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Tell Maven which Java source version you want to use -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- The configuration here tells the WAR plugin to include the FHIR Tester overlay. You can omit it if you are not using that feature. -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestEntries>
|
|
||||||
<Build-Time>${maven.build.timestamp}</Build-Time>
|
|
||||||
</manifestEntries>
|
|
||||||
</archive>
|
|
||||||
<overlays>
|
|
||||||
<overlay>
|
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
|
||||||
<artifactId>hapi-fhir-testpage-overlay</artifactId>
|
|
||||||
</overlay>
|
|
||||||
</overlays>
|
|
||||||
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- This is to run the integration tests -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>integration-test</goal>
|
|
||||||
<goal>verify</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.basepom.maven</groupId>
|
|
||||||
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>default</id>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>check</goal>
|
|
||||||
</goals>
|
|
||||||
<inherited>true</inherited>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<failBuildInCaseOfConflict>true</failBuildInCaseOfConflict>
|
|
||||||
<checkTestClasspath>false</checkTestClasspath>
|
|
||||||
<!--
|
|
||||||
<printEqualFiles>false</printEqualFiles>
|
|
||||||
<failBuildInCaseOfDifferentContentConflict>true</failBuildInCaseOfDifferentContentConflict>
|
|
||||||
<failBuildInCaseOfEqualContentConflict>true</failBuildInCaseOfEqualContentConflict>
|
|
||||||
<failBuildInCaseOfConflict>true</failBuildInCaseOfConflict>
|
|
||||||
<checkCompileClasspath>true</checkCompileClasspath>
|
|
||||||
<checkRuntimeClasspath>false</checkRuntimeClasspath>
|
|
||||||
<skip>false</skip>
|
|
||||||
<quiet>false</quiet>
|
|
||||||
<preferLocal>true</preferLocal>
|
|
||||||
<useResultFile>true</useResultFile>
|
|
||||||
<resultFileMinClasspathCount>2</resultFileMinClasspathCount>
|
|
||||||
<resultFile>${project.build.directory}/duplicate-finder-result.xml</resultFile>
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<ignoredDependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.el</groupId>
|
|
||||||
<artifactId>javax.el-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>javax.mail-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.activation</groupId>
|
|
||||||
<artifactId>javax.activation-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.helger</groupId>
|
|
||||||
<artifactId>ph-schematron</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-logging</groupId>
|
|
||||||
<artifactId>commons-logging</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jscience</groupId>
|
|
||||||
<artifactId>jscience</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-jcl</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-jcl</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.findbugs</groupId>
|
|
||||||
<artifactId>annotations</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.derby</groupId>
|
|
||||||
<artifactId>derbyclient</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.derby</groupId>
|
|
||||||
<artifactId>derbynet</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.derby</groupId>
|
|
||||||
<artifactId>derbyclient</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.checkerframework</groupId>
|
|
||||||
<artifactId>checker-compat-qual</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</ignoredDependencies>
|
|
||||||
-->
|
|
||||||
<ignoredResourcePatterns>
|
|
||||||
<ignoredResourcePattern>.*\.txt$</ignoredResourcePattern>
|
|
||||||
<ignoredResourcePattern>.*\.html$</ignoredResourcePattern>
|
|
||||||
</ignoredResourcePatterns>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -26,174 +26,184 @@ import java.sql.Driver;
|
|||||||
@EnableTransactionManagement()
|
@EnableTransactionManagement()
|
||||||
public class FhirServerConfigCommon {
|
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 enableIndexMissingFields = HapiProperties.getEnableIndexMissingFields();
|
||||||
private Boolean autoCreatePlaceholderReferenceTargets = HapiProperties.getAutoCreatePlaceholderReferenceTargets();
|
private Boolean autoCreatePlaceholderReferenceTargets = HapiProperties.getAutoCreatePlaceholderReferenceTargets();
|
||||||
private Boolean enforceReferentialIntegrityOnWrite = HapiProperties.getEnforceReferentialIntegrityOnWrite();
|
private Boolean enforceReferentialIntegrityOnWrite = HapiProperties.getEnforceReferentialIntegrityOnWrite();
|
||||||
private Boolean enforceReferentialIntegrityOnDelete = HapiProperties.getEnforceReferentialIntegrityOnDelete();
|
private Boolean enforceReferentialIntegrityOnDelete = HapiProperties.getEnforceReferentialIntegrityOnDelete();
|
||||||
private Boolean allowContainsSearches = HapiProperties.getAllowContainsSearches();
|
private Boolean allowContainsSearches = HapiProperties.getAllowContainsSearches();
|
||||||
private Boolean allowMultipleDelete = HapiProperties.getAllowMultipleDelete();
|
private Boolean allowMultipleDelete = HapiProperties.getAllowMultipleDelete();
|
||||||
private Boolean allowExternalReferences = HapiProperties.getAllowExternalReferences();
|
private Boolean allowExternalReferences = HapiProperties.getAllowExternalReferences();
|
||||||
private Boolean expungeEnabled = HapiProperties.getExpungeEnabled();
|
private Boolean expungeEnabled = HapiProperties.getExpungeEnabled();
|
||||||
private Boolean allowPlaceholderReferences = HapiProperties.getAllowPlaceholderReferences();
|
private Boolean allowPlaceholderReferences = HapiProperties.getAllowPlaceholderReferences();
|
||||||
private Boolean subscriptionRestHookEnabled = HapiProperties.getSubscriptionRestHookEnabled();
|
private Boolean subscriptionRestHookEnabled = HapiProperties.getSubscriptionRestHookEnabled();
|
||||||
private Boolean subscriptionEmailEnabled = HapiProperties.getSubscriptionEmailEnabled();
|
private Boolean subscriptionEmailEnabled = HapiProperties.getSubscriptionEmailEnabled();
|
||||||
private Boolean allowOverrideDefaultSearchParams = HapiProperties.getAllowOverrideDefaultSearchParams();
|
private Boolean allowOverrideDefaultSearchParams = HapiProperties.getAllowOverrideDefaultSearchParams();
|
||||||
private String emailFrom = HapiProperties.getEmailFrom();
|
private String emailFrom = HapiProperties.getEmailFrom();
|
||||||
private Boolean emailEnabled = HapiProperties.getEmailEnabled();
|
private Boolean emailEnabled = HapiProperties.getEmailEnabled();
|
||||||
private String emailHost = HapiProperties.getEmailHost();
|
private String emailHost = HapiProperties.getEmailHost();
|
||||||
private Integer emailPort = HapiProperties.getEmailPort();
|
private Integer emailPort = HapiProperties.getEmailPort();
|
||||||
private String emailUsername = HapiProperties.getEmailUsername();
|
private String emailUsername = HapiProperties.getEmailUsername();
|
||||||
private String emailPassword = HapiProperties.getEmailPassword();
|
private String emailPassword = HapiProperties.getEmailPassword();
|
||||||
@Autowired
|
private Boolean emailAuth = HapiProperties.getEmailAuth();
|
||||||
private SubscriptionDeliveryHandlerFactory mySubscriptionDeliveryHandlerFactory;
|
private Boolean emailStartTlsEnable = HapiProperties.getEmailStartTlsEnable();
|
||||||
|
private Boolean emailStartTlsRequired = HapiProperties.getEmailStartTlsRequired();
|
||||||
|
private Boolean emailQuitWait = HapiProperties.getEmailQuitWait();
|
||||||
|
|
||||||
public FhirServerConfigCommon() {
|
@Autowired
|
||||||
ourLog.info("Server configured to " + (this.allowContainsSearches ? "allow" : "deny") + " contains searches");
|
private SubscriptionDeliveryHandlerFactory mySubscriptionDeliveryHandlerFactory;
|
||||||
ourLog.info("Server configured to " + (this.allowMultipleDelete ? "allow" : "deny") + " multiple deletes");
|
|
||||||
ourLog.info("Server configured to " + (this.allowExternalReferences ? "allow" : "deny") + " external references");
|
|
||||||
ourLog.info("Server configured to " + (this.expungeEnabled ? "enable" : "disable") + " expunges");
|
|
||||||
ourLog.info("Server configured to " + (this.allowPlaceholderReferences ? "allow" : "deny") + " placeholder references");
|
|
||||||
ourLog.info("Server configured to " + (this.allowOverrideDefaultSearchParams ? "allow" : "deny") + " overriding default search params");
|
|
||||||
|
|
||||||
if (this.emailEnabled) {
|
public FhirServerConfigCommon() {
|
||||||
ourLog.info("Server is configured to enable email with host '" + this.emailHost + "' and port " + this.emailPort.toString());
|
ourLog.info("Server configured to " + (this.allowContainsSearches ? "allow" : "deny") + " contains searches");
|
||||||
ourLog.info("Server will use '" + this.emailFrom + "' as the from email address");
|
ourLog.info("Server configured to " + (this.allowMultipleDelete ? "allow" : "deny") + " multiple deletes");
|
||||||
|
ourLog.info("Server configured to " + (this.allowExternalReferences ? "allow" : "deny") + " external references");
|
||||||
|
ourLog.info("Server configured to " + (this.expungeEnabled ? "enable" : "disable") + " expunges");
|
||||||
|
ourLog.info("Server configured to " + (this.allowPlaceholderReferences ? "allow" : "deny") + " placeholder references");
|
||||||
|
ourLog.info("Server configured to " + (this.allowOverrideDefaultSearchParams ? "allow" : "deny") + " overriding default search params");
|
||||||
|
|
||||||
if (this.emailUsername != null && this.emailUsername.length() > 0) {
|
if (this.emailEnabled) {
|
||||||
ourLog.info("Server is configured to use username '" + this.emailUsername + "' for email");
|
ourLog.info("Server is configured to enable email with host '" + this.emailHost + "' and port " + this.emailPort.toString());
|
||||||
}
|
ourLog.info("Server will use '" + this.emailFrom + "' as the from email address");
|
||||||
|
|
||||||
if (this.emailPassword != null && this.emailPassword.length() > 0) {
|
if (this.emailUsername != null && this.emailUsername.length() > 0) {
|
||||||
ourLog.info("Server is configured to use a password for email");
|
ourLog.info("Server is configured to use username '" + this.emailUsername + "' for email");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this.subscriptionRestHookEnabled) {
|
if (this.emailPassword != null && this.emailPassword.length() > 0) {
|
||||||
ourLog.info("REST-hook subscriptions enabled");
|
ourLog.info("Server is configured to use a password for email");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.subscriptionEmailEnabled) {
|
|
||||||
ourLog.info("Email subscriptions enabled");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (this.subscriptionRestHookEnabled) {
|
||||||
* Configure FHIR properties around the the JPA server via this bean
|
ourLog.info("REST-hook subscriptions enabled");
|
||||||
*/
|
|
||||||
@Bean()
|
|
||||||
public DaoConfig daoConfig() {
|
|
||||||
DaoConfig retVal = new DaoConfig();
|
|
||||||
|
|
||||||
retVal.setIndexMissingFields(this.enableIndexMissingFields ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
|
|
||||||
retVal.setAutoCreatePlaceholderReferenceTargets(this.autoCreatePlaceholderReferenceTargets);
|
|
||||||
retVal.setEnforceReferentialIntegrityOnWrite(this.enforceReferentialIntegrityOnWrite);
|
|
||||||
retVal.setEnforceReferentialIntegrityOnDelete(this.enforceReferentialIntegrityOnDelete);
|
|
||||||
retVal.setAllowContainsSearches(this.allowContainsSearches);
|
|
||||||
retVal.setAllowMultipleDelete(this.allowMultipleDelete);
|
|
||||||
retVal.setAllowExternalReferences(this.allowExternalReferences);
|
|
||||||
retVal.setExpungeEnabled(this.expungeEnabled);
|
|
||||||
retVal.setAutoCreatePlaceholderReferenceTargets(this.allowPlaceholderReferences);
|
|
||||||
retVal.setEmailFromAddress(this.emailFrom);
|
|
||||||
|
|
||||||
Integer maxFetchSize = HapiProperties.getMaximumFetchSize();
|
|
||||||
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
|
|
||||||
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
|
|
||||||
|
|
||||||
Long reuseCachedSearchResultsMillis = HapiProperties.getReuseCachedSearchResultsMillis();
|
|
||||||
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
|
|
||||||
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
|
|
||||||
|
|
||||||
Long retainCachedSearchesMinutes = HapiProperties.getExpireSearchResultsAfterMins();
|
|
||||||
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
|
|
||||||
|
|
||||||
// Subscriptions are enabled by channel type
|
|
||||||
if (HapiProperties.getSubscriptionRestHookEnabled()) {
|
|
||||||
ourLog.info("Enabling REST-hook subscriptions");
|
|
||||||
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
|
||||||
}
|
|
||||||
if (HapiProperties.getSubscriptionEmailEnabled()) {
|
|
||||||
ourLog.info("Enabling email subscriptions");
|
|
||||||
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
|
||||||
}
|
|
||||||
if (HapiProperties.getSubscriptionWebsocketEnabled()) {
|
|
||||||
ourLog.info("Enabling websocket subscriptions");
|
|
||||||
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.WEBSOCKET);
|
|
||||||
}
|
|
||||||
|
|
||||||
retVal.setFilterParameterEnabled(HapiProperties.getFilterSearchEnabled());
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
if (this.subscriptionEmailEnabled) {
|
||||||
public ModelConfig modelConfig() {
|
ourLog.info("Email subscriptions enabled");
|
||||||
ModelConfig modelConfig = new ModelConfig();
|
}
|
||||||
modelConfig.setAllowContainsSearches(this.allowContainsSearches);
|
}
|
||||||
modelConfig.setAllowExternalReferences(this.allowExternalReferences);
|
|
||||||
modelConfig.setDefaultSearchParamsCanBeOverridden(this.allowOverrideDefaultSearchParams);
|
|
||||||
modelConfig.setEmailFromAddress(this.emailFrom);
|
|
||||||
|
|
||||||
// You can enable these if you want to support Subscriptions from your server
|
/**
|
||||||
if (this.subscriptionRestHookEnabled) {
|
* Configure FHIR properties around the the JPA server via this bean
|
||||||
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
*/
|
||||||
}
|
@Bean()
|
||||||
|
public DaoConfig daoConfig() {
|
||||||
|
DaoConfig retVal = new DaoConfig();
|
||||||
|
|
||||||
if (this.subscriptionEmailEnabled) {
|
retVal.setIndexMissingFields(this.enableIndexMissingFields ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
|
||||||
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
retVal.setAutoCreatePlaceholderReferenceTargets(this.autoCreatePlaceholderReferenceTargets);
|
||||||
}
|
retVal.setEnforceReferentialIntegrityOnWrite(this.enforceReferentialIntegrityOnWrite);
|
||||||
|
retVal.setEnforceReferentialIntegrityOnDelete(this.enforceReferentialIntegrityOnDelete);
|
||||||
|
retVal.setAllowContainsSearches(this.allowContainsSearches);
|
||||||
|
retVal.setAllowMultipleDelete(this.allowMultipleDelete);
|
||||||
|
retVal.setAllowExternalReferences(this.allowExternalReferences);
|
||||||
|
retVal.setExpungeEnabled(this.expungeEnabled);
|
||||||
|
retVal.setAutoCreatePlaceholderReferenceTargets(this.allowPlaceholderReferences);
|
||||||
|
retVal.setEmailFromAddress(this.emailFrom);
|
||||||
|
|
||||||
return modelConfig;
|
Integer maxFetchSize = HapiProperties.getMaximumFetchSize();
|
||||||
|
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
|
||||||
|
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
|
||||||
|
|
||||||
|
Long reuseCachedSearchResultsMillis = HapiProperties.getReuseCachedSearchResultsMillis();
|
||||||
|
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
|
||||||
|
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
|
||||||
|
|
||||||
|
Long retainCachedSearchesMinutes = HapiProperties.getExpireSearchResultsAfterMins();
|
||||||
|
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
|
||||||
|
|
||||||
|
// Subscriptions are enabled by channel type
|
||||||
|
if (HapiProperties.getSubscriptionRestHookEnabled()) {
|
||||||
|
ourLog.info("Enabling REST-hook subscriptions");
|
||||||
|
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
||||||
|
}
|
||||||
|
if (HapiProperties.getSubscriptionEmailEnabled()) {
|
||||||
|
ourLog.info("Enabling email subscriptions");
|
||||||
|
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
||||||
|
}
|
||||||
|
if (HapiProperties.getSubscriptionWebsocketEnabled()) {
|
||||||
|
ourLog.info("Enabling websocket subscriptions");
|
||||||
|
retVal.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.WEBSOCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
retVal.setFilterParameterEnabled(HapiProperties.getFilterSearchEnabled());
|
||||||
* The following bean configures the database connection. The 'url' property value of "jdbc:derby:directory:jpaserver_derby_files;create=true" indicates that the server should save resources in a
|
|
||||||
* directory called "jpaserver_derby_files".
|
return retVal;
|
||||||
* <p>
|
}
|
||||||
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
|
||||||
*/
|
@Bean
|
||||||
@Bean(destroyMethod = "close")
|
public ModelConfig modelConfig() {
|
||||||
public BasicDataSource dataSource() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
ModelConfig modelConfig = new ModelConfig();
|
||||||
BasicDataSource retVal = new BasicDataSource();
|
modelConfig.setAllowContainsSearches(this.allowContainsSearches);
|
||||||
Driver driver = (Driver) Class.forName(HapiProperties.getDataSourceDriver()).getConstructor().newInstance();
|
modelConfig.setAllowExternalReferences(this.allowExternalReferences);
|
||||||
retVal.setDriver(driver);
|
modelConfig.setDefaultSearchParamsCanBeOverridden(this.allowOverrideDefaultSearchParams);
|
||||||
retVal.setUrl(HapiProperties.getDataSourceUrl());
|
modelConfig.setEmailFromAddress(this.emailFrom);
|
||||||
retVal.setUsername(HapiProperties.getDataSourceUsername());
|
|
||||||
retVal.setPassword(HapiProperties.getDataSourcePassword());
|
// You can enable these if you want to support Subscriptions from your server
|
||||||
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
|
if (this.subscriptionRestHookEnabled) {
|
||||||
return retVal;
|
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Lazy
|
if (this.subscriptionEmailEnabled) {
|
||||||
@Bean
|
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
|
||||||
public IBinaryStorageSvc binaryStorageSvc() {
|
|
||||||
DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
|
|
||||||
|
|
||||||
if (HapiProperties.getMaxBinarySize() != null) {
|
|
||||||
binaryStorageSvc.setMaximumBinarySize(HapiProperties.getMaxBinarySize());
|
|
||||||
}
|
|
||||||
|
|
||||||
return binaryStorageSvc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean()
|
return modelConfig;
|
||||||
public IEmailSender emailSender() {
|
}
|
||||||
if (this.emailEnabled) {
|
|
||||||
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
|
||||||
|
|
||||||
retVal.setSmtpServerHostname(this.emailHost);
|
/**
|
||||||
retVal.setSmtpServerPort(this.emailPort);
|
* The following bean configures the database connection. The 'url' property value of "jdbc:derby:directory:jpaserver_derby_files;create=true" indicates that the server should save resources in a
|
||||||
retVal.setSmtpServerUsername(this.emailUsername);
|
* directory called "jpaserver_derby_files".
|
||||||
retVal.setSmtpServerPassword(this.emailPassword);
|
* <p>
|
||||||
|
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
||||||
|
*/
|
||||||
|
@Bean(destroyMethod = "close")
|
||||||
|
public BasicDataSource dataSource() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||||
|
BasicDataSource retVal = new BasicDataSource();
|
||||||
|
Driver driver = (Driver) Class.forName(HapiProperties.getDataSourceDriver()).getConstructor().newInstance();
|
||||||
|
retVal.setDriver(driver);
|
||||||
|
retVal.setUrl(HapiProperties.getDataSourceUrl());
|
||||||
|
retVal.setUsername(HapiProperties.getDataSourceUsername());
|
||||||
|
retVal.setPassword(HapiProperties.getDataSourcePassword());
|
||||||
|
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
Validate.notNull(mySubscriptionDeliveryHandlerFactory, "No subscription delivery handler");
|
@Lazy
|
||||||
mySubscriptionDeliveryHandlerFactory.setEmailSender(retVal);
|
@Bean
|
||||||
|
public IBinaryStorageSvc binaryStorageSvc() {
|
||||||
|
DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
|
||||||
|
|
||||||
|
if (HapiProperties.getMaxBinarySize() != null) {
|
||||||
return retVal;
|
binaryStorageSvc.setMaximumBinarySize(HapiProperties.getMaxBinarySize());
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return binaryStorageSvc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean()
|
||||||
|
public IEmailSender emailSender() {
|
||||||
|
if (this.emailEnabled) {
|
||||||
|
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
||||||
|
|
||||||
|
retVal.setSmtpServerHostname(this.emailHost);
|
||||||
|
retVal.setSmtpServerPort(this.emailPort);
|
||||||
|
retVal.setSmtpServerUsername(this.emailUsername);
|
||||||
|
retVal.setSmtpServerPassword(this.emailPassword);
|
||||||
|
// TODO KHS add these when HAPI 4.2.0 is released
|
||||||
|
// retVal.setAuth(this.emailAuth);
|
||||||
|
// retVal.setStartTlsEnable(this.emailStartTlsEnable);
|
||||||
|
// retVal.setStartTlsRequired(this.emailStartTlsRequired);
|
||||||
|
// retVal.setQuitWait(this.emailQuitWait);
|
||||||
|
|
||||||
|
Validate.notNull(mySubscriptionDeliveryHandlerFactory, "No subscription delivery handler");
|
||||||
|
mySubscriptionDeliveryHandlerFactory.setEmailSender(retVal);
|
||||||
|
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ import javax.annotation.Nonnull;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
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 {
|
public class HapiProperties {
|
||||||
static final String ENABLE_INDEX_MISSING_FIELDS = "enable_index_missing_fields";
|
static final String ENABLE_INDEX_MISSING_FIELDS = "enable_index_missing_fields";
|
||||||
@@ -102,7 +105,7 @@ public class HapiProperties {
|
|||||||
builder.setRestUrl(getProperty("elasticsearch.rest_url"));
|
builder.setRestUrl(getProperty("elasticsearch.rest_url"));
|
||||||
builder.setUsername(getProperty("elasticsearch.username"));
|
builder.setUsername(getProperty("elasticsearch.username"));
|
||||||
builder.setPassword(getProperty("elasticsearch.password"));
|
builder.setPassword(getProperty("elasticsearch.password"));
|
||||||
builder.setIndexSchemaManagementStrategy(getPropertyEnum("elasticsearch.schema_management_strateg", IndexSchemaManagementStrategy.class, IndexSchemaManagementStrategy.CREATE));
|
builder.setIndexSchemaManagementStrategy(getPropertyEnum("elasticsearch.schema_management_strategy", IndexSchemaManagementStrategy.class, IndexSchemaManagementStrategy.CREATE));
|
||||||
builder.setDebugRefreshAfterWrite(getPropertyBoolean("elasticsearch.debug.refresh_after_write", false));
|
builder.setDebugRefreshAfterWrite(getPropertyBoolean("elasticsearch.debug.refresh_after_write", false));
|
||||||
builder.setDebugPrettyPrintJsonLog(getPropertyBoolean("elasticsearch.debug.pretty_print_json_log", false));
|
builder.setDebugPrettyPrintJsonLog(getPropertyBoolean("elasticsearch.debug.pretty_print_json_log", false));
|
||||||
builder.apply(retVal);
|
builder.apply(retVal);
|
||||||
@@ -160,24 +163,28 @@ public class HapiProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String getProperty(String propertyName) {
|
private static String getProperty(String propertyName) {
|
||||||
Properties properties = HapiProperties.getProperties();
|
String env = "HAPI_" + propertyName.toUpperCase(Locale.US);
|
||||||
|
env = env.replace(".", "_");
|
||||||
|
env = env.replace("-", "_");
|
||||||
|
|
||||||
if (properties != null) {
|
String propertyValue = System.getenv(env);
|
||||||
return properties.getProperty(propertyName);
|
if (propertyValue != null) {
|
||||||
|
return propertyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
Properties properties = HapiProperties.getProperties();
|
||||||
|
if (properties != null) {
|
||||||
|
propertyValue = properties.getProperty(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return propertyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getProperty(String propertyName, String defaultValue) {
|
private static String getProperty(String propertyName, String defaultValue) {
|
||||||
Properties properties = HapiProperties.getProperties();
|
String value = getProperty(propertyName);
|
||||||
|
|
||||||
if (properties != null) {
|
if (value != null && value.length() > 0) {
|
||||||
String value = properties.getProperty(propertyName);
|
return value;
|
||||||
|
|
||||||
if (value != null && value.length() > 0) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@@ -398,6 +405,23 @@ public class HapiProperties {
|
|||||||
return HapiProperties.getProperty("email.password");
|
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() {
|
public static Long getReuseCachedSearchResultsMillis() {
|
||||||
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
|
String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
|
||||||
return Long.valueOf(value);
|
return Long.valueOf(value);
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ elasticsearch.enabled=false
|
|||||||
elasticsearch.rest_url=http://localhost:9200
|
elasticsearch.rest_url=http://localhost:9200
|
||||||
elasticsearch.username=SomeUsername
|
elasticsearch.username=SomeUsername
|
||||||
elasticsearch.password=SomePassword
|
elasticsearch.password=SomePassword
|
||||||
elasticsearch.rest_url=http://localhost:9200
|
|
||||||
elasticsearch.required_index_status=YELLOW
|
elasticsearch.required_index_status=YELLOW
|
||||||
elasticsearch.schema_management_strategy=CREATE
|
elasticsearch.schema_management_strategy=CREATE
|
||||||
# Immediately refresh indexes after every write. This is very bad for
|
# Immediately refresh indexes after every write. This is very bad for
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ 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.codesystems.SubscriptionChannelType;
|
|
||||||
import org.hl7.fhir.r5.model.*;
|
import org.hl7.fhir.r5.model.*;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
@@ -76,8 +75,8 @@ public class ExampleServerR5IT {
|
|||||||
|
|
||||||
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
|
||||||
channel.getType().addCoding()
|
channel.getType().addCoding()
|
||||||
.setSystem(SubscriptionChannelType.WEBSOCKET.getSystem())
|
.setSystem("http://terminology.hl7.org/CodeSystem/subscription-channel-type")
|
||||||
.setCode(SubscriptionChannelType.WEBSOCKET.toCode());
|
.setCode("websocket");
|
||||||
channel.getPayload().setContentType("application/json");
|
channel.getPayload().setContentType("application/json");
|
||||||
subscription.setChannel(channel);
|
subscription.setChannel(channel);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user