From c9c944d236943ac9fa9e83104c7557eb3b81eef1 Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Tue, 18 Aug 2020 08:05:34 -0400 Subject: [PATCH] Fix #122 - EMPI error on startup when EMPI not enabled --- pom.xml | 12 +- .../jpa/{starter => empi}/EmpiConfig.java | 12 +- .../fhir/jpa/starter/ApplicationContext.java | 1 + src/main/resources/empi-rules.json | 1 + .../jpa/starter/ExampleServerDstu2IT.java | 12 +- .../jpa/starter/ExampleServerDstu3IT.java | 252 +++++++++--------- .../fhir/jpa/starter/ExampleServerR4IT.java | 17 +- .../fhir/jpa/starter/ExampleServerR5IT.java | 24 +- .../jpa/starter/MultitenantServerR4IT.java | 12 +- 9 files changed, 170 insertions(+), 173 deletions(-) rename src/main/java/ca/uhn/fhir/jpa/{starter => empi}/EmpiConfig.java (75%) diff --git a/pom.xml b/pom.xml index 6f5a2a18fc9..bc49c7e63e2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ + 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"> 4.0.0 - - junit - junit - 4.12 - test - - @@ -338,6 +331,7 @@ org.apache.maven.plugins maven-failsafe-plugin + 3.0.0-M5 true diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/EmpiConfig.java b/src/main/java/ca/uhn/fhir/jpa/empi/EmpiConfig.java similarity index 75% rename from src/main/java/ca/uhn/fhir/jpa/starter/EmpiConfig.java rename to src/main/java/ca/uhn/fhir/jpa/empi/EmpiConfig.java index 107aa97cffa..b1f74a2d99c 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/EmpiConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/empi/EmpiConfig.java @@ -1,15 +1,11 @@ -package ca.uhn.fhir.jpa.starter; +package ca.uhn.fhir.jpa.empi; -import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.empi.api.IEmpiSettings; import ca.uhn.fhir.empi.rules.config.EmpiRuleValidator; import ca.uhn.fhir.empi.rules.config.EmpiSettings; -import ca.uhn.fhir.jpa.empi.svc.EmpiSearchParamSvc; -import ca.uhn.fhir.jpa.subscription.channel.subscription.IChannelNamer; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.jpa.starter.HapiProperties; import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.DefaultResourceLoader; @@ -17,6 +13,10 @@ import java.io.IOException; +/** + * TODO: Move this to package "ca.uhn.fhir.jpa.starter" in HAPI FHIR 5.2.0+. The lousy component scan + * in 5.1.0 picks this up even if EMPI is disabled currently. + */ @Configuration public class EmpiConfig { diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ApplicationContext.java b/src/main/java/ca/uhn/fhir/jpa/starter/ApplicationContext.java index c4d29199ed0..0beda1db72a 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ApplicationContext.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ApplicationContext.java @@ -1,6 +1,7 @@ package ca.uhn.fhir.jpa.starter; import ca.uhn.fhir.context.FhirVersionEnum; +import ca.uhn.fhir.jpa.empi.EmpiConfig; import ca.uhn.fhir.jpa.empi.config.EmpiConsumerConfig; import ca.uhn.fhir.jpa.empi.config.EmpiSubmitterConfig; import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig; diff --git a/src/main/resources/empi-rules.json b/src/main/resources/empi-rules.json index ad549d80a47..9f2706abaec 100644 --- a/src/main/resources/empi-rules.json +++ b/src/main/resources/empi-rules.json @@ -1,4 +1,5 @@ { + "version": "1", "candidateSearchParams": [ { "resourceType": "Patient", diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java index ee6ebf854b4..b34e67d0009 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java @@ -9,13 +9,13 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.webapp.WebAppContext; import org.hl7.fhir.instance.model.api.IIdType; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.nio.file.Paths; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ExampleServerDstu2IT { @@ -45,12 +45,12 @@ public void testCreateAndRead() { assertEquals(methodName, pt2.getName().get(0).getFamily().get(0).getValue()); } - @AfterClass + @AfterAll public static void afterClass() throws Exception { ourServer.stop(); } - @BeforeClass + @BeforeAll public static void beforeClass() throws Exception { String path = Paths.get("").toAbsolutePath().toString(); diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java index f1c26172edf..5ff9de5a0f3 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java @@ -18,9 +18,9 @@ import org.hl7.fhir.dstu3.model.Patient; import org.hl7.fhir.dstu3.model.Subscription; import org.hl7.fhir.instance.model.api.IIdType; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.net.URI; import java.nio.file.Paths; @@ -28,130 +28,130 @@ import java.util.concurrent.TimeUnit; import static ca.uhn.fhir.util.TestUtil.waitForSize; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ExampleServerDstu3IT { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu3IT.class); - private static IGenericClient ourClient; - private static FhirContext ourCtx; - private static int ourPort; - private static Server ourServer; - - static { - HapiProperties.forceReload(); - HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3"); - HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr3"); - HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true"); - HapiProperties.setProperty(HapiProperties.ALLOW_EXTERNAL_REFERENCES, "true"); - HapiProperties.setProperty(HapiProperties.ALLOW_PLACEHOLDER_REFERENCES, "true"); - ourCtx = FhirContext.forDstu3(); - } - - @Test - public void testCreateAndRead() { - ourLog.info("Base URL is: " + HapiProperties.getServerAddress()); - String methodName = "testCreateResourceConditional"; - - Patient pt = new Patient(); - pt.addName().setFamily(methodName); - IIdType id = ourClient.create().resource(pt).execute().getId(); - - Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute(); - 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 + "/hapi-fhir-jpaserver/websocket"); - ClientUpgradeRequest request = new ClientUpgradeRequest(); - ourLog.info("Connecting to : {}", echoUri); - Future 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 - public static void afterClass() throws Exception { - ourServer.stop(); - } - - @BeforeClass - public static void beforeClass() throws Exception { - String path = Paths.get("").toAbsolutePath().toString(); - - ourLog.info("Project base path is: {}", path); - - ourServer = new Server(0); - - WebAppContext webAppContext = new WebAppContext(); - webAppContext.setContextPath("/hapi-fhir-jpaserver"); - webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml"); - webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter"); - webAppContext.setParentLoaderPriority(true); - - ourServer.setHandler(webAppContext); - ourServer.start(); - - ourPort = JettyUtil.getPortForStartedServer(ourServer); - - ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); - ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000); - String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/"; - ourClient = ourCtx.newRestfulGenericClient(ourServerBase); - ourClient.registerInterceptor(new LoggingInterceptor(true)); - } - - public static void main(String[] theArgs) throws Exception { - ourPort = 8080; - beforeClass(); - } + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu3IT.class); + private static IGenericClient ourClient; + private static FhirContext ourCtx; + private static int ourPort; + private static Server ourServer; + + static { + HapiProperties.forceReload(); + HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU3"); + HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr3"); + HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true"); + HapiProperties.setProperty(HapiProperties.ALLOW_EXTERNAL_REFERENCES, "true"); + HapiProperties.setProperty(HapiProperties.ALLOW_PLACEHOLDER_REFERENCES, "true"); + ourCtx = FhirContext.forDstu3(); + } + + @Test + public void testCreateAndRead() { + ourLog.info("Base URL is: " + HapiProperties.getServerAddress()); + String methodName = "testCreateResourceConditional"; + + Patient pt = new Patient(); + pt.addName().setFamily(methodName); + IIdType id = ourClient.create().resource(pt).execute().getId(); + + Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute(); + 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 + "/hapi-fhir-jpaserver/websocket"); + ClientUpgradeRequest request = new ClientUpgradeRequest(); + ourLog.info("Connecting to : {}", echoUri); + Future 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(); + } + + @AfterAll + public static void afterClass() throws Exception { + ourServer.stop(); + } + + @BeforeAll + public static void beforeClass() throws Exception { + String path = Paths.get("").toAbsolutePath().toString(); + + ourLog.info("Project base path is: {}", path); + + ourServer = new Server(0); + + WebAppContext webAppContext = new WebAppContext(); + webAppContext.setContextPath("/hapi-fhir-jpaserver"); + webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml"); + webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-starter"); + webAppContext.setParentLoaderPriority(true); + + ourServer.setHandler(webAppContext); + ourServer.start(); + + ourPort = JettyUtil.getPortForStartedServer(ourServer); + + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000); + String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/"; + ourClient = ourCtx.newRestfulGenericClient(ourServerBase); + ourClient.registerInterceptor(new LoggingInterceptor(true)); + } + + public static void main(String[] theArgs) throws Exception { + ourPort = 8080; + beforeClass(); + } } diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java index 22b5656383f..c610481748b 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java @@ -21,9 +21,9 @@ import org.hl7.fhir.r4.model.Person; import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Subscription; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.net.URI; import java.nio.file.Paths; @@ -35,8 +35,8 @@ import static ca.uhn.fhir.util.TestUtil.waitForSize; import static org.awaitility.Awaitility.await; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ExampleServerR4IT { @@ -61,6 +61,9 @@ public void testCreateAndRead() { String methodName = "testCreateResourceConditional"; Patient pt = new Patient(); + pt.setActive(true); + pt.getBirthDateElement().setValueAsString("2020-01-01"); + pt.addIdentifier().setSystem("http://foo").setValue("12345"); pt.addName().setFamily(methodName); IIdType id = ourClient.create().resource(pt).execute().getId(); @@ -151,12 +154,12 @@ private int activeSubscriptionCount() { return ourClient.search().forResource(Subscription.class).where(Subscription.STATUS.exactly().code("active")).cacheControl(new CacheControlDirective().setNoCache(true)).returnBundle(Bundle.class).execute().getEntry().size(); } - @AfterClass + @AfterAll public static void afterClass() throws Exception { ourServer.stop(); } - @BeforeClass + @BeforeAll public static void beforeClass() throws Exception { String path = Paths.get("").toAbsolutePath().toString(); diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java index 62ac1a3dfa4..ea9855f8eef 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java @@ -20,9 +20,9 @@ import org.hl7.fhir.r5.model.Patient; import org.hl7.fhir.r5.model.Subscription; import org.hl7.fhir.r5.model.SubscriptionTopic; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.net.URI; import java.nio.file.Paths; @@ -30,7 +30,8 @@ import java.util.concurrent.TimeUnit; import static ca.uhn.fhir.util.TestUtil.waitForSize; -import static org.junit.Assert.assertEquals; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ExampleServerR5IT { @@ -77,9 +78,9 @@ public void testWebsocketSubscription() throws Exception { subscription.getTopic().setResource(topic); subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)"); subscription.setStatus(Enumerations.SubscriptionState.REQUESTED); - subscription.getChannelType() - .setSystem("http://terminology.hl7.org/CodeSystem/subscription-channel-type") - .setCode("websocket"); + subscription.getChannelType() + .setSystem("http://terminology.hl7.org/CodeSystem/subscription-channel-type") + .setCode("websocket"); subscription.setContentType("application/json"); MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute(); @@ -111,13 +112,10 @@ public void testWebsocketSubscription() throws Exception { obs.setStatus(Enumerations.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); + await().until(()->mySocketImplementation.myPingCount > 0); /* * Clean up @@ -125,12 +123,12 @@ public void testWebsocketSubscription() throws Exception { ourClient.delete().resourceById(mySubscriptionId).execute(); } - @AfterClass + @AfterAll public static void afterClass() throws Exception { ourServer.stop(); } - @BeforeClass + @BeforeAll public static void beforeClass() throws Exception { String path = Paths.get("").toAbsolutePath().toString(); diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java index a2a6148326f..25e7315275b 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java @@ -15,13 +15,13 @@ import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Patient; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import java.nio.file.Paths; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public class MultitenantServerR4IT { @@ -94,12 +94,12 @@ public void testCreateAndReadInTenantB() { assertEquals("Family B", pt2.getName().get(0).getFamily()); } - @AfterClass + @AfterAll public static void afterClass() throws Exception { ourServer.stop(); } - @BeforeClass + @BeforeAll public static void beforeClass() throws Exception { String path = Paths.get("").toAbsolutePath().toString();