Merge pull request #20 from hapifhir/ja_get_websockets_working

Add support for websockets
This commit is contained in:
Sean McIlvenna
2019-05-01 13:38:05 -07:00
committed by GitHub
10 changed files with 44 additions and 56 deletions

View File

@@ -20,7 +20,7 @@ mvn jetty:run
Then, browse to the following link to use the server: Then, browse to the following link to use the server:
[http://localhost:8080/](http://localhost:8080/) [http://localhost:8080/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/)
# Deploying to a Container # Deploying to a Container
@@ -74,3 +74,14 @@ FLUSH PRIVILEGES;
* hibernate.dialect=org.hibernate.dialect.MySQL5Dialect * hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
It is important to use MySQL5Dialect when using MySQL version 5+. It is important to use MySQL5Dialect when using MySQL version 5+.
# 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:
* `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.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)

12
pom.xml
View File

@@ -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>3.7.0</version> <version>3.8.0-SNAPSHOT</version>
</parent> </parent>
<groupId>ca.uhn.hapi.fhir.demo</groupId> <groupId>ca.uhn.hapi.fhir.demo</groupId>
@@ -134,14 +134,6 @@
<groupId>org.apache.derby</groupId> <groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId> <artifactId>derby</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbynet</artifactId>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
</dependency>
<!-- The following dependencies are only needed for automated unit tests, you do not neccesarily need them to run the example. --> <!-- The following dependencies are only needed for automated unit tests, you do not neccesarily need them to run the example. -->
<dependency> <dependency>
@@ -209,7 +201,7 @@
<version>9.4.8.v20180619</version> <version>9.4.8.v20180619</version>
<configuration> <configuration>
<webApp> <webApp>
<contextPath>/</contextPath> <contextPath>/hapi-fhir-jpaserver</contextPath>
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames> <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
</webApp> </webApp>
</configuration> </configuration>

View File

@@ -35,7 +35,7 @@ public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName(HapiProperties.getPersistenceUnitName()); retVal.setPersistenceUnitName("HAPI_PU");
try { try {
retVal.setDataSource(myDataSource); retVal.setDataSource(myDataSource);

View File

@@ -35,7 +35,7 @@ public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName(HapiProperties.getPersistenceUnitName()); retVal.setPersistenceUnitName("HAPI_PU");
try { try {
retVal.setDataSource(myDataSource); retVal.setDataSource(myDataSource);

View File

@@ -35,7 +35,7 @@ public class FhirServerConfigR4 extends BaseJavaConfigR4 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName(HapiProperties.getPersistenceUnitName()); retVal.setPersistenceUnitName("HAPI_PU");
try { try {
retVal.setDataSource(myDataSource); retVal.setDataSource(myDataSource);

View File

@@ -32,9 +32,7 @@ public class HapiProperties {
static final String LOGGER_NAME = "logger.name"; static final String LOGGER_NAME = "logger.name";
static final String MAX_FETCH_SIZE = "max_fetch_size"; static final String MAX_FETCH_SIZE = "max_fetch_size";
static final String MAX_PAGE_SIZE = "max_page_size"; static final String MAX_PAGE_SIZE = "max_page_size";
static final String PERSISTENCE_UNIT_NAME = "persistence_unit_name";
static final String SERVER_ADDRESS = "server_address"; static final String SERVER_ADDRESS = "server_address";
static final String SERVER_BASE = "server.base";
static final String SERVER_ID = "server.id"; static final String SERVER_ID = "server.id";
static final String SERVER_NAME = "server.name"; static final String SERVER_NAME = "server.name";
static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled"; static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled";
@@ -201,10 +199,6 @@ public class HapiProperties {
return HapiProperties.getIntegerProperty(MAX_FETCH_SIZE, Integer.MAX_VALUE); return HapiProperties.getIntegerProperty(MAX_FETCH_SIZE, Integer.MAX_VALUE);
} }
public static String getPersistenceUnitName() {
return HapiProperties.getProperty(PERSISTENCE_UNIT_NAME, "HAPI_PU");
}
public static String getLoggerName() { public static String getLoggerName() {
return HapiProperties.getProperty(LOGGER_NAME, "fhirtest.access"); return HapiProperties.getProperty(LOGGER_NAME, "fhirtest.access");
} }
@@ -269,10 +263,6 @@ public class HapiProperties {
return HapiProperties.getProperty(CORS_ALLOWED_ORIGIN, "*"); return HapiProperties.getProperty(CORS_ALLOWED_ORIGIN, "*");
} }
public static String getServerBase() {
return HapiProperties.getProperty(SERVER_BASE, "/fhir");
}
public static String getServerName() { public static String getServerName() {
return HapiProperties.getProperty(SERVER_NAME, "Local Tester"); return HapiProperties.getProperty(SERVER_NAME, "Local Tester");
} }

View File

@@ -1,16 +1,18 @@
# Adjust this to set the version of FHIR supported by this server. See # Adjust this to set the version of FHIR supported by this server. See
# FhirVersionEnum for a list of available constants. # FhirVersionEnum for a list of available constants. Example values include
# DSTU2, DSTU3, R4.
fhir_version=DSTU3 fhir_version=DSTU3
# This is the address that the FHIR server will report as its own address. # 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 # If this server will be deployed (for example) to an internet accessible
# server, put the DNS name of that server here. # server, put the DNS name of that server here.
server_address=http://localhost:8080/fhir/ #
# Note that this is also the address that the hapi-fhir-testpage-overlay
# This is the context path for the FHIR endpoint. If this is changed, the # (the web UI similar to the one at http://hapi.fhir.org) will use to
# setting above should also be changed. # connect internally to the FHIR server, so this also needs to be a name
server.base=/fhir # accessible from the server itself.
server_address=http://localhost:8080/hapi-fhir-jpaserver/fhir/
default_encoding=JSON default_encoding=JSON
etag_support=ENABLED etag_support=ENABLED

View File

@@ -13,8 +13,6 @@ import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths; import java.nio.file.Paths;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -33,14 +31,13 @@ public class ExampleServerDstu2IT {
HapiProperties.forceReload(); HapiProperties.forceReload();
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU2"); HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU2");
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:derby:memory:dbr2;create=true"); HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:derby:memory:dbr2;create=true");
HapiProperties.setProperty(HapiProperties.TEST_PORT, Integer.toString(PortUtil.findFreePort()));
ourCtx = FhirContext.forDstu2(); ourCtx = FhirContext.forDstu2();
ourPort = HapiProperties.getTestPort(); ourPort = PortUtil.findFreePort();
} }
@Test @Test
public void testCreateAndRead() throws IOException { public void testCreateAndRead() {
ourLog.info("Base URL is: http://localhost:" + ourPort + HapiProperties.getServerBase()); ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
String methodName = "testCreateResourceConditional"; String methodName = "testCreateResourceConditional";
Patient pt = new Patient(); Patient pt = new Patient();
@@ -62,13 +59,10 @@ public class ExampleServerDstu2IT {
ourLog.info("Project base path is: {}", path); ourLog.info("Project base path is: {}", path);
if (ourPort == 0) {
ourPort = RandomServerPortProvider.findFreePort();
}
ourServer = new Server(ourPort); ourServer = new Server(ourPort);
WebAppContext webAppContext = new WebAppContext(); WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/"); webAppContext.setContextPath("/hapi-fhir-jpaserver");
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml"); webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter"); webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
webAppContext.setParentLoaderPriority(true); webAppContext.setParentLoaderPriority(true);
@@ -78,7 +72,7 @@ public class ExampleServerDstu2IT {
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000); ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
ourServerBase = "http://localhost:" + ourPort + HapiProperties.getServerBase(); 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));
} }

View File

@@ -44,15 +44,14 @@ public class ExampleServerDstu3IT {
HapiProperties.forceReload(); HapiProperties.forceReload();
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3"); HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3");
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:derby:memory:dbr3;create=true"); HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:derby:memory:dbr3;create=true");
HapiProperties.setProperty(HapiProperties.TEST_PORT, Integer.toString(PortUtil.findFreePort()));
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true"); HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
ourCtx = FhirContext.forDstu3(); ourCtx = FhirContext.forDstu3();
ourPort = HapiProperties.getTestPort(); ourPort = PortUtil.findFreePort();
} }
@Test @Test
public void testCreateAndRead() throws IOException { public void testCreateAndRead() {
ourLog.info("Base URL is: http://localhost:" + ourPort + HapiProperties.getServerBase()); ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
String methodName = "testCreateResourceConditional"; String methodName = "testCreateResourceConditional";
Patient pt = new Patient(); Patient pt = new Patient();
@@ -92,7 +91,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 + "/websocket"); URI echoUri = new URI("ws://localhost:" + ourPort + "/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);
@@ -138,7 +137,7 @@ public class ExampleServerDstu3IT {
ourServer = new Server(ourPort); ourServer = new Server(ourPort);
WebAppContext webAppContext = new WebAppContext(); WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/"); webAppContext.setContextPath("/hapi-fhir-jpaserver");
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml"); webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter"); webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
webAppContext.setParentLoaderPriority(true); webAppContext.setParentLoaderPriority(true);
@@ -148,7 +147,7 @@ public class ExampleServerDstu3IT {
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000); ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
ourServerBase = "http://localhost:" + ourPort + HapiProperties.getServerBase(); 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));
} }

View File

@@ -22,7 +22,6 @@ import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@@ -45,15 +44,14 @@ public class ExampleServerR4IT {
HapiProperties.forceReload(); HapiProperties.forceReload();
HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:derby:memory:dbr4;create=true"); HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:derby:memory:dbr4;create=true");
HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R4"); HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R4");
HapiProperties.setProperty(HapiProperties.TEST_PORT, Integer.toString(PortUtil.findFreePort()));
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true"); HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
ourCtx = FhirContext.forR4(); ourCtx = FhirContext.forR4();
ourPort = HapiProperties.getTestPort(); ourPort = PortUtil.findFreePort();
} }
@Test @Test
public void testCreateAndRead() throws IOException { public void testCreateAndRead() {
ourLog.info("Base URL is: http://localhost:" + ourPort + HapiProperties.getServerBase()); ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
String methodName = "testCreateResourceConditional"; String methodName = "testCreateResourceConditional";
Patient pt = new Patient(); Patient pt = new Patient();
@@ -93,7 +91,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 + "/websocket"); URI echoUri = new URI("ws://localhost:" + ourPort + "/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);
@@ -139,7 +137,7 @@ public class ExampleServerR4IT {
ourServer = new Server(ourPort); ourServer = new Server(ourPort);
WebAppContext webAppContext = new WebAppContext(); WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/"); webAppContext.setContextPath("/hapi-fhir-jpaserver");
webAppContext.setDisplayName("HAPI FHIR"); webAppContext.setDisplayName("HAPI FHIR");
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml"); webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter"); webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter");
@@ -150,7 +148,9 @@ public class ExampleServerR4IT {
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000); ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
ourServerBase = "http://localhost:" + ourPort + HapiProperties.getServerBase(); ourServerBase = HapiProperties.getServerAddress();
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));
} }