diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 435d58b..9919452 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -17,9 +17,9 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Build with Maven run: mvn -B package --file pom.xml diff --git a/pom.xml b/pom.xml index 6a69b1b..6019652 100644 --- a/pom.xml +++ b/pom.xml @@ -14,13 +14,13 @@ ca.uhn.hapi.fhir hapi-fhir - 5.7.2 + 6.0.0 hapi-fhir-jpaserver-starter - 8 + 11 @@ -405,7 +405,7 @@ maven-compiler-plugin 3.8.1 - 8 + 11 diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java index a4ab834..af8be7c 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -11,7 +11,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; @ConfigurationProperties(prefix = "hapi.fhir") @Configuration @@ -71,9 +74,6 @@ public class AppProperties { private boolean store_resource_in_lucene_index_enabled = false; private NormalizedQuantitySearchLevel normalized_quantity_search_level = NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED; - private Integer search_coord_core_pool_size = 20; - private Integer search_coord_max_pool_size = 100; - private Integer search_coord_queue_capacity = 200; private Boolean use_apache_address_strategy = false; private Boolean use_apache_address_strategy_https = false; @@ -496,24 +496,6 @@ public class AppProperties { this.normalized_quantity_search_level = normalized_quantity_search_level; } - public Integer getSearch_coord_core_pool_size() { return search_coord_core_pool_size; } - - public void setSearch_coord_core_pool_size(Integer search_coord_core_pool_size) { - this.search_coord_core_pool_size = search_coord_core_pool_size; - } - - public Integer getSearch_coord_max_pool_size() { return search_coord_max_pool_size; } - - public void setSearch_coord_max_pool_size(Integer search_coord_max_pool_size) { - this.search_coord_max_pool_size = search_coord_max_pool_size; - } - - public Integer getSearch_coord_queue_capacity() { return search_coord_queue_capacity; } - - public void setSearch_coord_queue_capacity(Integer search_coord_queue_capacity) { - this.search_coord_queue_capacity = search_coord_queue_capacity; - } - public boolean getInstall_transitive_ig_dependencies() { return install_transitive_ig_dependencies; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java index 2cf60f5..0ba2072 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java @@ -1,7 +1,7 @@ package ca.uhn.fhir.jpa.starter; -import ca.uhn.fhir.jpa.starter.mdm.MdmConfig; import ca.uhn.fhir.jpa.starter.annotations.OnEitherVersion; +import ca.uhn.fhir.jpa.starter.mdm.MdmConfig; import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig; import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig; import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig; diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java b/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java index fb48ffd..6d8a0f2 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/BaseJpaRestfulServer.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.jpa.starter; +import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.support.IValidationSupport; @@ -9,20 +10,15 @@ import ca.uhn.fhir.interceptor.api.IInterceptorService; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor; +import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor; import ca.uhn.fhir.jpa.bulk.export.provider.BulkDataExportProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor; import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc; import ca.uhn.fhir.jpa.packages.PackageInstallationSpec; import ca.uhn.fhir.jpa.partition.PartitionManagementProvider; -import ca.uhn.fhir.jpa.provider.IJpaSystemProvider; -import ca.uhn.fhir.jpa.provider.JpaCapabilityStatementProvider; -import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2; -import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider; -import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider; +import ca.uhn.fhir.jpa.provider.*; import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; -import ca.uhn.fhir.jpa.provider.ValueSetOperationProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.mdm.provider.MdmProviderLoader; @@ -30,19 +26,9 @@ import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.narrative2.NullNarrativeGenerator; import ca.uhn.fhir.rest.openapi.OpenApiInterceptor; -import ca.uhn.fhir.rest.server.ApacheProxyAddressStrategy; -import ca.uhn.fhir.rest.server.ETagSupportEnum; -import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy; -import ca.uhn.fhir.rest.server.IncomingRequestAddressStrategy; -import ca.uhn.fhir.rest.server.RestfulServer; -import ca.uhn.fhir.rest.server.interceptor.CorsInterceptor; -import ca.uhn.fhir.rest.server.interceptor.FhirPathFilterInterceptor; -import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; -import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; -import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; -import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor; +import ca.uhn.fhir.rest.server.*; +import ca.uhn.fhir.rest.server.interceptor.*; import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor; -import ca.uhn.fhir.rest.server.provider.ReindexProvider; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; @@ -50,19 +36,16 @@ import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.ResultSeverityEnum; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import javax.servlet.ServletException; import org.hl7.fhir.r4.model.Bundle.BundleType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.web.cors.CorsConfiguration; +import javax.servlet.ServletException; +import java.util.*; +import java.util.stream.Collectors; + public class BaseJpaRestfulServer extends RestfulServer { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaRestfulServer.class); @@ -80,6 +63,8 @@ public class BaseJpaRestfulServer extends RestfulServer { @Autowired IJpaSystemProvider jpaSystemProvider; @Autowired + ValueSetOperationProvider myValueSetOperationProvider; + @Autowired IInterceptorBroadcaster interceptorBroadcaster; @Autowired DatabaseBackedPagingProvider databaseBackedPagingProvider; @@ -93,10 +78,11 @@ public class BaseJpaRestfulServer extends RestfulServer { BulkDataExportProvider bulkDataExportProvider; @Autowired PartitionManagementProvider partitionManagementProvider; - @Autowired - ValueSetOperationProvider valueSetOperationProvider; - @Autowired - ReindexProvider reindexProvider; + //TODO GGG RE-ADD ONCE FIXED IN HAPI-FHIR +// @Autowired +// ValueSetOperationProvider valueSetOperationProvider; + @Autowired + ReindexProvider reindexProvider; @Autowired BinaryStorageInterceptor binaryStorageInterceptor; @Autowired @@ -149,7 +135,8 @@ public class BaseJpaRestfulServer extends RestfulServer { registerProviders(resourceProviderFactory.createProviders()); registerProvider(jpaSystemProvider); - + //TODO GGG RE-ADD ONCE FIXED IN HAPI-FHIR +// registerProvider(myValueSetOperationProvider); /* * The conformance provider exports the supported resources, search parameters, etc for * this server. The JPA version adds resourceProviders counts to the exported statement, so it @@ -376,7 +363,8 @@ public class BaseJpaRestfulServer extends RestfulServer { } // valueSet Operations i.e $expand - registerProvider(valueSetOperationProvider); + //TODO GGG RE-ADD ONCE FIXED IN HAPI-FHIR +// registerProvider(myValueSetOperationProvider); //reindex Provider $reindex registerProvider(reindexProvider); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ElasticsearchConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/ElasticsearchConfig.java index fd27e84..21216e6 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ElasticsearchConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ElasticsearchConfig.java @@ -14,7 +14,7 @@ public class ElasticsearchConfig { @Autowired private ConfigurableEnvironment configurableEnvironment; - @Bean() + @Bean public ElasticsearchSvcImpl elasticsearchSvc() { if (EnvironmentHelper.isElasticsearchEnabled(configurableEnvironment)) { String elasticsearchUrl = EnvironmentHelper.getElasticsearchServerUrl(configurableEnvironment); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/EnvironmentHelper.java b/src/main/java/ca/uhn/fhir/jpa/starter/EnvironmentHelper.java index 96a958f..11b6128 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/EnvironmentHelper.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/EnvironmentHelper.java @@ -22,7 +22,10 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.PropertySource; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; public class EnvironmentHelper { 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 3896167..15638f5 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigCommon.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigCommon.java @@ -1,8 +1,8 @@ package ca.uhn.fhir.jpa.starter; import ca.uhn.fhir.jpa.api.config.DaoConfig; +import ca.uhn.fhir.jpa.binary.api.IBinaryStorageSvc; import ca.uhn.fhir.jpa.binstore.DatabaseBlobBinaryStorageSvcImpl; -import ca.uhn.fhir.jpa.binstore.IBinaryStorageSvc; import ca.uhn.fhir.jpa.config.HibernatePropertiesProvider; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings.CrossPartitionReferenceMode; @@ -14,8 +14,6 @@ import ca.uhn.fhir.rest.server.mail.IMailSvc; import ca.uhn.fhir.rest.server.mail.MailConfig; import ca.uhn.fhir.rest.server.mail.MailSvc; import com.google.common.base.Strings; -import java.util.HashSet; -import java.util.Optional; import org.hl7.fhir.dstu2.model.Subscription; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.context.annotation.Bean; @@ -25,6 +23,9 @@ import org.springframework.context.annotation.Primary; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; +import java.util.HashSet; +import java.util.Optional; + /** * This is the primary configuration file for the example server */ @@ -75,7 +76,7 @@ public class FhirServerConfigCommon { /** * Configure FHIR properties around the the JPA server via this bean */ - @Bean() + @Bean public DaoConfig daoConfig(AppProperties appProperties) { DaoConfig retVal = new DaoConfig(); @@ -212,7 +213,7 @@ public class FhirServerConfigCommon { return binaryStorageSvc; } - @Bean() + @Bean public IEmailSender emailSender(AppProperties appProperties, Optional subscriptionDeliveryHandlerFactory) { if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) { MailConfig mailConfig = new MailConfig(); 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 25548bf..b801138 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu2.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu2.java @@ -1,85 +1,16 @@ package ca.uhn.fhir.jpa.starter; -import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2; -import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; +import ca.uhn.fhir.jpa.config.JpaDstu2Config; import ca.uhn.fhir.jpa.starter.annotations.OnDSTU2Condition; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; - -import javax.annotation.PostConstruct; -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; +import org.springframework.context.annotation.Import; @Configuration @Conditional(OnDSTU2Condition.class) -public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 { - - @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. - */ - @Autowired - AppProperties appProperties; - - @PostConstruct - public void initSettings() { - if(appProperties.getSearch_coord_core_pool_size() != null) { - setSearchCoordCorePoolSize(appProperties.getSearch_coord_core_pool_size()); - } - if(appProperties.getSearch_coord_max_pool_size() != null) { - setSearchCoordMaxPoolSize(appProperties.getSearch_coord_max_pool_size()); - } - if(appProperties.getSearch_coord_queue_capacity() != null) { - setSearchCoordQueueCapacity(appProperties.getSearch_coord_queue_capacity()); - } - } - - @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( - ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { - LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(myConfigurableListableBeanFactory); - 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, myConfigurableListableBeanFactory)); - return retVal; - } - - @Bean - @Primary - public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager retVal = new JpaTransactionManager(); - retVal.setEntityManagerFactory(entityManagerFactory); - return retVal; - } - - +@Import({ + StarterJpaConfig.class, + JpaDstu2Config.class +}) +public class FhirServerConfigDstu2 { } 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 074d5b7..35d1dab 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu3.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigDstu3.java @@ -1,89 +1,19 @@ package ca.uhn.fhir.jpa.starter; -import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3; -import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; +import ca.uhn.fhir.jpa.config.dstu3.JpaDstu3Config; import ca.uhn.fhir.jpa.starter.annotations.OnDSTU3Condition; import ca.uhn.fhir.jpa.starter.cql.StarterCqlDstu3Config; -import javax.annotation.PostConstruct; -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.annotation.Bean; +import ca.uhn.fhir.jpa.starter.mdm.MdmConfig; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @Configuration @Conditional(OnDSTU3Condition.class) -@Import({StarterCqlDstu3Config.class, ElasticsearchConfig.class}) -public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 { - - @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. - */ - @Autowired - AppProperties appProperties; - - @PostConstruct - public void initSettings() { - if(appProperties.getSearch_coord_core_pool_size() != null) { - setSearchCoordCorePoolSize(appProperties.getSearch_coord_core_pool_size()); - } - if(appProperties.getSearch_coord_max_pool_size() != null) { - setSearchCoordMaxPoolSize(appProperties.getSearch_coord_max_pool_size()); - } - if(appProperties.getSearch_coord_queue_capacity() != null) { - setSearchCoordQueueCapacity(appProperties.getSearch_coord_queue_capacity()); - } - } - - - @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( - ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { - LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(myConfigurableListableBeanFactory); - 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, - myConfigurableListableBeanFactory)); - - return retVal; - } - - @Bean - @Primary - public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager retVal = new JpaTransactionManager(); - retVal.setEntityManagerFactory(entityManagerFactory); - return retVal; - } +@Import({ + StarterJpaConfig.class, + JpaDstu3Config.class, + StarterCqlDstu3Config.class, + ElasticsearchConfig.class}) +public class FhirServerConfigDstu3 { } 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 206ad80..c31cf52 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR4.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR4.java @@ -1,88 +1,20 @@ package ca.uhn.fhir.jpa.starter; -import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.jpa.config.BaseJavaConfigR4; -import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; +import ca.uhn.fhir.jpa.config.r4.JpaR4Config; import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition; import ca.uhn.fhir.jpa.starter.cql.StarterCqlR4Config; -import javax.annotation.PostConstruct; -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.annotation.Bean; +import ca.uhn.fhir.jpa.starter.mdm.MdmConfig; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @Configuration @Conditional(OnR4Condition.class) -@Import({StarterCqlR4Config.class, ElasticsearchConfig.class}) -public class FhirServerConfigR4 extends BaseJavaConfigR4 { - - @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. - */ - @Autowired - AppProperties appProperties; - - @PostConstruct - public void initSettings() { - if(appProperties.getSearch_coord_core_pool_size() != null) { - setSearchCoordCorePoolSize(appProperties.getSearch_coord_core_pool_size()); - } - if(appProperties.getSearch_coord_max_pool_size() != null) { - setSearchCoordMaxPoolSize(appProperties.getSearch_coord_max_pool_size()); - } - if(appProperties.getSearch_coord_queue_capacity() != null) { - setSearchCoordQueueCapacity(appProperties.getSearch_coord_queue_capacity()); - } - } - - @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( - ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { - LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(myConfigurableListableBeanFactory); - 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, - myConfigurableListableBeanFactory)); - return retVal; - } - - @Bean - @Primary - public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager retVal = new JpaTransactionManager(); - retVal.setEntityManagerFactory(entityManagerFactory); - return retVal; - } - +@Import({ + StarterJpaConfig.class, + JpaR4Config.class, + StarterCqlR4Config.class, + ElasticsearchConfig.class +}) +public class FhirServerConfigR4 { } 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 6d6d64f..8ee03df 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR5.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/FhirServerConfigR5.java @@ -1,87 +1,17 @@ package ca.uhn.fhir.jpa.starter; -import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.jpa.config.BaseJavaConfigR5; -import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; +import ca.uhn.fhir.jpa.config.r5.JpaR5Config; import ca.uhn.fhir.jpa.starter.annotations.OnR5Condition; -import javax.annotation.PostConstruct; -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @Configuration @Conditional(OnR5Condition.class) -@Import({ElasticsearchConfig.class}) -public class FhirServerConfigR5 extends BaseJavaConfigR5 { - - @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. - */ - @Autowired - AppProperties appProperties; - - @PostConstruct - public void initSettings() { - if(appProperties.getSearch_coord_core_pool_size() != null) { - setSearchCoordCorePoolSize(appProperties.getSearch_coord_core_pool_size()); - } - if(appProperties.getSearch_coord_max_pool_size() != null) { - setSearchCoordMaxPoolSize(appProperties.getSearch_coord_max_pool_size()); - } - if(appProperties.getSearch_coord_queue_capacity() != null) { - setSearchCoordQueueCapacity(appProperties.getSearch_coord_queue_capacity()); - } - } - - @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( - ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { - LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory(myConfigurableListableBeanFactory); - 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, - myConfigurableListableBeanFactory)); - return retVal; - } - - @Bean - @Primary - public JpaTransactionManager hapiTransactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager retVal = new JpaTransactionManager(); - retVal.setEntityManagerFactory(entityManagerFactory); - return retVal; - } - +@Import({ + StarterJpaConfig.class, + JpaR5Config.class, + ElasticsearchConfig.class +}) +public class FhirServerConfigR5 { } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/StarterJpaConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/StarterJpaConfig.java new file mode 100644 index 0000000..07fd028 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/StarterJpaConfig.java @@ -0,0 +1,109 @@ +package ca.uhn.fhir.jpa.starter; + +import ca.uhn.fhir.context.ConfigurationException; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.IDaoRegistry; +import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; +import ca.uhn.fhir.jpa.batch.config.NonPersistedBatchConfigurer; +import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil; +import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil; +import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil; +import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl; +import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; +import ca.uhn.fhir.jpa.provider.DaoRegistryResourceSupportedSvc; +import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; +import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; +import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl; +import ca.uhn.fhir.jpa.util.ResourceCountCache; +import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain; +import ca.uhn.fhir.rest.api.IResourceSupportedSvc; +import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; +import org.springframework.batch.core.configuration.annotation.BatchConfigurer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +@Configuration +public class StarterJpaConfig { + @Bean + public IFulltextSearchSvc fullTextSearchSvc() { + return new FulltextSearchSvcImpl(); + } + + @Bean + public IStaleSearchDeletingSvc staleSearchDeletingSvc() { + return new StaleSearchDeletingSvcImpl(); + } + + @Primary + @Bean + public CachingValidationSupport validationSupportChain(JpaValidationSupportChain theJpaValidationSupportChain) { + return ValidationSupportConfigUtil.newCachingValidationSupport(theJpaValidationSupportChain); + } + + @Bean + public BatchConfigurer batchConfigurer() { + return new NonPersistedBatchConfigurer(); + } + + @Autowired + AppProperties appProperties; + @Autowired + private DataSource myDataSource; + @Autowired + private ConfigurableEnvironment configurableEnvironment; + + /** + * 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. + */ + @Bean + public DatabaseBackedPagingProvider databaseBackedPagingProvider() { + DatabaseBackedPagingProvider pagingProvider = new DatabaseBackedPagingProvider(); + pagingProvider.setDefaultPageSize(appProperties.getDefault_page_size()); + pagingProvider.setMaximumPageSize(appProperties.getMax_page_size()); + return pagingProvider; + } + + @Bean + public IResourceSupportedSvc resourceSupportedSvc(IDaoRegistry theDaoRegistry) { + return new DaoRegistryResourceSupportedSvc(theDaoRegistry); + } + + @Bean(name = "myResourceCountsCache") + public ResourceCountCache resourceCountsCache(IFhirSystemDao theSystemDao) { + return ResourceCountCacheUtil.newResourceCountCache(theSystemDao); + } + + @Primary + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory( + ConfigurableListableBeanFactory myConfigurableListableBeanFactory, FhirContext theFhirContext) { + LocalContainerEntityManagerFactoryBean retVal = HapiEntityManagerFactoryUtil.newEntityManagerFactory(myConfigurableListableBeanFactory, theFhirContext); + 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, myConfigurableListableBeanFactory)); + 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/mdm/MdmConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java index 39718f6..50dfe9e 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java @@ -1,15 +1,12 @@ package ca.uhn.fhir.jpa.starter.mdm; -import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.mdm.config.MdmConsumerConfig; import ca.uhn.fhir.jpa.mdm.config.MdmSubmitterConfig; import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; import ca.uhn.fhir.mdm.rules.config.MdmSettings; -import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import com.google.common.base.Charsets; -import java.io.IOException; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -19,6 +16,8 @@ import org.springframework.context.annotation.Import; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; +import java.io.IOException; + @Configuration @Conditional(MdmConfigCondition.class) @Import({MdmConsumerConfig.class, MdmSubmitterConfig.class}) diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 67c86f4..0174848 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -95,8 +95,10 @@ hapi: # enable_index_contained_resource: false ### !!Extended Lucene/Elasticsearch Indexing is still a experimental feature, expect some features (e.g. _total=accurate) to not work as expected!! ### more information here: https://hapifhir.io/hapi-fhir/docs/server_jpa/elastic.html - # advanced_lucene_indexing: false + advanced_lucene_indexing: false # enforce_referential_integrity_on_delete: false + # This is an experimental feature, and does not fully support _total and other FHIR features. +# enforce_referential_integrity_on_delete: false # enforce_referential_integrity_on_write: false # etag_support_enabled: true # expunge_enabled: true @@ -109,6 +111,7 @@ hapi: # mdm_enabled: true # local_base_urls: # - https://hapi.fhir.org/baseR4 + mdm_enabled: false # partitioning: # allow_references_across_partitions: false # partitioning_include_in_search_hashes: false diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java index 1387354..6ad49c6 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java @@ -43,13 +43,18 @@ import org.testcontainers.elasticsearch.ElasticsearchContainer; "hapi.fhir.fhir_version=r4", "hapi.fhir.lastn_enabled=true", "hapi.fhir.store_resource_in_lucene_index_enabled=true", + "hapi.fhir.advanced_lucene_indexing=true", "elasticsearch.enabled=true", // Because the port is set randomly, we will set the rest_url using the Initializer. // "elasticsearch.rest_url='http://localhost:9200'", "elasticsearch.username=SomeUsername", "elasticsearch.password=SomePassword", + "elasticsearch.debug.refresh_after_write=true", "elasticsearch.protocol=http", - "spring.main.allow-bean-definition-overriding=true" + "spring.main.allow-bean-definition-overriding=true", + "spring.jpa.properties.hibernate.search.enabled=true", + "spring.jpa.properties.hibernate.search.backend.type=elasticsearch", + "spring.jpa.properties.hibernate.search.backend.analysis.configurer=ca.uhn.fhir.jpa.search.elastic.HapiElasticsearchAnalysisConfigurer" }) @ContextConfiguration(initializers = ElasticsearchLastNR4IT.Initializer.class) public class ElasticsearchLastNR4IT { @@ -57,10 +62,9 @@ public class ElasticsearchLastNR4IT { private IGenericClient ourClient; private FhirContext ourCtx; - private static final String ELASTIC_VERSION = "7.10.2"; - private static final String ELASTIC_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch:" + ELASTIC_VERSION; - - private static ElasticsearchContainer embeddedElastic; + private static final String ELASTIC_VERSION = "7.16.3"; + private static final String ELASTIC_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch:" + ELASTIC_VERSION; + private static ElasticsearchContainer embeddedElastic; @Autowired private ElasticsearchSvcImpl myElasticsearchSvc; @@ -80,7 +84,8 @@ public class ElasticsearchLastNR4IT { private int port; @Test - void testLastN() throws IOException { + void testLastN() throws IOException, InterruptedException { + Thread.sleep(2000); Patient pt = new Patient(); pt.addName().setFamily("Lastn").addGiven("Arthur"); @@ -90,8 +95,10 @@ public class ElasticsearchLastNR4IT { obs.getSubject().setReferenceElement(id); String observationCode = "testobservationcode"; String codeSystem = "http://testobservationcodesystem"; + obs.getCode().addCoding().setCode(observationCode).setSystem(codeSystem); obs.setValue(new StringType(observationCode)); + Date effectiveDtm = new GregorianCalendar().getTime(); obs.setEffective(new DateTimeType(effectiveDtm)); obs.getCategoryFirstRep().addCoding().setCode("testcategorycode").setSystem("http://testcategorycodesystem");