diff --git a/README.md b/README.md index 45c8eab..ab908be 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,13 @@ Much of this HAPI starter project can be configured using the properties file in ## 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 with MySQL, use the commands below to add user and database: -* datasource.driver=com.mysql.jdbc.Driver -* datasource.url=jdbc:mysql://localhost:3306/hapi_dstu3 -* hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +``` +CREATE USER 'fhirUser'@'localhost' IDENTIFIED BY 'fhirPass'; +CREATE DATABASE fhir_r4; +GRANT ALL PRIVILEGES ON fhir_r4.* to 'fhirUser'@'localhost'; +FLUSH PRIVILEGES; +``` It is important to use MySQL5Dialect when using MySQL version 5+. diff --git a/pom.xml b/pom.xml index 8a42a4e..fb188fc 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ oss-snapshots - true + false https://oss.sonatype.org/content/repositories/snapshots/ @@ -111,16 +111,11 @@ - - org.ebaysf.web - cors-filter - - - servlet-api - javax.servlet - - - + + + + + @@ -207,24 +202,20 @@ hapi-fhir-jpaserver - - - - - org.eclipse.jetty - jetty-maven-plugin - 9.4.8.v20180619 - - - / - true - - - - - - + + + org.eclipse.jetty + jetty-maven-plugin + 9.4.8.v20180619 + + + / + true + + + + org.apache.maven.plugins diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/FhirTesterConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/FhirTesterConfig.java index f7d8a77..11ccbcb 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirTesterConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirTesterConfig.java @@ -43,6 +43,7 @@ public class FhirTesterConfig { .withFhirVersion(HapiProperties.getFhirVersion()) .withBaseUrl(HapiProperties.getServerAddress()) .withName(HapiProperties.getServerName()); + retVal.setRefuseToFetchThirdPartyUrls(HapiProperties.getTesterConfigRefustToFetchThirdPartyUrls()); return retVal; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java index 0a5d74c..88becfb 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java @@ -39,6 +39,7 @@ public class HapiProperties { static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled"; static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled"; 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"; private static Properties properties; @@ -249,6 +250,10 @@ public class HapiProperties { return HapiProperties.getIntegerProperty(TEST_PORT, 0); } + public static Boolean getTesterConfigRefustToFetchThirdPartyUrls() { + return HapiProperties.getBooleanProperty(TESTER_CONFIG_REFUSE_TO_FETCH_THIRD_PARTY_URLS, false); + } + public static String getServerBase() { return HapiProperties.getProperty(SERVER_BASE, "/fhir"); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/JpaRestfulServer.java b/src/main/java/ca/uhn/fhir/jpa/starter/JpaRestfulServer.java index f4fbece..74aceb0 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/JpaRestfulServer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/JpaRestfulServer.java @@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.IFhirSystemDao; +import ca.uhn.fhir.jpa.model.interceptor.executor.InterceptorService; import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2; import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2; import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider; @@ -14,17 +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.TerminologyUploaderProviderR4; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; +import ca.uhn.fhir.jpa.subscription.SubscriptionInterceptorLoader; +import ca.uhn.fhir.jpa.subscription.module.interceptor.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.model.dstu2.composite.MetaDt; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy; import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.RestfulServer; +import ca.uhn.fhir.rest.server.interceptor.CorsInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Meta; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.web.cors.CorsConfiguration; import javax.servlet.ServletException; +import java.util.Arrays; import java.util.List; public class JpaRestfulServer extends RestfulServer { @@ -173,6 +179,33 @@ public class JpaRestfulServer extends RestfulServer { SubscriptionTriggeringProvider retriggeringProvider = appCtx.getBean(SubscriptionTriggeringProvider.class); registerProvider(retriggeringProvider); } + + // Define your CORS configuration. This is an example + // showing a typical setup. You should customize this + // to your specific needs + 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("*"); + + 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); + + // Enable the use of subscriptions + SubscriptionInterceptorLoader subscriptionInterceptorLoader = appCtx.getBean(SubscriptionInterceptorLoader.class); + subscriptionInterceptorLoader.registerInterceptors(); + // Subscription debug logging + InterceptorService interceptorService = (InterceptorService) appCtx.getBean("interceptorService"); + interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor()); } } diff --git a/src/main/resources/hapi.properties b/src/main/resources/hapi.properties index 277618d..3749603 100644 --- a/src/main/resources/hapi.properties +++ b/src/main/resources/hapi.properties @@ -1,7 +1,7 @@ # Adjust this to set the version of FHIR supported by this server. See # FhirVersionEnum for a list of available constants. -fhir_version=DSTU3 +fhir_version=R4 # This is the address that the FHIR server will report as its own address. # If this server will be deployed (for example) to an internet accessible @@ -25,16 +25,16 @@ logger.name=fhirtest.access logger.format=Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}] logger.error_format=ERROR - ${requestVerb} ${requestUrl} logger.log_exceptions=true -datasource.driver=org.apache.derby.jdbc.EmbeddedDriver -datasource.url=jdbc:derby:directory:target/jpaserver_derby_files;create=true -datasource.username= -datasource.password= +datasource.driver=com.mysql.cj.jdbc.Driver +datasource.url=jdbc:mysql://localhost:3306/fhir_r4 +datasource.username=fhirUser +datasource.password=fhirPass server.name=Local Tester server.id=home test.port= subscription.email.enabled=true subscription.resthook.enabled=true -hibernate.dialect=ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect +hibernate.dialect=org.hibernate.dialect.MySQL5Dialect hibernate.search.model_mapping=ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory hibernate.format_sql=false hibernate.show_sql=false @@ -47,3 +47,4 @@ hibernate.cache.use_minimal_puts=false hibernate.search.default.directory_provider=filesystem hibernate.search.default.indexBase=target/lucenefiles hibernate.search.lucene_version=LUCENE_CURRENT +tester.config.refuse_to_fetch_third_party_urls=false diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 54164b1..60250e0 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -37,69 +37,65 @@ 2 + + spring + / + fhirServlet ca.uhn.fhir.jpa.starter.JpaRestfulServer 1 - fhirServlet /fhir/* - - spring - / - - - - - - CORS Filter - org.ebaysf.web.cors.CORSFilter - - A comma separated list of allowed origins. Note: An '*' cannot be used for an allowed origin when using credentials. - cors.allowed.origins - * - - - A comma separated list of HTTP verbs, using which a CORS request can be made. - cors.allowed.methods - GET,POST,PUT,DELETE,OPTIONS - - - A comma separated list of allowed headers when making a non simple CORS request. - cors.allowed.headers - Accept,Access-Control-Request-Headers,Access-Control-Request-Method,Cache-Control,Content-Type,Origin,Prefer,X-FHIR-Starter,X-Requested-With - - - A comma separated list non-standard response headers that will be exposed to XHR2 object. - cors.exposed.headers - Location,Content-Location - - - A flag that suggests if CORS is supported with cookies - cors.support.credentials - true - - - A flag to control logging - cors.logging.enabled - true - - - Indicates how long (in seconds) the results of a preflight request can be cached in a preflight result cache. - cors.preflight.maxage - 300 - - - - CORS Filter - /* - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +