Merge pull request #12 from jjcosare/master

Docs of hapi-fhir-testpage-overlay not loading properly due to local conformance statement issue
This commit is contained in:
James Agnew
2019-03-19 10:35:32 -04:00
committed by GitHub
15 changed files with 198 additions and 136 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/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/) [http://localhost:8080/](http://localhost:8080/)
# Deploying to a Container # Deploying to a Container
@@ -40,7 +40,7 @@ This will create a file called `hapi-fhir-jpaserver.war` in your `target` direct
Again, browse to the following link to use the server (note that the port 8080 may not be correct depending on how your server is configured). Again, browse to the following link to use the server (note that the port 8080 may not be correct depending on how your server is configured).
[http://localhost:8080/hapi-fhir-jpaserver/](http://localhost:8080/hapi-fhir-jpaserver/) [http://localhost:8080/](http://localhost:8080/)
# Customizing The Web Testpage UI # Customizing The Web Testpage UI
@@ -56,10 +56,21 @@ Much of this HAPI starter project can be configured using the properties file in
## MySql ## MySql
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:
* datasource.driver=com.mysql.jdbc.Driver > Add user and database on your mysql server via mysql cli
```
CREATE USER 'hapiDbUser'@'localhost' IDENTIFIED BY 'hapiDbPass';
CREATE DATABASE hapi_dstu3;
GRANT ALL PRIVILEGES ON hapi_dstu3.* to 'hapiDbUser'@'localhost';
FLUSH PRIVILEGES;
```
> Update hapi.properties file to have the following
* datasource.driver=com.mysql.cj.jdbc.Driver
* datasource.url=jdbc:mysql://localhost:3306/hapi_dstu3 * datasource.url=jdbc:mysql://localhost:3306/hapi_dstu3
* datasource.username=hapiDbUser
* datasource.password=hapiDbPass
* 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+.

21
pom.xml
View File

@@ -24,7 +24,7 @@
<repository> <repository>
<id>oss-snapshots</id> <id>oss-snapshots</id>
<snapshots> <snapshots>
<enabled>true</enabled> <enabled>false</enabled>
</snapshots> </snapshots>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url> <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository> </repository>
@@ -111,17 +111,6 @@
</dependency> </dependency>
<!-- Used for CORS support --> <!-- Used for CORS support -->
<dependency>
<groupId>org.ebaysf.web</groupId>
<artifactId>cors-filter</artifactId>
<exclusions>
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Web is used to deploy the server to a web container. --> <!-- Spring Web is used to deploy the server to a web container. -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
@@ -207,24 +196,20 @@
<!-- Tells Maven to name the generated WAR file as hapi-fhir-jpaserver.war --> <!-- Tells Maven to name the generated WAR file as hapi-fhir-jpaserver.war -->
<finalName>hapi-fhir-jpaserver</finalName> <finalName>hapi-fhir-jpaserver</finalName>
<!-- 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. -->
<pluginManagement>
<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> <plugin>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId> <artifactId>jetty-maven-plugin</artifactId>
<version>9.4.8.v20180619</version> <version>9.4.8.v20180619</version>
<configuration> <configuration>
<webApp> <webApp>
<contextPath>/hapi-fhir-jpaserver</contextPath> <contextPath>/</contextPath>
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames> <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
</webApp> </webApp>
</configuration> </configuration>
</plugin> </plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- 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>

View File

@@ -18,7 +18,6 @@ public class FhirServerConfigR4 extends BaseJavaConfigR4 {
@Autowired @Autowired
private DataSource myDataSource; private DataSource myDataSource;
/** /**
* We override the paging provider definition so that we can customize * We override the paging provider definition so that we can customize
* 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

View File

@@ -43,6 +43,7 @@ public class FhirTesterConfig {
.withFhirVersion(HapiProperties.getFhirVersion()) .withFhirVersion(HapiProperties.getFhirVersion())
.withBaseUrl(HapiProperties.getServerAddress()) .withBaseUrl(HapiProperties.getServerAddress())
.withName(HapiProperties.getServerName()); .withName(HapiProperties.getServerName());
retVal.setRefuseToFetchThirdPartyUrls(HapiProperties.getTesterConfigRefustToFetchThirdPartyUrls());
return retVal; return retVal;
} }

View File

@@ -40,6 +40,9 @@ public class HapiProperties {
static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled"; static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled";
static final String SUBSCRIPTION_WEBSOCKET_ENABLED = "subscription.websocket.enabled"; static final String SUBSCRIPTION_WEBSOCKET_ENABLED = "subscription.websocket.enabled";
static final String TEST_PORT = "test.port"; 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 ALLOW_CONTAINS_SEARCHES = "allow_contains_searches"; 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 ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS = "allow_override_default_search_params";
static final String EMAIL_FROM = "email.from"; static final String EMAIL_FROM = "email.from";
@@ -253,6 +256,18 @@ public class HapiProperties {
return HapiProperties.getIntegerProperty(TEST_PORT, 0); return HapiProperties.getIntegerProperty(TEST_PORT, 0);
} }
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 getServerBase() { public static String getServerBase() {
return HapiProperties.getProperty(SERVER_BASE, "/fhir"); return HapiProperties.getProperty(SERVER_BASE, "/fhir");
} }

View File

@@ -4,7 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.model.interceptor.api.IInterceptorRegistry; import ca.uhn.fhir.jpa.model.interceptor.executor.InterceptorService;
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.JpaSystemProviderDstu2;
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider; import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
@@ -15,19 +15,22 @@ import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4; import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.jpa.provider.r4.TerminologyUploaderProviderR4; import ca.uhn.fhir.jpa.provider.r4.TerminologyUploaderProviderR4;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.subscription.SubscriptionActivatingInterceptor; import ca.uhn.fhir.jpa.subscription.SubscriptionInterceptorLoader;
import ca.uhn.fhir.jpa.subscription.SubscriptionMatcherInterceptor; import ca.uhn.fhir.jpa.subscription.module.interceptor.SubscriptionDebugLogInterceptor;
import ca.uhn.fhir.model.dstu2.composite.MetaDt; 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.HardcodedServerAddressStrategy; import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
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.ResponseHighlighterInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Meta; import org.hl7.fhir.dstu3.model.Meta;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class JpaRestfulServer extends RestfulServer { public class JpaRestfulServer extends RestfulServer {
@@ -45,10 +48,6 @@ public class JpaRestfulServer extends RestfulServer {
*/ */
ApplicationContext appCtx = (ApplicationContext) getServletContext().getAttribute("org.springframework.web.context.WebApplicationContext.ROOT"); ApplicationContext appCtx = (ApplicationContext) getServletContext().getAttribute("org.springframework.web.context.WebApplicationContext.ROOT");
// if (HapiProperties.getSubscriptionWebsocketEnabled()) {
// appCtx.register(WebsocketDispatcherConfig.class);
// }
/* /*
* ResourceProviders are fetched from the Spring context * ResourceProviders are fetched from the Spring context
*/ */
@@ -170,22 +169,43 @@ public class JpaRestfulServer extends RestfulServer {
registerProvider(retriggeringProvider); registerProvider(retriggeringProvider);
} }
// Define your CORS configuration. This is an example
// showing a typical setup. You should customize this
// to your specific needs
if(HapiProperties.getCorsEnabled()) {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedHeader("x-fhir-starter");
config.addAllowedHeader("Origin");
config.addAllowedHeader("Accept");
config.addAllowedHeader("X-Requested-With");
config.addAllowedHeader("Content-Type");
config.addAllowedOrigin(HapiProperties.getCorsAllowedOrigin());
config.addExposedHeader("Location");
config.addExposedHeader("Content-Location");
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
// Create the interceptor and register it
CorsInterceptor interceptor = new CorsInterceptor(config);
registerInterceptor(interceptor);
}
// 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 (HapiProperties.getSubscriptionWebsocketEnabled() ||
HapiProperties.getSubscriptionEmailEnabled() || HapiProperties.getSubscriptionEmailEnabled() ||
HapiProperties.getSubscriptionRestHookEnabled()) { HapiProperties.getSubscriptionRestHookEnabled()) {
IInterceptorRegistry interceptorRegistry = appCtx.getBean(IInterceptorRegistry.class); // Loads subscription interceptors (SubscriptionActivatingInterceptor, SubscriptionMatcherInterceptor)
// with activation of scheduled subscription
SubscriptionInterceptorLoader subscriptionInterceptorLoader = appCtx.getBean(SubscriptionInterceptorLoader.class);
subscriptionInterceptorLoader.registerInterceptors();
SubscriptionActivatingInterceptor subscriptionActivatingInterceptor = appCtx.getBean(SubscriptionActivatingInterceptor.class); // Subscription debug logging
interceptorRegistry.registerInterceptor(subscriptionActivatingInterceptor); InterceptorService interceptorService = (InterceptorService) appCtx.getBean("interceptorService");
interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor());
SubscriptionMatcherInterceptor subscriptionMatcherInterceptor = appCtx.getBean(SubscriptionMatcherInterceptor.class);
subscriptionMatcherInterceptor.start();
interceptorRegistry.registerInterceptor(subscriptionMatcherInterceptor);
} }
} }
} }

