entry : aToBeAdded.entrySet()) {
+ if (aBase.containsKey(entry.getKey())) {
+ continue;
+ }
+
+ aBase.put(entry.getKey(), entry.getValue());
+ }
+ }
+}
diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigCommon.java b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigCommon.java
index 123b7a0..cfe9bde 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigCommon.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigCommon.java
@@ -8,17 +8,14 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory;
import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
import ca.uhn.fhir.jpa.subscription.match.deliver.email.JavaMailEmailSender;
-import org.apache.commons.dbcp2.BasicDataSource;
+import com.google.common.base.Strings;
import org.hl7.fhir.dstu2.model.Subscription;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
-import org.thymeleaf.util.Validate;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Driver;
+import java.util.Optional;
/**
* This is the primary configuration file for the example server
@@ -29,57 +26,34 @@ public class FhirServerConfigCommon {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
- private Boolean enableIndexMissingFields = HapiProperties.getEnableIndexMissingFields();
- private Boolean autoCreatePlaceholderReferenceTargets = HapiProperties.getAutoCreatePlaceholderReferenceTargets();
- private Boolean enforceReferentialIntegrityOnWrite = HapiProperties.getEnforceReferentialIntegrityOnWrite();
- private Boolean enforceReferentialIntegrityOnDelete = HapiProperties.getEnforceReferentialIntegrityOnDelete();
- private Boolean allowContainsSearches = HapiProperties.getAllowContainsSearches();
- private Boolean allowMultipleDelete = HapiProperties.getAllowMultipleDelete();
- private Boolean allowExternalReferences = HapiProperties.getAllowExternalReferences();
- private Boolean expungeEnabled = HapiProperties.getExpungeEnabled();
- private Boolean allowPlaceholderReferences = HapiProperties.getAllowPlaceholderReferences();
- private Boolean subscriptionRestHookEnabled = HapiProperties.getSubscriptionRestHookEnabled();
- private Boolean subscriptionEmailEnabled = HapiProperties.getSubscriptionEmailEnabled();
- private Boolean allowOverrideDefaultSearchParams = HapiProperties.getAllowOverrideDefaultSearchParams();
- private String emailFrom = HapiProperties.getEmailFrom();
- private Boolean emailEnabled = HapiProperties.getEmailEnabled();
- private String emailHost = HapiProperties.getEmailHost();
- private Integer emailPort = HapiProperties.getEmailPort();
- private String emailUsername = HapiProperties.getEmailUsername();
- private String emailPassword = HapiProperties.getEmailPassword();
- private Boolean emailAuth = HapiProperties.getEmailAuth();
- private Boolean emailStartTlsEnable = HapiProperties.getEmailStartTlsEnable();
- private Boolean emailStartTlsRequired = HapiProperties.getEmailStartTlsRequired();
- private Boolean emailQuitWait = HapiProperties.getEmailQuitWait();
- @Autowired
- private ApplicationContext myAppCtx;
- public FhirServerConfigCommon() {
- ourLog.info("Server configured to " + (this.allowContainsSearches ? "allow" : "deny") + " contains searches");
- 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");
+ public FhirServerConfigCommon(AppProperties appProperties) {
+ ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny") + " contains searches");
+ ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny") + " multiple deletes");
+ ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny") + " external references");
+ ourLog.info("Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges");
+ ourLog.info("Server configured to " + (appProperties.getAllow_placeholder_references() ? "allow" : "deny") + " placeholder references");
+ ourLog.info("Server configured to " + (appProperties.getAllow_override_default_search_params() ? "allow" : "deny") + " overriding default search params");
- if (this.emailEnabled) {
- 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 (appProperties.getSubscription().getEmail() != null) {
+ AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail();
+ ourLog.info("Server is configured to enable email with host '" + email.getHost() + "' and port " + email.getPort());
+ ourLog.info("Server will use '" + email.getFrom() + "' as the from email address");
- if (this.emailUsername != null && this.emailUsername.length() > 0) {
- ourLog.info("Server is configured to use username '" + this.emailUsername + "' for email");
+ if (!Strings.isNullOrEmpty(email.getUsername())) {
+ ourLog.info("Server is configured to use username '" + email.getUsername() + "' for email");
}
- if (this.emailPassword != null && this.emailPassword.length() > 0) {
+ if (!Strings.isNullOrEmpty(email.getPassword())) {
ourLog.info("Server is configured to use a password for email");
}
}
- if (this.subscriptionRestHookEnabled) {
+ if (appProperties.getSubscription().getResthook_enabled()) {
ourLog.info("REST-hook subscriptions enabled");
}
- if (this.subscriptionEmailEnabled) {
+ if (appProperties.getSubscription().getEmail() != null) {
ourLog.info("Email subscriptions enabled");
}
}
@@ -88,56 +62,60 @@ public class FhirServerConfigCommon {
* Configure FHIR properties around the the JPA server via this bean
*/
@Bean()
- public DaoConfig daoConfig() {
+ public DaoConfig daoConfig(AppProperties appProperties) {
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);
+ retVal.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? DaoConfig.IndexEnabledEnum.ENABLED : DaoConfig.IndexEnabledEnum.DISABLED);
+ retVal.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets());
+ retVal.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write());
+ retVal.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete());
+ retVal.setAllowContainsSearches(appProperties.getAllow_contains_searches());
+ retVal.setAllowMultipleDelete(appProperties.getAllow_multiple_delete());
+ retVal.setAllowExternalReferences(appProperties.getAllow_external_references());
+ retVal.setExpungeEnabled(appProperties.getExpunge_enabled());
+ retVal.setAutoCreatePlaceholderReferenceTargets(appProperties.getAllow_placeholder_references());
+ if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null)
+ retVal.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom());
- Integer maxFetchSize = HapiProperties.getMaximumFetchSize();
+ Integer maxFetchSize = appProperties.getMax_page_size();
retVal.setFetchSizeDefaultMaximum(maxFetchSize);
ourLog.info("Server configured to have a maximum fetch size of " + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize));
- Long reuseCachedSearchResultsMillis = HapiProperties.getReuseCachedSearchResultsMillis();
+ Long reuseCachedSearchResultsMillis = appProperties.getReuse_cached_search_results_millis();
retVal.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis);
ourLog.info("Server configured to cache search results for {} milliseconds", reuseCachedSearchResultsMillis);
- Long retainCachedSearchesMinutes = HapiProperties.getExpireSearchResultsAfterMins();
+
+ Long retainCachedSearchesMinutes = appProperties.getRetain_cached_searches_mins();
retVal.setExpireSearchResultsAfterMillis(retainCachedSearchesMinutes * 60 * 1000);
- // Subscriptions are enabled by channel type
- if (HapiProperties.getSubscriptionRestHookEnabled()) {
- ourLog.info("Enabling REST-hook subscriptions");
- retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK);
- }
- if (HapiProperties.getSubscriptionEmailEnabled()) {
- ourLog.info("Enabling email subscriptions");
- retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL);
- }
- if (HapiProperties.getSubscriptionWebsocketEnabled()) {
- ourLog.info("Enabling websocket subscriptions");
- retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.WEBSOCKET);
+ if(appProperties.getSubscription() != null) {
+ // Subscriptions are enabled by channel type
+ if (appProperties.getSubscription().getResthook_enabled()) {
+ ourLog.info("Enabling REST-hook subscriptions");
+ retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK);
+ }
+ if (appProperties.getSubscription().getEmail() != null) {
+ ourLog.info("Enabling email subscriptions");
+ retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL);
+ }
+ if (appProperties.getSubscription().getWebsocket_enabled()) {
+ ourLog.info("Enabling websocket subscriptions");
+ retVal.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.WEBSOCKET);
+ }
}
- retVal.setFilterParameterEnabled(HapiProperties.getFilterSearchEnabled());
+ retVal.setFilterParameterEnabled(appProperties.getFilter_search_enabled());
return retVal;
}
@Bean
- public PartitionSettings partitionSettings() {
+ public PartitionSettings partitionSettings(AppProperties appProperties) {
PartitionSettings retVal = new PartitionSettings();
// Partitioning
- if (HapiProperties.getPartitioningMultitenancyEnabled()) {
+ if (appProperties.getPartitioning() != null) {
retVal.setPartitioningEnabled(true);
}
@@ -146,19 +124,20 @@ public class FhirServerConfigCommon {
@Bean
- public ModelConfig modelConfig() {
+ public ModelConfig modelConfig(AppProperties appProperties) {
ModelConfig modelConfig = new ModelConfig();
- modelConfig.setAllowContainsSearches(this.allowContainsSearches);
- modelConfig.setAllowExternalReferences(this.allowExternalReferences);
- modelConfig.setDefaultSearchParamsCanBeOverridden(this.allowOverrideDefaultSearchParams);
- modelConfig.setEmailFromAddress(this.emailFrom);
+ modelConfig.setAllowContainsSearches(appProperties.getAllow_contains_searches());
+ modelConfig.setAllowExternalReferences(appProperties.getAllow_external_references());
+ modelConfig.setDefaultSearchParamsCanBeOverridden(appProperties.getAllow_override_default_search_params());
+ if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null)
+ modelConfig.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom());
// You can enable these if you want to support Subscriptions from your server
- if (this.subscriptionRestHookEnabled) {
+ if (appProperties.getSubscription() != null && appProperties.getSubscription().getResthook_enabled() != null) {
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.RESTHOOK);
}
- if (this.subscriptionEmailEnabled) {
+ if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) {
modelConfig.addSupportedSubscriptionType(Subscription.SubscriptionChannelType.EMAIL);
}
@@ -171,7 +150,7 @@ public class FhirServerConfigCommon {
*
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
*/
- @Bean(destroyMethod = "close")
+ /*@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();
@@ -181,38 +160,37 @@ public class FhirServerConfigCommon {
retVal.setPassword(HapiProperties.getDataSourcePassword());
retVal.setMaxTotal(HapiProperties.getDataSourceMaxPoolSize());
return retVal;
- }
+ }*/
@Lazy
@Bean
- public IBinaryStorageSvc binaryStorageSvc() {
+ public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) {
DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
- if (HapiProperties.getMaxBinarySize() != null) {
- binaryStorageSvc.setMaximumBinarySize(HapiProperties.getMaxBinarySize());
+ if (appProperties.getMax_binary_size() != null) {
+ binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size());
}
return binaryStorageSvc;
}
@Bean()
- public IEmailSender emailSender() {
- if (this.emailEnabled) {
+ public IEmailSender emailSender(AppProperties appProperties, Optional subscriptionDeliveryHandlerFactory) {
+ if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) {
JavaMailEmailSender retVal = new JavaMailEmailSender();
- retVal.setSmtpServerHostname(this.emailHost);
- retVal.setSmtpServerPort(this.emailPort);
- retVal.setSmtpServerUsername(this.emailUsername);
- retVal.setSmtpServerPassword(this.emailPassword);
- retVal.setAuth(this.emailAuth);
- retVal.setStartTlsEnable(this.emailStartTlsEnable);
- retVal.setStartTlsRequired(this.emailStartTlsRequired);
- retVal.setQuitWait(this.emailQuitWait);
-
- SubscriptionDeliveryHandlerFactory subscriptionDeliveryHandlerFactory = myAppCtx.getBean(SubscriptionDeliveryHandlerFactory.class);
- Validate.notNull(subscriptionDeliveryHandlerFactory, "No subscription delivery handler");
- subscriptionDeliveryHandlerFactory.setEmailSender(retVal);
+ AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail();
+ retVal.setSmtpServerHostname(email.getHost());
+ retVal.setSmtpServerPort(email.getPort());
+ retVal.setSmtpServerUsername(email.getUsername());
+ retVal.setSmtpServerPassword(email.getPassword());
+ retVal.setAuth(email.getAuth());
+ retVal.setStartTlsEnable(email.getStartTlsEnable());
+ retVal.setStartTlsRequired(email.getStartTlsRequired());
+ retVal.setQuitWait(email.getQuitWait());
+ if(subscriptionDeliveryHandlerFactory.isPresent())
+ subscriptionDeliveryHandlerFactory.get().setEmailSender(retVal);
return retVal;
}
diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu2.java b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu2.java
index d80e70f..8efc81f 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu2.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu2.java
@@ -7,53 +7,66 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
@Configuration
+@Profile("dstu2")
public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
- @Autowired
- private DataSource myDataSource;
+ @Autowired
+ private DataSource myDataSource;
- /**
- * We override the paging provider definition so that we can customize
- * the default/max page sizes for search results. You can set these however
- * you want, although very large page sizes will require a lot of RAM.
- */
- @Override
- public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
- DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
- pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
- pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
- return pagingProvider;
- }
-
- @Override
- @Bean()
- public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
- LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
- retVal.setPersistenceUnitName("HAPI_PU");
-
- try {
- retVal.setDataSource(myDataSource);
- } catch (Exception e) {
- throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
- }
-
- retVal.setJpaProperties(HapiProperties.getJpaProperties());
- return retVal;
+ /**
+ * We override the paging provider definition so that we can customize
+ * the default/max page sizes for search results. You can set these however
+ * you want, although very large page sizes will require a lot of RAM.
+ */
+ @Autowired
+ AppProperties appProperties;
+
+ @Override
+ public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
+ DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
+ pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
+ pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
+ return pagingProvider;
+ }
+
+ @Autowired
+ private ConfigurableEnvironment configurableEnvironment;
+
+ @Override
+ @Bean()
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
+ retVal.setPersistenceUnitName("HAPI_PU");
+
+ try {
+ retVal.setDataSource(myDataSource);
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
}
+ retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
+ return retVal;
+ }
@Bean
@Primary
public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) {
- JpaTransactionManager retVal = new JpaTransactionManager();
- retVal.setEntityManagerFactory(entityManagerFactory);
- return retVal;
- }
+ JpaTransactionManager retVal = new JpaTransactionManager();
+ retVal.setEntityManagerFactory(entityManagerFactory);
+ return retVal;
+ }
+
}
diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu3.java b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu3.java
index 2a93154..ace88af 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu3.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu3.java
@@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -14,46 +16,53 @@ import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
+@Profile("dstu3")
public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
- @Autowired
- private DataSource myDataSource;
+ @Autowired
+ private DataSource myDataSource;
- /**
- * We override the paging provider definition so that we can customize
- * the default/max page sizes for search results. You can set these however
- * you want, although very large page sizes will require a lot of RAM.
- */
- @Override
- public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
- DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
- pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
- pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
- return pagingProvider;
+ /**
+ * We override the paging provider definition so that we can customize
+ * the default/max page sizes for search results. You can set these however
+ * you want, although very large page sizes will require a lot of RAM.
+ */
+ @Autowired
+ AppProperties appProperties;
+
+ @Override
+ public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
+ DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
+ pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
+ pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
+ return pagingProvider;
+ }
+
+ @Autowired
+ private ConfigurableEnvironment configurableEnvironment;
+
+ @Override
+ @Bean
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
+ retVal.setPersistenceUnitName("HAPI_PU");
+
+ try {
+ retVal.setDataSource(myDataSource);
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
}
- @Override
- @Bean
- public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
- LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
- retVal.setPersistenceUnitName("HAPI_PU");
+ retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
+ return retVal;
+ }
- try {
- retVal.setDataSource(myDataSource);
- } catch (Exception e) {
- throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
- }
-
- retVal.setJpaProperties(HapiProperties.getJpaProperties());
- return retVal;
- }
-
- @Bean
- @Primary
- public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) {
- JpaTransactionManager retVal = new JpaTransactionManager();
- retVal.setEntityManagerFactory(entityManagerFactory);
- return retVal;
- }
+ @Bean
+ @Primary
+ public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) {
+ JpaTransactionManager retVal = new JpaTransactionManager();
+ retVal.setEntityManagerFactory(entityManagerFactory);
+ return retVal;
+ }
}
diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR4.java b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR4.java
index 5f3f8a9..8d8e699 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR4.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR4.java
@@ -7,53 +7,65 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
+import java.util.Arrays;
+import java.util.Properties;
@Configuration
+@Profile("r4")
public class FhirServerConfigR4 extends BaseJavaConfigR4 {
- @Autowired
- private DataSource myDataSource;
+ @Autowired
+ private DataSource myDataSource;
- /**
- * We override the paging provider definition so that we can customize
- * the default/max page sizes for search results. You can set these however
- * you want, although very large page sizes will require a lot of RAM.
- */
- @Override
- public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
- DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
- pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
- pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
- return pagingProvider;
+ /**
+ * We override the paging provider definition so that we can customize
+ * the default/max page sizes for search results. You can set these however
+ * you want, although very large page sizes will require a lot of RAM.
+ */
+ @Autowired
+ AppProperties appProperties;
+
+ @Override
+ public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
+ DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
+ pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
+ pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
+ return pagingProvider;
+ }
+
+ @Autowired
+ private ConfigurableEnvironment configurableEnvironment;
+
+ @Override
+ @Bean()
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
+ retVal.setPersistenceUnitName("HAPI_PU");
+
+ try {
+ retVal.setDataSource(myDataSource);
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
}
- @Override
- @Bean()
- public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
- LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
- retVal.setPersistenceUnitName("HAPI_PU");
-
- try {
- retVal.setDataSource(myDataSource);
- } catch (Exception e) {
- throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
- }
-
- retVal.setJpaProperties(HapiProperties.getJpaProperties());
- return retVal;
- }
+ retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
+ return retVal;
+ }
@Bean
@Primary
public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) {
- JpaTransactionManager retVal = new JpaTransactionManager();
- retVal.setEntityManagerFactory(entityManagerFactory);
- return retVal;
- }
+ JpaTransactionManager retVal = new JpaTransactionManager();
+ retVal.setEntityManagerFactory(entityManagerFactory);
+ return retVal;
+ }
}
diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR5.java b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR5.java
index d6cf537..5a5145b 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR5.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR5.java
@@ -7,6 +7,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
@@ -14,46 +16,53 @@ import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
+@Profile("r5")
public class FhirServerConfigR5 extends BaseJavaConfigR5 {
- @Autowired
- private DataSource myDataSource;
+ @Autowired
+ private DataSource myDataSource;
- /**
- * We override the paging provider definition so that we can customize
- * the default/max page sizes for search results. You can set these however
- * you want, although very large page sizes will require a lot of RAM.
- */
- @Override
- public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
- DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
- pagingProvider.setDefaultPageSize(HapiProperties.getDefaultPageSize());
- pagingProvider.setMaximumPageSize(HapiProperties.getMaximumPageSize());
- return pagingProvider;
+ /**
+ * We override the paging provider definition so that we can customize
+ * the default/max page sizes for search results. You can set these however
+ * you want, although very large page sizes will require a lot of RAM.
+ */
+ @Autowired
+ AppProperties appProperties;
+
+ @Override
+ public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
+ DatabaseBackedPagingProvider pagingProvider = super.databaseBackedPagingProvider();
+ pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size());
+ pagingProvider.setMaximumPageSize(appProperties.getMax_page_size());
+ return pagingProvider;
+ }
+
+ @Autowired
+ private ConfigurableEnvironment configurableEnvironment;
+
+ @Override
+ @Bean()
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
+ retVal.setPersistenceUnitName("HAPI_PU");
+
+ try {
+ retVal.setDataSource(myDataSource);
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
}
- @Override
- @Bean()
- public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
- LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
- retVal.setPersistenceUnitName("HAPI_PU");
-
- try {
- retVal.setDataSource(myDataSource);
- } catch (Exception e) {
- throw new ConfigurationException("Could not set the data source due to a configuration issue", e);
- }
-
- retVal.setJpaProperties(HapiProperties.getJpaProperties());
- return retVal;
- }
+ retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment));
+ return retVal;
+ }
@Bean
@Primary
public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) {
- JpaTransactionManager retVal = new JpaTransactionManager();
- retVal.setEntityManagerFactory(entityManagerFactory);
- return retVal;
- }
+ JpaTransactionManager retVal = new JpaTransactionManager();
+ retVal.setEntityManagerFactory(entityManagerFactory);
+ return retVal;
+ }
}
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 11ccbcb..45a7808 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirTesterConfig.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirTesterConfig.java
@@ -1,11 +1,10 @@
package ca.uhn.fhir.jpa.starter;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-
import ca.uhn.fhir.to.FhirTesterMvcConfig;
import ca.uhn.fhir.to.TesterConfig;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
//@formatter:off
/**
@@ -34,18 +33,22 @@ public class FhirTesterConfig {
* deploying your server to a place with a fully qualified domain name,
* you might want to use that instead of using the variable.
*/
- @Bean
- public TesterConfig testerConfig() {
- TesterConfig retVal = new TesterConfig();
- retVal
- .addServer()
- .withId(HapiProperties.getServerId())
- .withFhirVersion(HapiProperties.getFhirVersion())
- .withBaseUrl(HapiProperties.getServerAddress())
- .withName(HapiProperties.getServerName());
- retVal.setRefuseToFetchThirdPartyUrls(HapiProperties.getTesterConfigRefustToFetchThirdPartyUrls());
- return retVal;
- }
+ @Bean
+ public TesterConfig testerConfig(AppProperties appProperties) {
+ TesterConfig retVal = new TesterConfig();
+ appProperties.getTester().stream().forEach(t -> {
+ retVal
+ .addServer()
+ .withId(t.getId())
+ .withFhirVersion(t.getFhir_version())
+ .withBaseUrl(t.getServer_address())
+ .withName(t.getName());
+ retVal.setRefuseToFetchThirdPartyUrls(
+ t.getRefuse_to_fetch_third_party_urls());
+
+ });
+ return retVal;
+ }
}
//@formatter:on
diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java
deleted file mode 100644
index 20628e5..0000000
--- a/src/main/java/ca/uhn/fhir/jpa/starter/HapiProperties.java
+++ /dev/null
@@ -1,535 +0,0 @@
-package ca.uhn.fhir.jpa.starter;
-
-import ca.uhn.fhir.context.ConfigurationException;
-import ca.uhn.fhir.context.FhirVersionEnum;
-import ca.uhn.fhir.jpa.api.config.DaoConfig;
-import ca.uhn.fhir.jpa.search.elastic.ElasticsearchHibernatePropertiesBuilder;
-import ca.uhn.fhir.rest.api.EncodingEnum;
-import ca.uhn.fhir.rest.server.ETagSupportEnum;
-import com.google.common.annotations.VisibleForTesting;
-import org.apache.commons.lang3.StringUtils;
-import org.hibernate.search.elasticsearch.cfg.ElasticsearchIndexStatus;
-import org.hibernate.search.elasticsearch.cfg.IndexSchemaManagementStrategy;
-import org.jetbrains.annotations.NotNull;
-
-import javax.annotation.Nonnull;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-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 {
- static final String ENABLE_INDEX_MISSING_FIELDS = "enable_index_missing_fields";
- static final String AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS = "auto_create_placeholder_reference_targets";
- static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE = "enforce_referential_integrity_on_write";
- static final String ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE = "enforce_referential_integrity_on_delete";
- static final String BINARY_STORAGE_ENABLED = "binary_storage.enabled";
- static final String ALLOW_EXTERNAL_REFERENCES = "allow_external_references";
- static final String ALLOW_MULTIPLE_DELETE = "allow_multiple_delete";
- static final String ALLOW_PLACEHOLDER_REFERENCES = "allow_placeholder_references";
- static final String REUSE_CACHED_SEARCH_RESULTS_MILLIS = "reuse_cached_search_results_millis";
- static final String DATASOURCE_DRIVER = "datasource.driver";
- static final String DATASOURCE_MAX_POOL_SIZE = "datasource.max_pool_size";
- static final String DATASOURCE_PASSWORD = "datasource.password";
- static final String DATASOURCE_URL = "datasource.url";
- static final String DATASOURCE_USERNAME = "datasource.username";
- static final String DEFAULT_ENCODING = "default_encoding";
- static final String DEFAULT_PAGE_SIZE = "default_page_size";
- static final String DEFAULT_PRETTY_PRINT = "default_pretty_print";
- static final String ETAG_SUPPORT = "etag_support";
- static final String FHIR_VERSION = "fhir_version";
- static final String ALLOW_CASCADING_DELETES = "allow_cascading_deletes";
- static final String HAPI_PROPERTIES = "hapi.properties";
- static final String LOGGER_ERROR_FORMAT = "logger.error_format";
- static final String LOGGER_FORMAT = "logger.format";
- static final String LOGGER_LOG_EXCEPTIONS = "logger.log_exceptions";
- static final String LOGGER_NAME = "logger.name";
- static final String MAX_FETCH_SIZE = "max_fetch_size";
- static final String MAX_PAGE_SIZE = "max_page_size";
- static final String SERVER_ADDRESS = "server_address";
- static final String SERVER_ID = "server.id";
- static final String SERVER_NAME = "server.name";
- static final String SUBSCRIPTION_EMAIL_ENABLED = "subscription.email.enabled";
- static final String SUBSCRIPTION_RESTHOOK_ENABLED = "subscription.resthook.enabled";
- static final String SUBSCRIPTION_WEBSOCKET_ENABLED = "subscription.websocket.enabled";
- static final String EMPI_ENABLED = "empi.enabled";
- static final String PARTITIONING_ENABLED = "partitioning.enabled";
- static final String PARTITIONING_CROSS_PARTITION_REFERENCE_MODE = "partitioning.cross_partition_reference_mode";
- static final String ALLOWED_BUNDLE_TYPES = "allowed_bundle_types";
- 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 CORS_ALLOW_CREDENTIALS = "cors.allowCredentials";
- 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 EMAIL_FROM = "email.from";
- static final String VALIDATE_REQUESTS_ENABLED = "validation.requests.enabled";
- static final String VALIDATE_RESPONSES_ENABLED = "validation.responses.enabled";
- static final String FILTER_SEARCH_ENABLED = "filter_search.enabled";
- static final String GRAPHQL_ENABLED = "graphql.enabled";
- static final String BULK_EXPORT_ENABLED = "bulk.export.enabled";
- static final String EXPIRE_SEARCH_RESULTS_AFTER_MINS = "retain_cached_searches_mins";
- static final String MAX_BINARY_SIZE = "max_binary_size";
- static final String PARTITIONING_MULTITENANCY_ENABLED = "partitioning.multitenancy.enabled";
- private static final String PARTITIONING_INCLUDE_PARTITION_IN_SEARCH_HASHES = "partitioning.partitioning_include_in_search_hashes";
- static final String CLIENT_ID_STRATEGY = "daoconfig.client_id_strategy";
- private static Properties ourProperties;
-
- public static boolean isElasticSearchEnabled() {
- return HapiProperties.getPropertyBoolean("elasticsearch.enabled", false);
- }
-
- /*
- * Force the configuration to be reloaded
- */
- public static void forceReload() {
- ourProperties = null;
- getProperties();
- }
-
- /**
- * This is mostly here for unit tests. Use the actual properties file
- * to set values
- */
- @VisibleForTesting
- public static void setProperty(String theKey, String theValue) {
- getProperties().setProperty(theKey, theValue);
- }
-
- public static Properties getJpaProperties() {
- Properties retVal = loadProperties();
-
- if (isElasticSearchEnabled()) {
- ElasticsearchHibernatePropertiesBuilder builder = new ElasticsearchHibernatePropertiesBuilder();
- builder.setRequiredIndexStatus(getPropertyEnum("elasticsearch.required_index_status", ElasticsearchIndexStatus.class, ElasticsearchIndexStatus.YELLOW));
- builder.setRestUrl(getProperty("elasticsearch.rest_url"));
- builder.setUsername(getProperty("elasticsearch.username"));
- builder.setPassword(getProperty("elasticsearch.password"));
- builder.setIndexSchemaManagementStrategy(getPropertyEnum("elasticsearch.schema_management_strategy", IndexSchemaManagementStrategy.class, IndexSchemaManagementStrategy.CREATE));
- builder.setDebugRefreshAfterWrite(getPropertyBoolean("elasticsearch.debug.refresh_after_write", false));
- builder.setDebugPrettyPrintJsonLog(getPropertyBoolean("elasticsearch.debug.pretty_print_json_log", false));
- builder.apply(retVal);
- }
-
- return retVal;
- }
-
- private static Properties getProperties() {
- if (ourProperties == null) {
- Properties properties = loadProperties();
- HapiProperties.ourProperties = properties;
- }
-
- return ourProperties;
- }
-
- @NotNull
- private static Properties loadProperties() {
- // Load the configurable properties file
- Properties properties;
- try (InputStream in = HapiProperties.class.getClassLoader().getResourceAsStream(HAPI_PROPERTIES)) {
- properties = new Properties();
- properties.load(in);
- } catch (Exception e) {
- throw new ConfigurationException("Could not load HAPI properties", e);
- }
-
- Properties overrideProps = loadOverrideProperties();
- if (overrideProps != null) {
- properties.putAll(overrideProps);
- }
- properties.putAll(System.getenv().entrySet()
- .stream()
- .filter(e -> e.getValue() != null && properties.containsKey(e.getKey()))
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
- return properties;
- }
-
- /**
- * If a configuration file path is explicitly specified via -Dhapi.properties=, the properties there will
- * be used to override the entries in the default hapi.properties file (currently under WEB-INF/classes)
- *
- * @return properties loaded from the explicitly specified configuraiton file if there is one, or null otherwise.
- */
- private static Properties loadOverrideProperties() {
- String confFile = System.getProperty(HAPI_PROPERTIES);
- if (confFile != null) {
- try {
- Properties props = new Properties();
- props.load(new FileInputStream(confFile));
- return props;
- } catch (Exception e) {
- throw new ConfigurationException("Could not load HAPI properties file: " + confFile, e);
- }
- }
-
- return null;
- }
-
- private static String getProperty(String propertyName) {
- String env = "HAPI_" + propertyName.toUpperCase(Locale.US);
- env = env.replace(".", "_");
- env = env.replace("-", "_");
-
- String propertyValue = System.getenv(env);
- if (propertyValue != null) {
- return propertyValue;
- }
-
- Properties properties = HapiProperties.getProperties();
- if (properties != null) {
- propertyValue = properties.getProperty(propertyName);
- }
-
- return propertyValue;
- }
-
- private static String getProperty(String propertyName, String defaultValue) {
- String value = getProperty(propertyName);
-
- if (value != null && value.length() > 0) {
- return value;
- }
-
- return defaultValue;
- }
-
- private static Boolean getBooleanProperty(String propertyName, Boolean defaultValue) {
- String value = HapiProperties.getProperty(propertyName);
-
- if (value == null || value.length() == 0) {
- return defaultValue;
- }
-
- return Boolean.parseBoolean(value);
- }
-
- private static boolean getBooleanProperty(String propertyName, boolean defaultValue) {
- return getBooleanProperty(propertyName, Boolean.valueOf(defaultValue));
- }
-
- private static Integer getIntegerProperty(String propertyName, Integer defaultValue) {
- String value = HapiProperties.getProperty(propertyName);
-
- if (value == null || value.length() == 0) {
- return defaultValue;
- }
-
- return Integer.parseInt(value);
- }
-
- public static FhirVersionEnum getFhirVersion() {
- String fhirVersionString = HapiProperties.getProperty(FHIR_VERSION);
-
- if (fhirVersionString != null && fhirVersionString.length() > 0) {
- return FhirVersionEnum.valueOf(fhirVersionString);
- }
-
- return FhirVersionEnum.DSTU3;
- }
-
- public static boolean isBinaryStorageEnabled() {
- return HapiProperties.getBooleanProperty(BINARY_STORAGE_ENABLED, true);
- }
-
- public static ETagSupportEnum getEtagSupport() {
- String etagSupportString = HapiProperties.getProperty(ETAG_SUPPORT);
-
- if (etagSupportString != null && etagSupportString.length() > 0) {
- return ETagSupportEnum.valueOf(etagSupportString);
- }
-
- return ETagSupportEnum.ENABLED;
- }
-
- public static DaoConfig.ClientIdStrategyEnum getClientIdStrategy() {
- String idStrategy = HapiProperties.getProperty(CLIENT_ID_STRATEGY);
-
- if (idStrategy != null && idStrategy.length() > 0) {
- return DaoConfig.ClientIdStrategyEnum.valueOf(idStrategy);
- }
-
- return DaoConfig.ClientIdStrategyEnum.ALPHANUMERIC;
- }
-
- public static EncodingEnum getDefaultEncoding() {
- String defaultEncodingString = HapiProperties.getProperty(DEFAULT_ENCODING);
-
- if (defaultEncodingString != null && defaultEncodingString.length() > 0) {
- return EncodingEnum.valueOf(defaultEncodingString);
- }
-
- return EncodingEnum.JSON;
- }
-
- public static Boolean getDefaultPrettyPrint() {
- return HapiProperties.getBooleanProperty(DEFAULT_PRETTY_PRINT, true);
- }
-
- public static String getServerAddress() {
- return HapiProperties.getProperty(SERVER_ADDRESS);
- }
-
- public static Integer getDefaultPageSize() {
- return HapiProperties.getIntegerProperty(DEFAULT_PAGE_SIZE, 20);
- }
-
- public static Integer getMaximumPageSize() {
- return HapiProperties.getIntegerProperty(MAX_PAGE_SIZE, 200);
- }
-
- public static Integer getMaximumFetchSize() {
- return HapiProperties.getIntegerProperty(MAX_FETCH_SIZE, Integer.MAX_VALUE);
- }
-
- public static String getLoggerName() {
- return HapiProperties.getProperty(LOGGER_NAME, "fhirtest.access");
- }
-
- public static String getLoggerFormat() {
- return HapiProperties.getProperty(LOGGER_FORMAT, "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]");
- }
-
- public static String getLoggerErrorFormat() {
- return HapiProperties.getProperty(LOGGER_ERROR_FORMAT, "ERROR - ${requestVerb} ${requestUrl}");
- }
-
- public static Boolean getLoggerLogExceptions() {
- return HapiProperties.getBooleanProperty(LOGGER_LOG_EXCEPTIONS, true);
- }
-
- public static String getDataSourceDriver() {
- return HapiProperties.getProperty(DATASOURCE_DRIVER, "org.apache.derby.jdbc.EmbeddedDriver");
- }
-
- public static Integer getDataSourceMaxPoolSize() {
- return HapiProperties.getIntegerProperty(DATASOURCE_MAX_POOL_SIZE, 10);
- }
-
- public static String getDataSourceUrl() {
- return HapiProperties.getProperty(DATASOURCE_URL, "jdbc:derby:directory:target/jpaserver_derby_files;create=true");
- }
-
- public static String getDataSourceUsername() {
- return HapiProperties.getProperty(DATASOURCE_USERNAME);
- }
-
- public static String getDataSourcePassword() {
- return HapiProperties.getProperty(DATASOURCE_PASSWORD);
- }
-
- public static Boolean getAllowMultipleDelete() {
- return HapiProperties.getBooleanProperty(ALLOW_MULTIPLE_DELETE, false);
- }
-
- public static Boolean getAllowCascadingDeletes() {
- return HapiProperties.getBooleanProperty(ALLOW_CASCADING_DELETES, false);
- }
-
- public static Boolean getAllowExternalReferences() {
- return HapiProperties.getBooleanProperty(ALLOW_EXTERNAL_REFERENCES, false);
- }
-
- public static Boolean getExpungeEnabled() {
- return HapiProperties.getBooleanProperty("expunge_enabled", true);
- }
-
- 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 getAllowedBundleTypes() {
- return HapiProperties.getProperty(ALLOWED_BUNDLE_TYPES, "");
- }
-
- @Nonnull
- public static Set getSupportedResourceTypes() {
- String[] types = defaultString(getProperty("supported_resource_types")).split(",");
- return Arrays.stream(types)
- .map(StringUtils::trim)
- .filter(StringUtils::isNotBlank)
- .collect(Collectors.toSet());
- }
-
- public static String getServerName() {
- return HapiProperties.getProperty(SERVER_NAME, "Local Tester");
- }
-
- public static String getServerId() {
- return HapiProperties.getProperty(SERVER_ID, "home");
- }
-
- public static Boolean getAllowPlaceholderReferences() {
- return HapiProperties.getBooleanProperty(ALLOW_PLACEHOLDER_REFERENCES, true);
- }
-
- public static Boolean getSubscriptionEmailEnabled() {
- return HapiProperties.getBooleanProperty(SUBSCRIPTION_EMAIL_ENABLED, false);
- }
-
- public static Boolean getSubscriptionRestHookEnabled() {
- return HapiProperties.getBooleanProperty(SUBSCRIPTION_RESTHOOK_ENABLED, false);
- }
-
- public static Boolean getSubscriptionWebsocketEnabled() {
- return HapiProperties.getBooleanProperty(SUBSCRIPTION_WEBSOCKET_ENABLED, false);
- }
-
- public static Boolean getEmpiEnabled() {
- return HapiProperties.getBooleanProperty(EMPI_ENABLED, false);
- }
-
- public static Boolean getPartitioningEnabled() {
- return HapiProperties.getBooleanProperty(PARTITIONING_ENABLED, false);
- }
-
-
- public static String getPartitioningCrossPartitionReferenceMode() {
- return HapiProperties.getProperty(PARTITIONING_CROSS_PARTITION_REFERENCE_MODE, "NOT_ALLOWED");
- }
-
- public static Boolean getIncludePartitionInSearchHashes() {
- return HapiProperties.getBooleanProperty(PARTITIONING_INCLUDE_PARTITION_IN_SEARCH_HASHES, true);
- }
-
- public static Boolean getAllowContainsSearches() {
- return HapiProperties.getBooleanProperty(ALLOW_CONTAINS_SEARCHES, true);
- }
-
- public static Boolean getAllowOverrideDefaultSearchParams() {
- return HapiProperties.getBooleanProperty(ALLOW_OVERRIDE_DEFAULT_SEARCH_PARAMS, true);
- }
-
- public static String getEmailFrom() {
- return HapiProperties.getProperty(EMAIL_FROM, "some@test.com");
- }
-
- public static Boolean getEmailEnabled() {
- return HapiProperties.getBooleanProperty("email.enabled", false);
- }
-
- public static String getEmailHost() {
- return HapiProperties.getProperty("email.host");
- }
-
- public static Integer getEmailPort() {
- return HapiProperties.getIntegerProperty("email.port", 0);
- }
-
- public static String getEmailUsername() {
- return HapiProperties.getProperty("email.username");
- }
-
- public static String getEmailPassword() {
- 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() {
- String value = HapiProperties.getProperty(REUSE_CACHED_SEARCH_RESULTS_MILLIS, "60000");
- return Long.valueOf(value);
- }
-
- public static Long getExpireSearchResultsAfterMins() {
- String value = HapiProperties.getProperty(EXPIRE_SEARCH_RESULTS_AFTER_MINS, "60");
- return Long.valueOf(value);
- }
-
- public static Boolean getCorsAllowedCredentials() {
- return HapiProperties.getBooleanProperty(CORS_ALLOW_CREDENTIALS, false);
- }
-
- public static boolean getValidateRequestsEnabled() {
- return HapiProperties.getBooleanProperty(VALIDATE_REQUESTS_ENABLED, false);
- }
-
- public static boolean getValidateResponsesEnabled() {
- return HapiProperties.getBooleanProperty(VALIDATE_RESPONSES_ENABLED, false);
- }
-
- public static boolean getFilterSearchEnabled() {
- return HapiProperties.getBooleanProperty(FILTER_SEARCH_ENABLED, true);
- }
-
- public static boolean getGraphqlEnabled() {
- return HapiProperties.getBooleanProperty(GRAPHQL_ENABLED, true);
- }
-
- public static boolean getEnforceReferentialIntegrityOnDelete() {
- return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_DELETE, true);
- }
-
- public static boolean getEnforceReferentialIntegrityOnWrite() {
- return HapiProperties.getBooleanProperty(ENFORCE_REFERENTIAL_INTEGRITY_ON_WRITE, true);
- }
-
- public static boolean getAutoCreatePlaceholderReferenceTargets() {
- return HapiProperties.getBooleanProperty(AUTO_CREATE_PLACEHOLDER_REFERENCE_TARGETS, true);
- }
-
- public static boolean getEnableIndexMissingFields() {
- return HapiProperties.getBooleanProperty(ENABLE_INDEX_MISSING_FIELDS, false);
- }
-
- public static Integer getMaxBinarySize() {
- return getIntegerProperty(MAX_BINARY_SIZE, null);
- }
-
- private static boolean getPropertyBoolean(String thePropertyName, boolean theDefaultValue) {
- String value = getProperty(thePropertyName, Boolean.toString(theDefaultValue));
- return Boolean.parseBoolean(value);
- }
-
- private static T getPropertyEnum(String thePropertyName, Class theEnumType, T theDefaultValue) {
- String value = getProperty(thePropertyName, theDefaultValue.name());
- return (T) Enum.valueOf(theEnumType, value);
- }
-
- public static boolean getBulkExportEnabled() {
- return HapiProperties.getBooleanProperty(BULK_EXPORT_ENABLED, true);
- }
-
- public static boolean isFhirPathFilterInterceptorEnabled() {
- return HapiProperties.getBooleanProperty("fhirpath_interceptor.enabled", false);
- }
-
- public static boolean getPartitioningMultitenancyEnabled() {
- return HapiProperties.getBooleanProperty(PARTITIONING_MULTITENANCY_ENABLED, false);
- }
-
-
-}
-
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 f13ab64..c895c22 100644
--- a/src/main/java/ca/uhn/fhir/jpa/starter/JpaRestfulServer.java
+++ b/src/main/java/ca/uhn/fhir/jpa/starter/JpaRestfulServer.java
@@ -1,11 +1,22 @@
package ca.uhn.fhir.jpa.starter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Import;
+
import javax.servlet.ServletException;
+@Import(AppProperties.class)
public class JpaRestfulServer extends BaseJpaRestfulServer {
+ @Autowired
+ AppProperties appProperties;
+
private static final long serialVersionUID = 1L;
+ public JpaRestfulServer() {
+ super();
+ }
+
@Override
protected void initialize() throws ServletException {
super.initialize();
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
new file mode 100644
index 0000000..7a91683
--- /dev/null
+++ b/src/main/resources/application.yaml
@@ -0,0 +1,129 @@
+spring:
+ datasource:
+ url: 'jdbc:h2:file:./target/database/h2'
+ username: sa
+ password: null
+ driverClassName: org.h2.Driver
+ max-active: 15
+ profiles:
+ ### This is the FHIR version. Choose between, dstu2, dstu3, r4 or r5
+ active: r4
+ jpa:
+ properties:
+ hibernate.dialect: org.hibernate.dialect.H2Dialect
+ hibernate.search.model_mapping: ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory
+ hibernate.format_sql: false
+ hibernate.show_sql: false
+ hibernate.hbm2ddl.auto: update
+ hibernate.jdbc.batch_size: 20
+ hibernate.cache.use_query_cache: false
+ hibernate.cache.use_second_level_cache: false
+ hibernate.cache.use_structured_entries: false
+ hibernate.cache.use_minimal_puts: false
+ hibernate.search.default.directory_provider: filesystem
+ hibernate.search.default.indexBase: target/lucenefiles
+ hibernate.search.lucene_version: LUCENE_CURRENT
+
+hapi:
+ fhir:
+ defer_indexing_for_codesystems_of_size: 101
+# implementationguides:
+# -
+# url: https://build.fhir.org/ig/hl7dk/dk-medcom/branches/corrections/package.tgz
+# name: dk.fhir.ig.medcom-core
+# version: 0.8.0
+# -
+# name: hl7.fhir.uv.ips
+# version: 0.3.0
+
+ #supported_resource_types:
+ # - Patient
+ # - Observation
+# allow_cascading_deletes: true
+# allow_contains_searches: true
+# allow_external_references: true
+# allow_multiple_delete: true
+# allow_override_default_search_params: true
+# allow_placeholder_references: true
+# auto_create_placeholder_reference_targets: false
+# default_encoding: JSON
+# default_pretty_print: true
+# default_page_size: 20
+# enable_index_missing_fields: false
+# enforce_referential_integrity_on_delete: false
+# enforce_referential_integrity_on_write: false
+# etag_support_enabled: true
+# expunge_enabled: true
+# daoconfig_client_id_strategy: null
+# fhirpath_interceptor_enabled: false
+# filter_search_enabled: true
+# graphql_enabled: true
+ #partitioning:
+ # cross_partition_reference_mode: true
+ # multitenancy_enabled: true
+ # partitioning_include_in_search_hashes: true
+ #cors:
+ # allow_Credentials: true
+ # Supports multiple, comma separated allowed origin entries
+ # cors.allowed_origin=http://localhost:8080,https://localhost:8080,https://fhirtest.uhn.ca
+ # allowed_origin:
+ # - '*'
+
+# logger:
+# error_format: 'ERROR - ${requestVerb} ${requestUrl}'
+# format: >-
+# Path[${servletPath}] Source[${requestHeader.x-forwarded-for}]
+# Operation[${operationType} ${operationName} ${idOrResourceName}]
+# UA[${requestHeader.user-agent}] Params[${requestParameters}]
+# ResponseEncoding[${responseEncodingNoDefault}]
+# log_exceptions: true
+# name: fhirtest.access
+# max_binary_size: 104857600
+# max_page_size: 200
+# retain_cached_searches_mins: 60
+# reuse_cached_search_results_millis: 60000
+ tester:
+ -
+ id: home
+ name: Local Tester
+ server_address: 'http://localhost:8080/hapi-fhir-jpaserver/fhir'
+ refuse_to_fetch_third_party_urls: false
+ fhir_version: R4
+ -
+ id: global
+ name: Global Tester
+ server_address: "http://hapi.fhir.org/baseR4"
+ refuse_to_fetch_third_party_urls: false
+ fhir_version: R4
+# validation:
+# requests_enabled: true
+# responses_enabled: true
+# binary_storage_enabled: true
+# bulk_export_enabled: true
+# partitioning_multitenancy_enabled:
+# subscription:
+# resthook_enabled: false
+# websocket_enabled: false
+# email:
+# from: some@test.com
+# host: google.com
+# port:
+# username:
+# password:
+# auth:
+# startTlsEnable:
+# startTlsRequired:
+# quitWait:
+
+
+#
+#elasticsearch:
+# debug:
+# pretty_print_json_log: false
+# refresh_after_write: false
+# enabled: false
+# password: SomePassword
+# required_index_status: YELLOW
+# rest_url: 'http://localhost:9200'
+# schema_management_strategy: CREATE
+# username: SomeUsername
diff --git a/src/main/resources/hapi.properties b/src/main/resources/hapi.properties
deleted file mode 100644
index b7ef0f8..0000000
--- a/src/main/resources/hapi.properties
+++ /dev/null
@@ -1,167 +0,0 @@
-# Adjust this to set the version of FHIR supported by this server. See
-# FhirVersionEnum for a list of available constants. Example values include
-# DSTU2, DSTU3, R4.
-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
-# server, put the DNS name of that server here.
-#
-# Note that this is also the address that the hapi-fhir-testpage-overlay
-# (the web UI similar to the one at http://hapi.fhir.org) will use to
-# connect internally to the FHIR server, so this also needs to be a name
-# accessible from the server itself.
-server_address=http://localhost:8080/hapi-fhir-jpaserver/fhir/
-
-enable_index_missing_fields=false
-auto_create_placeholder_reference_targets=false
-enforce_referential_integrity_on_write=false
-enforce_referential_integrity_on_delete=false
-default_encoding=JSON
-etag_support=ENABLED
-reuse_cached_search_results_millis=60000
-retain_cached_searches_mins=60
-default_page_size=20
-max_page_size=200
-allow_override_default_search_params=true
-allow_contains_searches=true
-allow_multiple_delete=true
-allow_external_references=true
-allow_cascading_deletes=true
-allow_placeholder_references=true
-expunge_enabled=true
-persistence_unit_name=HAPI_PU
-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.h2.Driver
-datasource.url=jdbc:h2:file:./target/database/h2
-datasource.username=
-datasource.password=
-server.name=Local Tester
-server.id=home
-test.port=
-
-###################################################
-# Binary Storage (104857600 = 100mb)
-###################################################
-max_binary_size=104857600
-
-###################################################
-# Validation
-###################################################
-# Should all incoming requests be validated
-validation.requests.enabled=false
-# Should outgoing responses be validated
-validation.responses.enabled=false
-
-###################################################
-# Search Features
-###################################################
-filter_search.enabled=true
-graphql.enabled=true
-# See FhirPathFilterInterceptor
-fhirpath_interceptor.enabled=false
-
-###################################################
-# Supported Resources
-###################################################
-# Enable the following property if you want to customize the
-# list of resources that is supported by the server (i.e. to
-# disable specific resources)
-#supported_resource_types=Patient,Observation,Encounter
-
-###################################################
-# Database Settings
-###################################################
-hibernate.dialect=org.hibernate.dialect.H2Dialect
-hibernate.search.model_mapping=ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory
-hibernate.format_sql=false
-hibernate.show_sql=false
-hibernate.hbm2ddl.auto=update
-hibernate.jdbc.batch_size=20
-hibernate.cache.use_query_cache=false
-hibernate.cache.use_second_level_cache=false
-hibernate.cache.use_structured_entries=false
-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
-
-##################################################
-# ElasticSearch
-# Note that using ElasticSearch is disabled by
-# default and the server will use Lucene instead.
-##################################################
-elasticsearch.enabled=false
-elasticsearch.rest_url=http://localhost:9200
-elasticsearch.username=SomeUsername
-elasticsearch.password=SomePassword
-elasticsearch.required_index_status=YELLOW
-elasticsearch.schema_management_strategy=CREATE
-# Immediately refresh indexes after every write. This is very bad for
-# performance, but can be helpful for testing.
-elasticsearch.debug.refresh_after_write=false
-elasticsearch.debug.pretty_print_json_log=false
-
-
-##################################################
-# Binary Storage Operations
-##################################################
-binary_storage.enabled=true
-
-##################################################
-# Bulk Data Specification
-##################################################
-bulk.export.enabled=true
-
-##################################################
-# CORS Settings
-##################################################
-cors.enabled=true
-cors.allowCredentials=true
-# Supports multiple, comma separated allowed origin entries
-# cors.allowed_origin=http://localhost:8080,https://localhost:8080,https://fhirtest.uhn.ca
-cors.allowed_origin=*
-
-##################################################
-# Allowed Bundle Types for persistence (defaults are: COLLECTION,DOCUMENT,MESSAGE)
-##################################################
-#allowed_bundle_types=COLLECTION,DOCUMENT,MESSAGE,TRANSACTION,TRANSACTIONRESPONSE,BATCH,BATCHRESPONSE,HISTORY,SEARCHSET
-
-##################################################
-# Subscriptions
-##################################################
-
-# Enable REST Hook Subscription Channel
-subscription.resthook.enabled=false
-
-# Enable Email Subscription Channel
-subscription.email.enabled=false
-email.enabled=false
-email.from=some@test.com
-email.host=
-email.port=0
-email.username=
-email.password=
-
-# Enable Websocket Subscription Channel
-subscription.websocket.enabled=false
-
-###################################################
-# EMPI
-###################################################
-empi.enabled=false
-
-###################################################
-# Partitioning And Multitenancy
-###################################################
-partitioning.enabled=false
-partitioning.cross_partition_reference_mode=NOT_ALLOWED
-partitioning.partitioning_include_in_search_hashes=true
-partitioning.multitenancy.enabled=false
-
-#daoconfig.client_id_strategy=ANY
-
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index 9364495..8039731 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -9,24 +9,6 @@
-
- DEBUG
- ${smile.basedir}/log/empi-troubleshooting.log
-
- ${smile.basedir}/log/empi-troubleshooting.log.%i.gz
- 1
- 9
-
-
- 5MB
-
-
- %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n${log.stackfilter.pattern}
-
-
-
-
-
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 6ce88b0..0000000
--- a/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
- org.springframework.web.context.ContextLoaderListener
-
-
- contextClass
-
- ca.uhn.fhir.jpa.starter.ApplicationContext
-
-
-
- contextConfigLocation
-
-
-
-
-
-
- spring
- org.springframework.web.servlet.DispatcherServlet
-
- contextClass
- org.springframework.web.context.support.AnnotationConfigWebApplicationContext
-
-
- contextConfigLocation
-
- ca.uhn.fhir.jpa.starter.FhirTesterConfig
-
-
- 2
-
-
- spring
- /
-
-
-
- fhirServlet
- ca.uhn.fhir.jpa.starter.JpaRestfulServer
- 1
-
-
- fhirServlet
- /fhir/*
-
-
-
diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/Demo.java b/src/test/java/ca/uhn/fhir/jpa/starter/Demo.java
new file mode 100644
index 0000000..5dadf14
--- /dev/null
+++ b/src/test/java/ca/uhn/fhir/jpa/starter/Demo.java
@@ -0,0 +1,20 @@
+package ca.uhn.fhir.jpa.starter;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+
+@ServletComponentScan(basePackageClasses = {JpaRestfulServer.class})
+@SpringBootApplication(exclude = ElasticsearchRestClientAutoConfiguration.class)
+public class Demo {
+
+ public static void main(String[] args) {
+
+ System.setProperty("spring.profiles.active", "r4");
+ System.setProperty("spring.batch.job.enabled", "false");
+ SpringApplication.run(Demo.class, args);
+
+ //Server is now accessible at eg. http://localhost:8080/metadata
+ }
+}
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 b34e67d..aeab8d7 100644
--- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java
+++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java
@@ -5,79 +5,53 @@ import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
-import ca.uhn.fhir.test.utilities.JettyUtil;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
import org.hl7.fhir.instance.model.api.IIdType;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-
-import java.nio.file.Paths;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
+ {
+ "spring.batch.job.enabled=false",
+ "spring.profiles.active=dstu2",
+ "spring.datasource.url=jdbc:h2:mem:dbr2"
+ })
public class ExampleServerDstu2IT {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
- private static IGenericClient ourClient;
- private static FhirContext ourCtx;
- private static int ourPort;
- private static Server ourServer;
+ private IGenericClient ourClient;
+ private FhirContext ourCtx;
- static {
- HapiProperties.forceReload();
- HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "DSTU2");
- HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr2");
- ourCtx = FhirContext.forDstu2();
- }
+ @LocalServerPort
+ private int port;
+
+ @Test
+ void testCreateAndRead() {
- @Test
- public void testCreateAndRead() {
- ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
String methodName = "testCreateResourceConditional";
Patient pt = new Patient();
pt.addName().addFamily(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().get(0).getValue());
}
- @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);
+ @BeforeEach
+ void beforeEach() {
+ ourCtx = FhirContext.forDstu2();
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
- String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
+ String ourServerBase = "http://localhost:" + port + "/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/ExampleServerDstu3IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java
index 5ff9de5..208ca01 100644
--- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java
+++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java
@@ -7,9 +7,6 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
-import ca.uhn.fhir.test.utilities.JettyUtil;
-import org.eclipse.jetty.server.Server;
-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;
@@ -18,39 +15,44 @@ import org.hl7.fhir.dstu3.model.Observation;
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.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.URI;
-import java.nio.file.Paths;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import static ca.uhn.fhir.util.TestUtil.waitForSize;
import static org.junit.jupiter.api.Assertions.assertEquals;
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
+ {
+ "spring.batch.job.enabled=false",
+ "spring.profiles.active=dstu3",
+ "spring.datasource.url=jdbc:h2:mem:dbr3",
+ "hapi.fhir.subscription.websocket_enabled=true",
+ "hapi.fhir.allow_external_references=true",
+ "hapi.fhir.allow_placeholder_references=true",
+ })
+
+
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;
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
+ private IGenericClient ourClient;
+ private FhirContext ourCtx;
- 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();
- }
+ @LocalServerPort
+ private int port;
@Test
public void testCreateAndRead() {
- ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
+
String methodName = "testCreateResourceConditional";
Patient pt = new Patient();
@@ -90,7 +92,7 @@ public class ExampleServerDstu3IT {
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
myWebSocketClient.start();
- URI echoUri = new URI("ws://localhost:" + ourPort + "/hapi-fhir-jpaserver/websocket");
+ URI echoUri = new URI("ws://localhost:" + port + "/hapi-fhir-jpaserver/websocket");
ClientUpgradeRequest request = new ClientUpgradeRequest();
ourLog.info("Connecting to : {}", echoUri);
Future connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
@@ -119,39 +121,15 @@ public class ExampleServerDstu3IT {
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);
+ @BeforeEach
+ void beforeEach() {
+ ourCtx = FhirContext.forDstu3();
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
- String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
+ String ourServerBase = "http://localhost:" + port + "/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 c610481..dbcfff4 100644
--- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java
+++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java
@@ -7,26 +7,20 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
-import ca.uhn.fhir.test.utilities.JettyUtil;
import ca.uhn.fhir.util.BundleUtil;
-import org.eclipse.jetty.server.Server;
-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.instance.model.api.IIdType;
-import org.hl7.fhir.r4.model.Bundle;
-import org.hl7.fhir.r4.model.Observation;
-import org.hl7.fhir.r4.model.Patient;
-import org.hl7.fhir.r4.model.Person;
-import org.hl7.fhir.r4.model.Reference;
-import org.hl7.fhir.r4.model.Subscription;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.hl7.fhir.r4.model.*;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.URI;
-import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@@ -38,54 +32,58 @@ import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
+ {
+ "spring.batch.job.enabled=false",
+ "spring.profiles.active=r4",
+ "spring.datasource.url=jdbc:h2:mem:dbr4",
+ "hapi.fhir.subscription.websocket_enabled=true",
+ "hapi.fhir.empi_enabled=true",
+ //Override is currently required when using Empi as the construction of the Empi beans are ambiguous as they are constructed multiple places. This is evident when running in a spring boot environment
+ "spring.main.allow-bean-definition-overriding=true"
+ })
public class ExampleServerR4IT {
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerR4IT.class);
- private static IGenericClient ourClient;
- private static FhirContext ourCtx;
- private static int ourPort;
- private static Server ourServer;
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
+ private IGenericClient ourClient;
+ private FhirContext ourCtx;
- static {
- HapiProperties.forceReload();
- HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr4");
- HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R4");
- HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
- HapiProperties.setProperty(HapiProperties.EMPI_ENABLED, "true");
- ourCtx = FhirContext.forR4();
- }
+ @LocalServerPort
+ private int port;
- @Test
- public void testCreateAndRead() {
- ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
- 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();
+ @Test
+ void testCreateAndRead() {
- Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
- assertEquals(methodName, pt2.getName().get(0).getFamily());
+ String methodName = "testCreateResourceConditional";
- // Test EMPI
+ 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();
- // Wait until the EMPI message has been processed
- await().until(() -> getPeople().size() > 0);
- List persons = getPeople();
+ Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
+ assertEquals(methodName, pt2.getName().get(0).getFamily());
- // Verify a Person was created that links to our Patient
- Optional personLinkToCreatedPatient = persons.stream()
- .map(Person::getLink)
- .flatMap(Collection::stream)
- .map(Person.PersonLinkComponent::getTarget)
- .map(Reference::getReference)
- .filter(pid -> id.toUnqualifiedVersionless().getValue().equals(pid))
- .findAny();
- assertTrue(personLinkToCreatedPatient.isPresent());
- }
+ // Test EMPI
+
+ // Wait until the EMPI message has been processed
+ await().until(() -> getPeople().size() > 0);
+ List persons = getPeople();
+
+ // Verify a Person was created that links to our Patient
+ Optional personLinkToCreatedPatient = persons.stream()
+ .map(Person::getLink)
+ .flatMap(Collection::stream)
+ .map(Person.PersonLinkComponent::getTarget)
+ .map(Reference::getReference)
+ .filter(pid -> id.toUnqualifiedVersionless().getValue().equals(pid))
+ .findAny();
+ assertTrue(personLinkToCreatedPatient.isPresent());
+ }
private List getPeople() {
Bundle bundle = ourClient.search().forResource(Person.class).cacheControl(new CacheControlDirective().setNoCache(true)).returnBundle(Bundle.class).execute();
@@ -93,103 +91,76 @@ public class ExampleServerR4IT {
}
@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");
+ 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);
+ 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();
+ MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute();
+ IIdType mySubscriptionId = methodOutcome.getId();
- // Wait for the subscription to be activated
- await().until(() -> activeSubscriptionCount() == 3);
+ // Wait for the subscription to be activated
+ await().until(() -> activeSubscriptionCount() == 3);
- /*
- * Attach websocket
- */
+ /*
+ * Attach websocket
+ */
- WebSocketClient myWebSocketClient = new WebSocketClient();
- SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
+ 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);
+ myWebSocketClient.start();
+ URI echoUri = new URI("ws://localhost:" + port + "/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());
+ 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();
+ /*
+ * 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);
+ // Give some time for the subscription to deliver
+ Thread.sleep(2000);
- /*
- * Ensure that we receive a ping on the websocket
- */
- waitForSize(1, () -> mySocketImplementation.myPingCount);
+ /*
+ * Ensure that we receive a ping on the websocket
+ */
+ waitForSize(1, () -> mySocketImplementation.myPingCount);
- /*
- * Clean up
- */
- ourClient.delete().resourceById(mySubscriptionId).execute();
- }
+ /*
+ * Clean up
+ */
+ ourClient.delete().resourceById(mySubscriptionId).execute();
+ }
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();
}
- @AfterAll
- public static void afterClass() throws Exception {
- ourServer.stop();
- }
- @BeforeAll
- public static void beforeClass() throws Exception {
- String path = Paths.get("").toAbsolutePath().toString();
+ @BeforeEach
+ void beforeEach() {
- ourLog.info("Project base path is: {}", path);
-
- ourServer = new Server(0);
-
- WebAppContext webAppContext = new WebAppContext();
- webAppContext.setContextPath("/hapi-fhir-jpaserver");
- webAppContext.setDisplayName("HAPI FHIR");
- 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 = HapiProperties.getServerAddress();
- 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();
- }
+ ourCtx = FhirContext.forR4();
+ ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
+ ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
+ String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
+ ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
+ ourClient.registerInterceptor(new LoggingInterceptor(true));
+ }
}
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 ea9855f..9eea4d6 100644
--- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java
+++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java
@@ -1,5 +1,9 @@
package ca.uhn.fhir.jpa.starter;
+import static ca.uhn.fhir.util.TestUtil.waitForSize;
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.EncodingEnum;
@@ -7,9 +11,9 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
-import ca.uhn.fhir.test.utilities.JettyUtil;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
+import java.net.URI;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
@@ -20,38 +24,34 @@ import org.hl7.fhir.r5.model.Observation;
import org.hl7.fhir.r5.model.Patient;
import org.hl7.fhir.r5.model.Subscription;
import org.hl7.fhir.r5.model.SubscriptionTopic;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
-import java.net.URI;
-import java.nio.file.Paths;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-import static ca.uhn.fhir.util.TestUtil.waitForSize;
-import static org.awaitility.Awaitility.await;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
+ {
+ "spring.batch.job.enabled=false",
+ "spring.profiles.active=r5",
+ "spring.datasource.url=jdbc:h2:mem:dbr5",
+ "hapi.fhir.subscription.websocket_enabled=true"
+ })
public class ExampleServerR5IT {
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerR5IT.class);
- private static IGenericClient ourClient;
- private static FhirContext ourCtx;
- private static int ourPort;
- private static Server ourServer;
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
+ private IGenericClient ourClient;
+ private FhirContext ourCtx;
+
+ @LocalServerPort
+ private int port;
- static {
- HapiProperties.forceReload();
- HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr5");
- HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R5");
- HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
- ourCtx = FhirContext.forR5();
- }
@Test
public void testCreateAndRead() {
- ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
+
String methodName = "testCreateResourceConditional";
Patient pt = new Patient();
@@ -97,7 +97,7 @@ public class ExampleServerR5IT {
SocketImplementation mySocketImplementation = new SocketImplementation(mySubscriptionId.getIdPart(), EncodingEnum.JSON);
myWebSocketClient.start();
- URI echoUri = new URI("ws://localhost:" + ourPort + "/hapi-fhir-jpaserver/websocket");
+ URI echoUri = new URI("ws://localhost:" + port + "/hapi-fhir-jpaserver/websocket");
ClientUpgradeRequest request = new ClientUpgradeRequest();
ourLog.info("Connecting to : {}", echoUri);
Future connection = myWebSocketClient.connect(mySocketImplementation, echoUri, request);
@@ -115,7 +115,7 @@ public class ExampleServerR5IT {
/*
* Ensure that we receive a ping on the websocket
*/
- await().until(()->mySocketImplementation.myPingCount > 0);
+ await().until(() -> mySocketImplementation.myPingCount > 0);
/*
* Clean up
@@ -123,41 +123,14 @@ public class ExampleServerR5IT {
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.setDisplayName("HAPI FHIR");
- 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);
+ @BeforeEach
+ void beforeEach() {
+ ourCtx = FhirContext.forR5();
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
- String ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
-
+ String ourServerBase = "http://localhost:" + port + "/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/MultitenantServerR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java
index 25e7315..856ad70 100644
--- a/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java
+++ b/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java
@@ -7,44 +7,42 @@ import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.client.interceptor.UrlTenantSelectionInterceptor;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
-import ca.uhn.fhir.test.utilities.JettyUtil;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.hl7.fhir.r4.model.Bundle;
-import org.hl7.fhir.r4.model.CodeType;
-import org.hl7.fhir.r4.model.IntegerType;
-import org.hl7.fhir.r4.model.Parameters;
-import org.hl7.fhir.r4.model.Patient;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.hl7.fhir.r4.model.*;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-
-import java.nio.file.Paths;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class, properties =
+ {
+ "spring.batch.job.enabled=false",
+ "spring.profiles.active=r4",
+ "spring.datasource.url=jdbc:h2:mem:dbr4-mt",
+ "hapi.fhir.subscription.websocket_enabled=true",
+ "hapi.fhir.partitioning.partitioning_include_in_search_hashes=false"
+
+ })
public class MultitenantServerR4IT {
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MultitenantServerR4IT.class);
- private static IGenericClient ourClient;
- private static FhirContext ourCtx;
- private static int ourPort;
- private static Server ourServer;
+
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class);
+ private IGenericClient ourClient;
+ private FhirContext ourCtx;
+
+ @LocalServerPort
+ private int port;
+
private static UrlTenantSelectionInterceptor ourClientTenantInterceptor;
- static {
- HapiProperties.forceReload();
- HapiProperties.setProperty(HapiProperties.DATASOURCE_URL, "jdbc:h2:mem:dbr4-mt");
- HapiProperties.setProperty(HapiProperties.FHIR_VERSION, "R4");
- HapiProperties.setProperty(HapiProperties.SUBSCRIPTION_WEBSOCKET_ENABLED, "true");
- HapiProperties.setProperty(HapiProperties.PARTITIONING_ENABLED, "true");
- HapiProperties.setProperty(HapiProperties.PARTITIONING_MULTITENANCY_ENABLED, "true");
- ourCtx = FhirContext.forR4();
- }
@Test
public void testCreateAndReadInTenantA() {
- ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
+
// Create tenant A
ourClientTenantInterceptor.setTenantId("DEFAULT");
@@ -70,7 +68,7 @@ public class MultitenantServerR4IT {
@Test
public void testCreateAndReadInTenantB() {
- ourLog.info("Base URL is: " + HapiProperties.getServerAddress());
+
// Create tenant A
ourClientTenantInterceptor.setTenantId("DEFAULT");
@@ -94,45 +92,16 @@ public class MultitenantServerR4IT {
assertEquals("Family B", pt2.getName().get(0).getFamily());
}
- @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.setDisplayName("HAPI FHIR");
- 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 = HapiProperties.getServerAddress();
- ourServerBase = "http://localhost:" + ourPort + "/hapi-fhir-jpaserver/fhir/";
-
- ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
- ourClient.registerInterceptor(new LoggingInterceptor(true));
+ @BeforeEach
+ void beforeEach() {
ourClientTenantInterceptor = new UrlTenantSelectionInterceptor();
+ ourCtx = FhirContext.forR4();
+ ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
+ ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
+ String ourServerBase = "http://localhost:" + port + "/hapi-fhir-jpaserver/fhir/";
+ ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
+ ourClient.registerInterceptor(new LoggingInterceptor(true));
ourClient.registerInterceptor(ourClientTenantInterceptor);
}
-
- public static void main(String[] theArgs) throws Exception {
- ourPort = 8080;
- beforeClass();
- }
}
diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/RandomServerPortProvider.java b/src/test/java/ca/uhn/fhir/jpa/starter/RandomServerPortProvider.java
deleted file mode 100644
index 65446f0..0000000
--- a/src/test/java/ca/uhn/fhir/jpa/starter/RandomServerPortProvider.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package ca.uhn.fhir.jpa.starter;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides server ports
- */
-public class RandomServerPortProvider {
-
- private static List ourPorts = new ArrayList();
-
- public static int findFreePort() {
- ServerSocket server;
- try {
- server = new ServerSocket(0);
- int port = server.getLocalPort();
- ourPorts.add(port);
- server.close();
- Thread.sleep(500);
- return port;
- } catch (IOException e) {
- throw new Error(e);
- } catch (InterruptedException e) {
- throw new Error(e);
- }
- }
-
- public static List list() {
- return ourPorts;
- }
-
-}
-
\ No newline at end of file
diff --git a/src/test/resources/application-integrationtest.yaml b/src/test/resources/application-integrationtest.yaml
new file mode 100644
index 0000000..038a343
--- /dev/null
+++ b/src/test/resources/application-integrationtest.yaml
@@ -0,0 +1,104 @@
+spring:
+ datasource:
+ url: 'jdbc:h2:file:./target/database/h2'
+ username: sa
+ password: null
+ driverClassName: org.h2.Driver
+ max-active: 15
+ profiles:
+ ### This is the FHIR version. Choose between, dstu2, dstu3, r4 or r5
+ active: r4
+
+hapi:
+ fhir:
+ #supported_resource_types:
+ # - Patient
+ # - Observation
+# allow_cascading_deletes: true
+# allow_contains_searches: true
+# allow_external_references: true
+# allow_multiple_delete: true
+# allow_override_default_search_params: true
+# allow_placeholder_references: true
+# auto_create_placeholder_reference_targets: false
+# default_encoding: JSON
+# default_pretty_print: true
+# default_page_size: 20
+# enable_index_missing_fields: false
+# enforce_referential_integrity_on_delete: false
+# enforce_referential_integrity_on_write: false
+# etag_support_enabled: true
+# expunge_enabled: true
+# daoconfig_client_id_strategy: null
+# fhirpath_interceptor_enabled: false
+# filter_search_enabled: true
+# graphql_enabled: true
+ #partitioning:
+ # cross_partition_reference_mode: true
+ # multitenancy_enabled: true
+ # partitioning_include_in_search_hashes: true
+ #cors:
+ # allow_Credentials: true
+ # Supports multiple, comma separated allowed origin entries
+ # cors.allowed_origin=http://localhost:8080,https://localhost:8080,https://fhirtest.uhn.ca
+ # allowed_origin:
+ # - '*'
+
+# logger:
+# error_format: 'ERROR - ${requestVerb} ${requestUrl}'
+# format: >-
+# Path[${servletPath}] Source[${requestHeader.x-forwarded-for}]
+# Operation[${operationType} ${operationName} ${idOrResourceName}]
+# UA[${requestHeader.user-agent}] Params[${requestParameters}]
+# ResponseEncoding[${responseEncodingNoDefault}]
+# log_exceptions: true
+# name: fhirtest.access
+# max_binary_size: 104857600
+# max_page_size: 200
+# retain_cached_searches_mins: 60
+# reuse_cached_search_results_millis: 60000
+ tester:
+ -
+ id: home
+ name: Local Tester
+ server_address: 'http://localhost:8080/hapi-fhir-jpaserver/fhir'
+ refuse_to_fetch_third_party_urls: false
+ fhir_version: R4
+ -
+ id: global
+ name: Global Tester
+ server_address: "http://hapi.fhir.org/baseR4"
+ refuse_to_fetch_third_party_urls: false
+ fhir_version: R4
+# validation:
+# requests_enabled: true
+# responses_enabled: true
+# binary_storage_enabled: true
+# bulk_export_enabled: true
+# partitioning_multitenancy_enabled:
+# subscription:
+# resthook_enabled: false
+# websocket_enabled: false
+# email:
+# from: some@test.com
+# host: google.com
+# port:
+# username:
+# password:
+# auth:
+# startTlsEnable:
+# startTlsRequired:
+# quitWait:
+
+
+#
+#elasticsearch:
+# debug:
+# pretty_print_json_log: false
+# refresh_after_write: false
+# enabled: false
+# password: SomePassword
+# required_index_status: YELLOW
+# rest_url: 'http://localhost:9200'
+# schema_management_strategy: CREATE
+# username: SomeUsername