View File

@@ -6,18 +6,12 @@ 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/fhir/ server_address=http://localhost:8080/fhir/
# For Jetty, use this:
# server_address=http://localhost:8080/hapi-fhir-jpaserver/fhir/
# This is the context path for the FHIR endpoint. If this is changed, the # This is the context path for the FHIR endpoint. If this is changed, the
# setting above should also be changed. # setting above should also be changed.
server.base=/fhir server.base=/fhir
# For Jetty, use this:
# server.base=/hapi-fhir-jpaserver/fhir
default_encoding=JSON default_encoding=JSON
etag_support=ENABLED etag_support=ENABLED
default_page_size=20 default_page_size=20
@@ -53,6 +47,9 @@ hibernate.cache.use_minimal_puts=false
hibernate.search.default.directory_provider=filesystem hibernate.search.default.directory_provider=filesystem
hibernate.search.default.indexBase=target/lucenefiles hibernate.search.default.indexBase=target/lucenefiles
hibernate.search.lucene_version=LUCENE_CURRENT hibernate.search.lucene_version=LUCENE_CURRENT
tester.config.refuse_to_fetch_third_party_urls=false
cors.enabled=true
cors.allowed_origin=*
################################################## ##################################################
# Subscriptions # Subscriptions

View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head th:fragment="head">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="" />
<meta name="author" content="" />
<link rel="icon" type="image/x-icon" href="img/favicon.ico">
<script src="js/jquery-2.1.0.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" />
<link href="css/tester.css" rel="stylesheet" />
<script type="text/javascript" th:utext="'var conformance = ' + ${jsonEncodedConf} + ';'">
</script>
<script type="text/javascript" th:utext="'var resourceName = \'' + ${resourceName} + '\';'">
</script>
<link href="fa/css/font-awesome.min.css" rel="stylesheet" />
<link href="css/hapi-narrative.css" rel="stylesheet" />
<script type="text/javascript" src="js/moment-with-locales.min.js"></script>
<link href="css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<script src="js/bootstrap-datetimepicker.min.js"></script>
<link href="css/select2.css" rel="stylesheet"/>
<script src="js/select2.min.js"></script>
<script src="js/RestfulTester.js" type="text/javascript" ></script>
</head>
</html>

View File

@@ -31,74 +31,24 @@
<init-param> <init-param>
<param-name>contextConfigLocation</param-name> <param-name>contextConfigLocation</param-name>
<param-value> <param-value>
ca.uhn.fhir.jpa.starter.FhirTesterConfig, ca.uhn.fhir.jpa.starter.FhirTesterConfig
</param-value> </param-value>
</init-param> </init-param>
<load-on-startup>2</load-on-startup> <load-on-startup>2</load-on-startup>
</servlet> </servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet> <servlet>
<servlet-name>fhirServlet</servlet-name> <servlet-name>fhirServlet</servlet-name>
<servlet-class>ca.uhn.fhir.jpa.starter.JpaRestfulServer</servlet-class> <servlet-class>ca.uhn.fhir.jpa.starter.JpaRestfulServer</servlet-class>
<load-on-startup>1</load-on-startup> <load-on-startup>1</load-on-startup>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>fhirServlet</servlet-name> <servlet-name>fhirServlet</servlet-name>
<url-pattern>/fhir/*</url-pattern> <url-pattern>/fhir/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- This filters provide support for Cross Origin Resource Sharing (CORS) -->
<filter>
<filter-name>CORS Filter</filter-name>
<filter-class>org.ebaysf.web.cors.CORSFilter</filter-class>
<init-param>
<description>A comma separated list of allowed origins. Note: An '*' cannot be used for an allowed origin when using credentials.</description>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<description>A comma separated list of HTTP verbs, using which a CORS request can be made.</description>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
</init-param>
<init-param>
<description>A comma separated list of allowed headers when making a non simple CORS request.</description>
<param-name>cors.allowed.headers</param-name>
<param-value>Accept,Access-Control-Request-Headers,Access-Control-Request-Method,Cache-Control,Content-Type,Origin,Prefer,X-FHIR-Starter,X-Requested-With</param-value>
</init-param>
<init-param>
<description>A comma separated list non-standard response headers that will be exposed to XHR2 object.</description>
<param-name>cors.exposed.headers</param-name>
<param-value>Location,Content-Location</param-value>
</init-param>
<init-param>
<description>A flag that suggests if CORS is supported with cookies</description>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>A flag to control logging</description>
<param-name>cors.logging.enabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>Indicates how long (in seconds) the results of a preflight request can be cached in a preflight result cache.</description>
<param-name>cors.preflight.maxage</param-name>
<param-value>300</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app> </web-app>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

View File

@@ -15,6 +15,7 @@ import org.junit.Test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -57,13 +58,7 @@ public class ExampleServerDstu2IT {
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
/* String path = Paths.get("").toAbsolutePath().toString();
* This runs under maven, and I'm not sure how else to figure out the target directory from code..
*/
String path = ExampleServerDstu2IT.class.getClassLoader().getResource(".keep_hapi-fhir-jpaserver-starter").getPath();
path = new File(path).getParent();
path = new File(path).getParent();
path = new File(path).getParent();
ourLog.info("Project base path is: {}", path); ourLog.info("Project base path is: {}", path);

View File

@@ -1,14 +1,27 @@
package ca.uhn.fhir.jpa.starter; package ca.uhn.fhir.jpa.starter;
import static ca.uhn.fhir.util.TestUtil.waitForSize;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.nio.file.Paths;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.util.PortUtil; import ca.uhn.fhir.util.PortUtil;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.hl7.fhir.dstu3.model.Bundle;
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.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*; import org.junit.*;
@@ -32,6 +45,7 @@ public class ExampleServerDstu3IT {
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.TEST_PORT, Integer.toString(PortUtil.findFreePort()));
HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
ourCtx = FhirContext.forDstu3(); ourCtx = FhirContext.forDstu3();
ourPort = HapiProperties.getTestPort(); ourPort = HapiProperties.getTestPort();
} }
@@ -49,6 +63,64 @@ public class ExampleServerDstu3IT {
assertEquals(methodName, pt2.getName().get(0).getFamily()); assertEquals(methodName, pt2.getName().get(0).getFamily());
} }
@Test
public void testWebsocketSubscription() throws Exception {
/*
* Create subscription
*/
Subscription subscription = new Subscription();
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
subscription.setCriteria("Observation?status=final");
Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent();
channel.setType(Subscription.SubscriptionChannelType.WEBSOCKET);
channel.setPayload("application/json");
subscription.setChannel(channel);
MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute();
IIdType mySubscriptionId = methodOutcome.getId();
// Wait for the subscription to be activated
waitForSize(1, () -> ourClient.search().forResource(Subscription.class).where(Subscription.STATUS.exactly().code("active")).cacheControl(new CacheControlDirective().setNoCache(true)).returnBundle(Bundle.class).execute().getEntry().size());
/*
* Attach websocket
*/
WebSocketClient myWebSocketClient = new WebSocketClient();
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
myWebSocketClient.start();
URI echoUri = new URI("ws://localhost:" + ourPort + "/websocket");
ClientUpgradeRequest request = new ClientUpgradeRequest();
ourLog.info("Connecting to : {}", echoUri);
Future<Session> connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
Session session = connection.get(2, TimeUnit.SECONDS);
ourLog.info("Connected to WS: {}", session.isOpen());
/*
* Create a matching resource
*/
Observation obs = new Observation();
obs.setStatus(Observation.ObservationStatus.FINAL);
ourClient.create().resource(obs).execute();
// Give some time for the subscription to deliver
Thread.sleep(2000);
/*
* Ensure that we receive a ping on the websocket
*/
waitForSize(1, () -> mySocketImplementation.myPingCount);
/*
* Clean up
*/
ourClient.delete().resourceById(mySubscriptionId).execute();
}
@AfterClass @AfterClass
public static void afterClass() throws Exception { public static void afterClass() throws Exception {
ourServer.stop(); ourServer.stop();
@@ -56,13 +128,7 @@ public class ExampleServerDstu3IT {
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
/* String path = Paths.get("").toAbsolutePath().toString();
* This runs under maven, and I'm not sure how else to figure out the target directory from code..
*/
String path = ExampleServerDstu3IT.class.getClassLoader().getResource(".keep_hapi-fhir-jpaserver-starter").getPath();
path = new File(path).getParent();
path = new File(path).getParent();
path = new File(path).getParent();
ourLog.info("Project base path is: {}", path); ourLog.info("Project base path is: {}", path);

View File

@@ -22,9 +22,9 @@ 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.io.IOException;
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;
@@ -64,7 +64,6 @@ public class ExampleServerR4IT {
assertEquals(methodName, pt2.getName().get(0).getFamily()); assertEquals(methodName, pt2.getName().get(0).getFamily());
} }
@Test @Test
public void testWebsocketSubscription() throws Exception { public void testWebsocketSubscription() throws Exception {
/* /*
@@ -123,7 +122,6 @@ public class ExampleServerR4IT {
ourClient.delete().resourceById(mySubscriptionId).execute(); ourClient.delete().resourceById(mySubscriptionId).execute();
} }
@AfterClass @AfterClass
public static void afterClass() throws Exception { public static void afterClass() throws Exception {
ourServer.stop(); ourServer.stop();
@@ -131,13 +129,7 @@ public class ExampleServerR4IT {
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
/* String path = Paths.get("").toAbsolutePath().toString();
* This runs under maven, and I'm not sure how else to figure out the target directory from code..
*/
String path = ExampleServerR4IT.class.getClassLoader().getResource(".keep_hapi-fhir-jpaserver-starter").getPath();
path = new File(path).getParent();
path = new File(path).getParent();
path = new File(path).getParent();
ourLog.info("Project base path is: {}", path); ourLog.info("Project base path is: {}", path);