From 408da72cf4e7bdbd89ead2946817f78b71b46520 Mon Sep 17 00:00:00 2001 From: Brenin Rhodes Date: Thu, 19 Oct 2023 06:50:29 -0600 Subject: [PATCH] Add settings for CDS Hooks and use latest hapi-fhir-cr configs --- .../uhn/fhir/jpa/starter/AppProperties.java | 250 ----------------- .../ca/uhn/fhir/jpa/starter/Application.java | 8 +- .../cdshooks/CdsHooksConfigCondition.java | 14 + .../starter/cdshooks/CdsHooksProperties.java | 27 ++ .../jpa/starter/cdshooks/CdsHooksServlet.java | 22 +- .../cdshooks/ProviderConfiguration.java | 29 ++ .../cdshooks/StarterCdsHooksConfig.java | 22 ++ .../uhn/fhir/jpa/starter/cr/BaseCrConfig.java | 30 +- .../jpa/starter/cr/CrConfigCondition.java | 8 +- .../uhn/fhir/jpa/starter/cr/CrProperties.java | 264 ++++++++++++++++++ .../uhn/fhir/jpa/starter/cr/CrR4Config.java | 182 ------------ .../jpa/starter/cr/StarterCrDstu3Config.java | 56 ++-- .../jpa/starter/cr/StarterCrR4Config.java | 75 +++-- src/main/resources/application.yaml | 12 +- .../fhir/jpa/starter/ExampleServerR4IT.java | 13 +- 15 files changed, 474 insertions(+), 538 deletions(-) create mode 100644 src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksConfigCondition.java create mode 100644 src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksProperties.java create mode 100644 src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java create mode 100644 src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java delete mode 100644 src/main/java/ca/uhn/fhir/jpa/starter/cr/CrR4Config.java 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 f83d80f02e5..5ad6c830c8f 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -26,36 +26,6 @@ @EnableConfigurationProperties public class AppProperties { - private Boolean cr_enabled = false; - //cql settings - private Boolean cql_use_embedded_libraries = true; - private Boolean cql_runtime_debug_logging_enabled = false; - private Boolean cql_runtime_enable_validation = false; - private Boolean cql_runtime_enable_expression_caching = false; - private Boolean cql_compiler_validate_units = true; - private Boolean cql_compiler_verify_only = false; - private String cql_compiler_compatibility_level = "1.5"; - private CqlCompilerException.ErrorSeverity cql_compiler_error_level = CqlCompilerException.ErrorSeverity.Info; - private LibraryBuilder.SignatureLevel cql_compiler_signature_level = LibraryBuilder.SignatureLevel.All; - private Boolean cql_compiler_analyze_data_requirements = false; - private Boolean cql_compiler_collapse_data_requirements = false; - private CqlTranslator.Format cql_compiler_translator_format = CqlTranslator.Format.JSON; - private Boolean cql_compiler_enable_date_range_optimization = false; - private Boolean cql_compiler_enable_annotations = false; - private Boolean cql_compiler_enable_locators = false; - private Boolean cql_compiler_enable_results_type = false; - private Boolean cql_compiler_enable_detailed_errors = false; - private Boolean cql_compiler_disable_list_traversal = false; - private Boolean cql_compiler_disable_list_demotion = false; - private Boolean cql_compiler_disable_list_promotion = false; - private Boolean cql_compiler_enable_interval_demotion = false; - private Boolean cql_compiler_enable_interval_promotion = false; - private Boolean cql_compiler_disable_method_invocation = false; - private Boolean cql_compiler_require_from_keyword = false; - private Boolean cql_compiler_disable_default_model_info_load = false; - // Care-gaps Settings - private String caregaps_reporter = "default"; - private String caregaps_section_author = "default"; private Boolean ips_enabled = false; private Boolean openapi_enabled = false; private Boolean mdm_enabled = false; @@ -197,226 +167,6 @@ public void setPartitioning(Partitioning partitioning) { this.partitioning = partitioning; } - public Boolean getCr_enabled() { - return cr_enabled; - } - - public void setCr_enabled(Boolean cr_enabled) { - this.cr_enabled = cr_enabled; - } - - public boolean isCqlUseEmbeddedLibraries() { - return cql_use_embedded_libraries; - } - - public void setCqlUseEmbeddedLibraries(boolean cql_use_embedded_libraries) { - this.cql_use_embedded_libraries = cql_use_embedded_libraries; - } - - public boolean isCqlRuntimeDebugLoggingEnabled() { - return cql_runtime_debug_logging_enabled; - } - - public void setCqlRuntimeDebugLoggingEnabled(boolean cqlRuntimeDebugLoggingEnabled) { - this.cql_runtime_debug_logging_enabled = cqlRuntimeDebugLoggingEnabled; - } - - public boolean isCqlCompilerValidateUnits() { - return cql_compiler_validate_units; - } - - public void setCqlCompilerValidateUnits(boolean cqlCompilerValidateUnits) { - this.cql_compiler_validate_units = cqlCompilerValidateUnits; - } - - public boolean isCqlCompilerVerifyOnly() { - return cql_compiler_verify_only; - } - - public void setCqlCompilerVerifyOnly(boolean cqlCompilerVerifyOnly) { - this.cql_compiler_verify_only = cqlCompilerVerifyOnly; - } - - public String getCqlCompilerCompatibilityLevel() { - return cql_compiler_compatibility_level; - } - - public void setCqlCompilerCompatibilityLevel(String cqlCompilerCompatibilityLevel) { - this.cql_compiler_compatibility_level = cqlCompilerCompatibilityLevel; - } - - public CqlCompilerException.ErrorSeverity getCqlCompilerErrorSeverityLevel() { - return cql_compiler_error_level; - } - - public void setCqlCompilerErrorSeverityLevel(CqlCompilerException.ErrorSeverity cqlCompilerErrorSeverityLevel) { - this.cql_compiler_error_level = cqlCompilerErrorSeverityLevel; - } - - public LibraryBuilder.SignatureLevel getCqlCompilerSignatureLevel() { - return cql_compiler_signature_level; - } - - public void setCqlCompilerSignatureLevel(LibraryBuilder.SignatureLevel cqlCompilerSignatureLevel) { - this.cql_compiler_signature_level = cqlCompilerSignatureLevel; - } - - public boolean isCqlCompilerAnalyzeDataRequirements() { - return cql_compiler_analyze_data_requirements; - } - - public void setCqlCompilerAnalyzeDataRequirements(boolean cqlCompilerAnalyzeDataRequirements) { - this.cql_compiler_analyze_data_requirements = cqlCompilerAnalyzeDataRequirements; - } - - public boolean isCqlCompilerCollapseDataRequirements() { - return cql_compiler_collapse_data_requirements; - } - - public void setCqlCompilerCollapseDataRequirements(boolean cqlCompilerCollapseDataRequirements) { - this.cql_compiler_collapse_data_requirements = cqlCompilerCollapseDataRequirements; - } - - public boolean isEnableDateRangeOptimization() { - return cql_compiler_enable_date_range_optimization; - } - - public void setEnableDateRangeOptimization(boolean enableDateRangeOptimization) { - this.cql_compiler_enable_date_range_optimization = enableDateRangeOptimization; - } - - public boolean isEnableAnnotations() { - return cql_compiler_enable_annotations; - } - - public void setEnableAnnotations(boolean enableAnnotations) { - this.cql_compiler_enable_annotations = enableAnnotations; - } - - public boolean isEnableLocators() { - return cql_compiler_enable_locators; - } - - public void setEnableLocators(boolean enableLocators) { - this.cql_compiler_enable_locators = enableLocators; - } - - public boolean isEnableResultsType() { - return cql_compiler_enable_results_type; - } - - public void setEnableResultsType(boolean enableResultsType) { - this.cql_compiler_enable_results_type = enableResultsType; - } - - public boolean isEnableDetailedErrors() { - return cql_compiler_enable_detailed_errors; - } - - public void setEnableDetailedErrors(boolean enableDetailedErrors) { - this.cql_compiler_enable_detailed_errors = enableDetailedErrors; - } - - public boolean isDisableListTraversal() { - return cql_compiler_disable_list_traversal; - } - - public void setDisableListTraversal(boolean disableListTraversal) { - this.cql_compiler_disable_list_traversal = disableListTraversal; - } - - public boolean isDisableListDemotion() { - return cql_compiler_disable_list_demotion; - } - - public void setDisableListDemotion(boolean disableListDemotion) { - this.cql_compiler_disable_list_demotion = disableListDemotion; - } - - public boolean isDisableListPromotion() { - return cql_compiler_disable_list_promotion; - } - - public void setDisableListPromotion(boolean disableListPromotion) { - this.cql_compiler_disable_list_promotion = disableListPromotion; - } - - public boolean isEnableIntervalPromotion() { - return cql_compiler_enable_interval_promotion; - } - - public void setEnableIntervalPromotion(boolean enableIntervalPromotion) { - this.cql_compiler_enable_interval_promotion = enableIntervalPromotion; - } - - public boolean isEnableIntervalDemotion() { - return cql_compiler_enable_interval_demotion; - } - - public void setEnableIntervalDemotion(boolean enableIntervalDemotion) { - this.cql_compiler_enable_interval_demotion = enableIntervalDemotion; - } - - public boolean isDisableMethodInvocation() { - return cql_compiler_disable_method_invocation; - } - - public void setDisableMethodInvocation(boolean disableMethodInvocation) { - this.cql_compiler_disable_method_invocation = disableMethodInvocation; - } - - public boolean isRequireFromKeyword() { - return cql_compiler_require_from_keyword; - } - - public void setRequireFromKeyword(boolean requireFromKeyword) { - this.cql_compiler_require_from_keyword = requireFromKeyword; - } - - public boolean isDisableDefaultModelInfoLoad() { - return cql_compiler_disable_default_model_info_load; - } - - public void setDisableDefaultModelInfoLoad(boolean disableDefaultModelInfoLoad) { - this.cql_compiler_disable_default_model_info_load = disableDefaultModelInfoLoad; - } - - public boolean isCqlRuntimeEnableExpressionCaching() { - return cql_runtime_enable_expression_caching; - } - - public void setCqlRuntimeEnableExpressionCaching(boolean cqlRuntimeEnableExpressionCaching) { - this.cql_runtime_enable_expression_caching = cqlRuntimeEnableExpressionCaching; - } - - public boolean isCqlRuntimeEnableValidation() { - return cql_runtime_enable_validation; - } - - public void setCqlRuntimeEnableValidation(boolean cqlRuntimeEnableValidation) { - this.cql_runtime_enable_validation = cqlRuntimeEnableValidation; - } - - public CqlTranslator.Format getCqlTranslatorFormat() { - return cql_compiler_translator_format; - } - - public void setCqlTranslatorFormat(CqlTranslator.Format cqlTranslatorFormat) { - this.cql_compiler_translator_format = cqlTranslatorFormat; - } - - public String getCareGapsReporter() { - return caregaps_reporter; - } - public String getCareGapsSectionAuthor() { - return caregaps_section_author; - } - - public void setCareGapsSectionAuthor(String theCareGapsSectionAuthor) {this.caregaps_section_author = theCareGapsSectionAuthor;} - public void setCareGapsReporter(String theCareGapsReporter) { - this.caregaps_reporter = theCareGapsReporter; - } - public Boolean getIps_enabled() { return ips_enabled; } 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 da701fb8877..81fb73b85b2 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java @@ -96,8 +96,8 @@ public ServletRegistrationBean overlayRegistrationBean() { } - @Bean - IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) { - return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer); - } +// @Bean +// IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) { +// return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer); +// } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksConfigCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksConfigCondition.java new file mode 100644 index 00000000000..5553419b356 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksConfigCondition.java @@ -0,0 +1,14 @@ +package ca.uhn.fhir.jpa.starter.cdshooks; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public class CdsHooksConfigCondition implements Condition { + + @Override + public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { + String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cdshooks.enabled"); + return Boolean.parseBoolean(property); + } +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksProperties.java new file mode 100644 index 00000000000..147336f7e68 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksProperties.java @@ -0,0 +1,27 @@ +package ca.uhn.fhir.jpa.starter.cdshooks; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "hapi.fhir.cdshooks") +public class CdsHooksProperties { + + private boolean enabled; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + private String clientIdHeaderName; + + public String getClientIdHeaderName() { + return clientIdHeaderName; + } + + public void setClientIdHeaderName(String clientIdHeaderName) { + this.clientIdHeaderName = clientIdHeaderName; + } +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java index 8f32e821711..a6f54dd1ec8 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java @@ -37,6 +37,8 @@ public class CdsHooksServlet extends HttpServlet { @Autowired private AppProperties appProperties; @Autowired + private ProviderConfiguration providerConfiguration; + @Autowired ICdsServiceRegistry cdsServiceRegistry; @Autowired RestfulServer restfulServer; @@ -44,6 +46,10 @@ public class CdsHooksServlet extends HttpServlet { @Qualifier(CDS_HOOKS_OBJECT_MAPPER_FACTORY) ObjectMapper objectMapper; + protected ProviderConfiguration getProviderConfiguration() { + return this.providerConfiguration; + } + // CORS Pre-flight @Override protected void doOptions(HttpServletRequest req, HttpServletResponse resp) { @@ -103,26 +109,12 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) private void logRequestInfo(CdsServiceRequestJson request, String jsonRequest) { logger.info(jsonRequest); logger.info("cds-hooks hook instance: {}", request.getHookInstance()); - // logger.info("cds-hooks maxCodesPerQuery: {}", this.getProviderConfiguration().getMaxCodesPerQuery()); - // logger.info("cds-hooks expandValueSets: {}", this.getProviderConfiguration().getExpandValueSets()); - // logger.info("cds-hooks queryBatchThreshold: {}", this.getProviderConfiguration().getQueryBatchThreshold()); - // logger.info("cds-hooks searchStyle: {}", this.getProviderConfiguration().getSearchStyle()); - // logger.info("cds-hooks prefetch maxUriLength: {}", this.getProviderConfiguration().getMaxUriLength()); logger.info("cds-hooks local server address: {}", appProperties.getServer_address()); logger.info("cds-hooks fhir server address: {}", request.getFhirServer()); - // logger.info("cds-hooks cql_logging_enabled: {}", this.getProviderConfiguration().getCqlLoggingEnabled()); + logger.info("cds-hooks cql_logging_enabled: {}", this.getProviderConfiguration().getCqlLoggingEnabled()); } private CdsServicesJson getServices() { return cdsServiceRegistry.getCdsServicesJson(); } - - // public DebugMap getDebugMap() { - // DebugMap debugMap = new DebugMap(); - // if (cqlProperties.getCqlRuntimeOptions().isDebugLoggingEnabled()) { - // // getOptions().getCqlEngineOptions().isDebugLoggingEnabled()) { - // debugMap.setIsLoggingEnabled(true); - // } - // return debugMap; - // } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java new file mode 100644 index 00000000000..bd62b004bef --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java @@ -0,0 +1,29 @@ +package ca.uhn.fhir.jpa.starter.cdshooks; + +import ca.uhn.fhir.jpa.starter.cr.CrProperties; + +public class ProviderConfiguration { + + public static final ProviderConfiguration DEFAULT_PROVIDER_CONFIGURATION = new ProviderConfiguration(false, "client_id"); + + private final String clientIdHeaderName; + private final boolean cqlLoggingEnabled; + + public ProviderConfiguration(boolean cqlLoggingEnabled, String clientIdHeaderName) { + this.cqlLoggingEnabled = cqlLoggingEnabled; + this.clientIdHeaderName = clientIdHeaderName; + } + + public ProviderConfiguration(CdsHooksProperties cdsProperties, CrProperties crProperties) { + this.clientIdHeaderName = cdsProperties.getClientIdHeaderName(); + this.cqlLoggingEnabled = crProperties.isCqlRuntimeDebugLoggingEnabled(); + } + + public String getClientIdHeaderName() { + return this.clientIdHeaderName; + } + + public boolean getCqlLoggingEnabled() { + return this.cqlLoggingEnabled; + } +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/StarterCdsHooksConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/StarterCdsHooksConfig.java index cd5a0784a98..59e7412e741 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/StarterCdsHooksConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/StarterCdsHooksConfig.java @@ -4,16 +4,33 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.boot.web.servlet.ServletRegistrationBean; 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 ca.uhn.fhir.jpa.starter.cr.CrConfigCondition; +import ca.uhn.fhir.jpa.starter.cr.CrProperties; import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc; import ca.uhn.hapi.fhir.cdshooks.config.CdsHooksConfig; import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter; +import ca.uhn.hapi.fhir.cdshooks.svc.cr.CdsCrSettings; @Configuration +@Conditional({ CdsHooksConfigCondition.class, CrConfigCondition.class }) @Import(CdsHooksConfig.class) public class StarterCdsHooksConfig { + @Bean + public CdsHooksProperties cdsHooksProperties() { + return new CdsHooksProperties(); + } + + @Bean + public CdsCrSettings cdsCrSettings(CdsHooksProperties cdsHooksProperties) { + CdsCrSettings settings = CdsCrSettings.getDefault(); + settings.setClientIdHeaderName(cdsHooksProperties.getClientIdHeaderName()); + return settings; + } + @Bean public CdsHooksContextBooter cdsHooksContextBooter() { // ourLog.info("No Spring Context provided. Assuming all CDS Services will be registered dynamically."); @@ -25,6 +42,11 @@ public static class CdsHooksDaoAuthorizationSvc implements ICdsHooksDaoAuthoriza public void authorizePreShow(IBaseResource theResource) {} } + @Bean + public ProviderConfiguration providerConfiguration(CdsHooksProperties cdsProperties, CrProperties crProperties) { + return new ProviderConfiguration(cdsProperties, crProperties); + } + @Bean ICdsHooksDaoAuthorizationSvc cdsHooksDaoAuthorizationSvc() { return new CdsHooksDaoAuthorizationSvc(); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/BaseCrConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/BaseCrConfig.java index 1e08b33df1e..04101af9a60 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/BaseCrConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/BaseCrConfig.java @@ -1,17 +1,11 @@ package ca.uhn.fhir.jpa.starter.cr; -import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.cr.common.CodeCacheResourceChangeListener; import ca.uhn.fhir.cr.common.ElmCacheResourceChangeListener; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCacheRefresher; import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry; -import ca.uhn.fhir.jpa.cache.ResourceChangeListenerCacheFactory; -import ca.uhn.fhir.jpa.cache.ResourceChangeListenerCacheRefresherImpl; -import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryImpl; import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryInterceptor; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; import org.cqframework.cql.cql2elm.model.CompiledLibrary; import org.cqframework.cql.cql2elm.model.Model; import org.hl7.cql.model.ModelIdentifier; @@ -27,6 +21,11 @@ @Configuration public class BaseCrConfig { + @Bean + public CrProperties crProperties() { + return new CrProperties(); + } + @Bean public Map globalLibraryCache() { return new ConcurrentHashMap<>(); @@ -42,7 +41,6 @@ public Map> globalValueSetCache() { return new ConcurrentHashMap<>(); } - @Bean public ElmCacheResourceChangeListener elmCacheResourceChangeListener( IResourceChangeListenerRegistry theResourceChangeListenerRegistry, @@ -69,15 +67,17 @@ public CodeCacheResourceChangeListener codeCacheResourceChangeListener( return listener; } - @Bean - public IResourceChangeListenerRegistry resourceChangeListenerRegistry(InMemoryResourceMatcher theInMemoryResourceMatcher, FhirContext theFhirContext, ResourceChangeListenerCacheFactory theResourceChangeListenerCacheFactory) { - return new ResourceChangeListenerRegistryImpl(theFhirContext, theResourceChangeListenerCacheFactory, theInMemoryResourceMatcher); - } + // These beans were being duplicated + // @Bean + // public IResourceChangeListenerRegistry resourceChangeListenerRegistry(InMemoryResourceMatcher theInMemoryResourceMatcher, FhirContext theFhirContext, ResourceChangeListenerCacheFactory theResourceChangeListenerCacheFactory) { + // return new ResourceChangeListenerRegistryImpl(theFhirContext, theResourceChangeListenerCacheFactory, theInMemoryResourceMatcher); + // } + + // @Bean + // IResourceChangeListenerCacheRefresher resourceChangeListenerCacheRefresher() { + // return new ResourceChangeListenerCacheRefresherImpl(); + // } - @Bean - IResourceChangeListenerCacheRefresher resourceChangeListenerCacheRefresher() { - return new ResourceChangeListenerCacheRefresherImpl(); - } @Bean public ResourceChangeListenerRegistryInterceptor resourceChangeListenerRegistryInterceptor() { return new ResourceChangeListenerRegistryInterceptor(); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrConfigCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrConfigCondition.java index b488bcfe1fa..c9ac4b9764a 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrConfigCondition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrConfigCondition.java @@ -6,9 +6,9 @@ public class CrConfigCondition implements Condition { - @Override - public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { - String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cr_enabled"); - return Boolean.parseBoolean(property); + @Override + public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { + String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cr.enabled"); + return Boolean.parseBoolean(property); } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java new file mode 100644 index 00000000000..c0a2fd24fd9 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java @@ -0,0 +1,264 @@ +package ca.uhn.fhir.jpa.starter.cr; + +import org.cqframework.cql.cql2elm.CqlCompilerException; +import org.cqframework.cql.cql2elm.CqlTranslator; +import org.cqframework.cql.cql2elm.LibraryBuilder; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "hapi.fhir.cr") +public class CrProperties { + private Boolean enabled; + //cql settings + private Boolean cql_use_embedded_libraries = true; + private Boolean cql_runtime_debug_logging_enabled = false; + private Boolean cql_runtime_enable_validation = false; + private Boolean cql_runtime_enable_expression_caching = false; + private Boolean cql_compiler_validate_units = true; + private Boolean cql_compiler_verify_only = false; + private String cql_compiler_compatibility_level = "1.5"; + private CqlCompilerException.ErrorSeverity cql_compiler_error_level = CqlCompilerException.ErrorSeverity.Info; + private LibraryBuilder.SignatureLevel cql_compiler_signature_level = LibraryBuilder.SignatureLevel.All; + private Boolean cql_compiler_analyze_data_requirements = false; + private Boolean cql_compiler_collapse_data_requirements = false; + private CqlTranslator.Format cql_compiler_translator_format = CqlTranslator.Format.JSON; + private Boolean cql_compiler_enable_date_range_optimization = false; + private Boolean cql_compiler_enable_annotations = false; + private Boolean cql_compiler_enable_locators = false; + private Boolean cql_compiler_enable_results_type = false; + private Boolean cql_compiler_enable_detailed_errors = false; + private Boolean cql_compiler_disable_list_traversal = false; + private Boolean cql_compiler_disable_list_demotion = false; + private Boolean cql_compiler_disable_list_promotion = false; + private Boolean cql_compiler_enable_interval_demotion = false; + private Boolean cql_compiler_enable_interval_promotion = false; + private Boolean cql_compiler_disable_method_invocation = false; + private Boolean cql_compiler_require_from_keyword = false; + private Boolean cql_compiler_disable_default_model_info_load = false; + // Care-gaps Settings + private String caregaps_reporter = "default"; + private String caregaps_section_author = "default"; + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public boolean isCqlUseEmbeddedLibraries() { + return cql_use_embedded_libraries; + } + + public void setCqlUseEmbeddedLibraries(boolean cql_use_embedded_libraries) { + this.cql_use_embedded_libraries = cql_use_embedded_libraries; + } + + public boolean isCqlRuntimeDebugLoggingEnabled() { + return cql_runtime_debug_logging_enabled; + } + + public void setCqlRuntimeDebugLoggingEnabled(boolean cqlRuntimeDebugLoggingEnabled) { + this.cql_runtime_debug_logging_enabled = cqlRuntimeDebugLoggingEnabled; + } + + public boolean isCqlCompilerValidateUnits() { + return cql_compiler_validate_units; + } + + public void setCqlCompilerValidateUnits(boolean cqlCompilerValidateUnits) { + this.cql_compiler_validate_units = cqlCompilerValidateUnits; + } + + public boolean isCqlCompilerVerifyOnly() { + return cql_compiler_verify_only; + } + + public void setCqlCompilerVerifyOnly(boolean cqlCompilerVerifyOnly) { + this.cql_compiler_verify_only = cqlCompilerVerifyOnly; + } + + public String getCqlCompilerCompatibilityLevel() { + return cql_compiler_compatibility_level; + } + + public void setCqlCompilerCompatibilityLevel(String cqlCompilerCompatibilityLevel) { + this.cql_compiler_compatibility_level = cqlCompilerCompatibilityLevel; + } + + public CqlCompilerException.ErrorSeverity getCqlCompilerErrorSeverityLevel() { + return cql_compiler_error_level; + } + + public void setCqlCompilerErrorSeverityLevel(CqlCompilerException.ErrorSeverity cqlCompilerErrorSeverityLevel) { + this.cql_compiler_error_level = cqlCompilerErrorSeverityLevel; + } + + public LibraryBuilder.SignatureLevel getCqlCompilerSignatureLevel() { + return cql_compiler_signature_level; + } + + public void setCqlCompilerSignatureLevel(LibraryBuilder.SignatureLevel cqlCompilerSignatureLevel) { + this.cql_compiler_signature_level = cqlCompilerSignatureLevel; + } + + public boolean isCqlCompilerAnalyzeDataRequirements() { + return cql_compiler_analyze_data_requirements; + } + + public void setCqlCompilerAnalyzeDataRequirements(boolean cqlCompilerAnalyzeDataRequirements) { + this.cql_compiler_analyze_data_requirements = cqlCompilerAnalyzeDataRequirements; + } + + public boolean isCqlCompilerCollapseDataRequirements() { + return cql_compiler_collapse_data_requirements; + } + + public void setCqlCompilerCollapseDataRequirements(boolean cqlCompilerCollapseDataRequirements) { + this.cql_compiler_collapse_data_requirements = cqlCompilerCollapseDataRequirements; + } + + public boolean isEnableDateRangeOptimization() { + return cql_compiler_enable_date_range_optimization; + } + + public void setEnableDateRangeOptimization(boolean enableDateRangeOptimization) { + this.cql_compiler_enable_date_range_optimization = enableDateRangeOptimization; + } + + public boolean isEnableAnnotations() { + return cql_compiler_enable_annotations; + } + + public void setEnableAnnotations(boolean enableAnnotations) { + this.cql_compiler_enable_annotations = enableAnnotations; + } + + public boolean isEnableLocators() { + return cql_compiler_enable_locators; + } + + public void setEnableLocators(boolean enableLocators) { + this.cql_compiler_enable_locators = enableLocators; + } + + public boolean isEnableResultsType() { + return cql_compiler_enable_results_type; + } + + public void setEnableResultsType(boolean enableResultsType) { + this.cql_compiler_enable_results_type = enableResultsType; + } + + public boolean isEnableDetailedErrors() { + return cql_compiler_enable_detailed_errors; + } + + public void setEnableDetailedErrors(boolean enableDetailedErrors) { + this.cql_compiler_enable_detailed_errors = enableDetailedErrors; + } + + public boolean isDisableListTraversal() { + return cql_compiler_disable_list_traversal; + } + + public void setDisableListTraversal(boolean disableListTraversal) { + this.cql_compiler_disable_list_traversal = disableListTraversal; + } + + public boolean isDisableListDemotion() { + return cql_compiler_disable_list_demotion; + } + + public void setDisableListDemotion(boolean disableListDemotion) { + this.cql_compiler_disable_list_demotion = disableListDemotion; + } + + public boolean isDisableListPromotion() { + return cql_compiler_disable_list_promotion; + } + + public void setDisableListPromotion(boolean disableListPromotion) { + this.cql_compiler_disable_list_promotion = disableListPromotion; + } + + public boolean isEnableIntervalPromotion() { + return cql_compiler_enable_interval_promotion; + } + + public void setEnableIntervalPromotion(boolean enableIntervalPromotion) { + this.cql_compiler_enable_interval_promotion = enableIntervalPromotion; + } + + public boolean isEnableIntervalDemotion() { + return cql_compiler_enable_interval_demotion; + } + + public void setEnableIntervalDemotion(boolean enableIntervalDemotion) { + this.cql_compiler_enable_interval_demotion = enableIntervalDemotion; + } + + public boolean isDisableMethodInvocation() { + return cql_compiler_disable_method_invocation; + } + + public void setDisableMethodInvocation(boolean disableMethodInvocation) { + this.cql_compiler_disable_method_invocation = disableMethodInvocation; + } + + public boolean isRequireFromKeyword() { + return cql_compiler_require_from_keyword; + } + + public void setRequireFromKeyword(boolean requireFromKeyword) { + this.cql_compiler_require_from_keyword = requireFromKeyword; + } + + public boolean isDisableDefaultModelInfoLoad() { + return cql_compiler_disable_default_model_info_load; + } + + public void setDisableDefaultModelInfoLoad(boolean disableDefaultModelInfoLoad) { + this.cql_compiler_disable_default_model_info_load = disableDefaultModelInfoLoad; + } + + public boolean isCqlRuntimeEnableExpressionCaching() { + return cql_runtime_enable_expression_caching; + } + + public void setCqlRuntimeEnableExpressionCaching(boolean cqlRuntimeEnableExpressionCaching) { + this.cql_runtime_enable_expression_caching = cqlRuntimeEnableExpressionCaching; + } + + public boolean isCqlRuntimeEnableValidation() { + return cql_runtime_enable_validation; + } + + public void setCqlRuntimeEnableValidation(boolean cqlRuntimeEnableValidation) { + this.cql_runtime_enable_validation = cqlRuntimeEnableValidation; + } + + public CqlTranslator.Format getCqlTranslatorFormat() { + return cql_compiler_translator_format; + } + + public void setCqlTranslatorFormat(CqlTranslator.Format cqlTranslatorFormat) { + this.cql_compiler_translator_format = cqlTranslatorFormat; + } + + public String getCareGapsReporter() { + return caregaps_reporter; + } + + public String getCareGapsSectionAuthor() { + return caregaps_section_author; + } + + public void setCareGapsSectionAuthor(String theCareGapsSectionAuthor) { + this.caregaps_section_author = theCareGapsSectionAuthor; + } + + public void setCareGapsReporter(String theCareGapsReporter) { + this.caregaps_reporter = theCareGapsReporter; + } +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrR4Config.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrR4Config.java deleted file mode 100644 index 07cc7cc8bf3..00000000000 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrR4Config.java +++ /dev/null @@ -1,182 +0,0 @@ -package ca.uhn.fhir.jpa.starter.cr; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.FhirVersionEnum; -import ca.uhn.fhir.cr.common.IRepositoryFactory; -import ca.uhn.fhir.cr.config.ProviderLoader; -import ca.uhn.fhir.cr.config.ProviderSelector; -import ca.uhn.fhir.cr.r4.IActivityDefinitionProcessorFactory; -import ca.uhn.fhir.cr.r4.ICareGapsServiceFactory; -import ca.uhn.fhir.cr.r4.ICqlExecutionServiceFactory; -import ca.uhn.fhir.cr.r4.IMeasureServiceFactory; -import ca.uhn.fhir.cr.r4.IPlanDefinitionProcessorFactory; -import ca.uhn.fhir.cr.r4.IQuestionnaireProcessorFactory; -import ca.uhn.fhir.cr.r4.IQuestionnaireResponseProcessorFactory; -import ca.uhn.fhir.cr.r4.ISubmitDataProcessorFactory; -import ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionApplyProvider; -import ca.uhn.fhir.cr.r4.cqlexecution.CqlExecutionOperationProvider; -import ca.uhn.fhir.cr.r4.measure.CareGapsOperationProvider; -import ca.uhn.fhir.cr.r4.measure.MeasureOperationsProvider; -import ca.uhn.fhir.cr.r4.measure.SubmitDataProvider; -import ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionApplyProvider; -import ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionPackageProvider; -import ca.uhn.fhir.cr.r4.questionnaire.QuestionnairePackageProvider; -import ca.uhn.fhir.cr.r4.questionnaire.QuestionnairePopulateProvider; -import ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseExtractProvider; -import ca.uhn.fhir.rest.server.RestfulServer; -import org.opencds.cqf.fhir.cql.EvaluationSettings; -import org.opencds.cqf.fhir.cr.activitydefinition.r4.ActivityDefinitionProcessor; -import org.opencds.cqf.fhir.cr.cql.r4.R4CqlExecutionService; -import org.opencds.cqf.fhir.cr.measure.CareGapsProperties; -import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions; -import org.opencds.cqf.fhir.cr.measure.r4.R4CareGapsService; -import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureService; -import org.opencds.cqf.fhir.cr.measure.r4.R4SubmitDataService; -import org.opencds.cqf.fhir.cr.plandefinition.r4.PlanDefinitionProcessor; -import org.opencds.cqf.fhir.cr.questionnaire.r4.QuestionnaireProcessor; -import org.opencds.cqf.fhir.cr.questionnaireresponse.r4.QuestionnaireResponseProcessor; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.Executor; - -@Configuration -public class CrR4Config { - - @Bean - IMeasureServiceFactory r4MeasureServiceFactory( - IRepositoryFactory theRepositoryFactory, MeasureEvaluationOptions theEvaluationOptions) { - return rd -> new R4MeasureService(theRepositoryFactory.create(rd), theEvaluationOptions); - } - - @Bean - ISubmitDataProcessorFactory r4SubmitDataProcessorFactory(IRepositoryFactory theRepositoryFactory) { - return rd -> new R4SubmitDataService(theRepositoryFactory.create(rd)); - } - - @Bean - ICqlExecutionServiceFactory r4CqlExecutionServiceFactory( - IRepositoryFactory theRepositoryFactory, EvaluationSettings theEvaluationSettings) { - return rd -> new R4CqlExecutionService(theRepositoryFactory.create(rd), theEvaluationSettings); - } - - @Bean - CqlExecutionOperationProvider r4CqlExecutionOperationProvider() { - return new CqlExecutionOperationProvider(); - } - - @Bean - ICareGapsServiceFactory careGapsServiceFactory( - IRepositoryFactory theRepositoryFactory, - CareGapsProperties theCareGapsProperties, - MeasureEvaluationOptions theMeasureEvaluationOptions, - @Qualifier("cqlExecutor") Executor theExecutor) { - return rd -> new R4CareGapsService( - theCareGapsProperties, - theRepositoryFactory.create(rd), - theMeasureEvaluationOptions, - theExecutor, - rd.getFhirServerBase()); - } - - @Bean - CareGapsOperationProvider r4CareGapsOperationProvider() { - return new CareGapsOperationProvider(); - } - - @Bean - SubmitDataProvider r4SubmitDataProvider() { - return new SubmitDataProvider(); - } - - @Bean - MeasureOperationsProvider r4MeasureOperationsProvider() { - return new MeasureOperationsProvider(); - } - - @Bean - IActivityDefinitionProcessorFactory r4ActivityDefinitionProcessorFactory( - IRepositoryFactory theRepositoryFactory, EvaluationSettings theEvaluationSettings) { - return rd -> new ActivityDefinitionProcessor( - theRepositoryFactory.create(rd), theEvaluationSettings); - } - - @Bean - IPlanDefinitionProcessorFactory r4PlanDefinitionProcessorFactory( - IRepositoryFactory theRepositoryFactory, EvaluationSettings theEvaluationSettings) { - return rd -> new PlanDefinitionProcessor( - theRepositoryFactory.create(rd), theEvaluationSettings); - } - - @Bean - IQuestionnaireProcessorFactory r4QuestionnaireProcessorFactory( - IRepositoryFactory theRepositoryFactory, EvaluationSettings theEvaluationSettings) { - return rd -> new QuestionnaireProcessor( - theRepositoryFactory.create(rd), theEvaluationSettings); - } - - @Bean - IQuestionnaireResponseProcessorFactory r4QuestionnaireResponseProcessorFactory( - IRepositoryFactory theRepositoryFactory, EvaluationSettings theEvaluationSettings) { - return rd -> new QuestionnaireResponseProcessor( - theRepositoryFactory.create(rd), theEvaluationSettings); - } - - @Bean - ActivityDefinitionApplyProvider r4ActivityDefinitionApplyProvider() { - return new ActivityDefinitionApplyProvider(); - } - - @Bean - PlanDefinitionApplyProvider r4PlanDefinitionApplyProvider() { - return new PlanDefinitionApplyProvider(); - } - - @Bean - QuestionnaireResponseExtractProvider - r4QuestionnaireResponseExtractProvider() { - return new QuestionnaireResponseExtractProvider(); - } - - @Bean - PlanDefinitionPackageProvider r4PlanDefinitionPackageProvider() { - return new PlanDefinitionPackageProvider(); - } - - @Bean - QuestionnairePackageProvider r4QuestionnairePackageProvider() { - return new QuestionnairePackageProvider(); - } - - @Bean - QuestionnairePopulateProvider r4QuestionnairePopulateProvider() { - return new QuestionnairePopulateProvider(); - } - - @Bean - public ProviderLoader r4PdLoader( - ApplicationContext theApplicationContext, FhirContext theFhirContext, RestfulServer theRestfulServer) { - - var selector = new ProviderSelector( - theFhirContext, - Map.of( - FhirVersionEnum.R4, - Arrays.asList( - MeasureOperationsProvider.class, - SubmitDataProvider.class, - CareGapsOperationProvider.class, - CqlExecutionOperationProvider.class, - ActivityDefinitionApplyProvider.class, - PlanDefinitionApplyProvider.class, - QuestionnaireResponseExtractProvider.class, - QuestionnairePackageProvider.class, - PlanDefinitionPackageProvider.class, - QuestionnairePopulateProvider.class))); - - return new ProviderLoader(theRestfulServer, theApplicationContext, selector); - } -} \ No newline at end of file diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java index 58c731fc2da..78bd7fd679b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java @@ -5,7 +5,6 @@ import ca.uhn.fhir.cr.config.dstu3.ExtractOperationConfig; import ca.uhn.fhir.cr.config.dstu3.PackageOperationConfig; import ca.uhn.fhir.cr.config.dstu3.PopulateOperationConfig; -import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.jpa.starter.annotations.OnDSTU3Condition; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; @@ -27,15 +26,17 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; @Configuration @Conditional({ OnDSTU3Condition.class, CrConfigCondition.class }) -@Import({ CrDstu3Config.class, +@Import({ + BaseCrConfig.class, + CrDstu3Config.class, ApplyOperationConfig.class, ExtractOperationConfig.class, PackageOperationConfig.class, - PopulateOperationConfig.class, BaseCrConfig.class}) + PopulateOperationConfig.class +}) public class StarterCrDstu3Config { private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrDstu3Config.class); @@ -52,7 +53,7 @@ MeasureEvaluationOptions measureEvaluationOptions(EvaluationSettings theEvaluati @Bean public EvaluationSettings evaluationSettings( - AppProperties theAppProperties, + CrProperties theCrProperties, Map theGlobalLibraryCache, Map theGlobalModelCache, Map> theGlobalValueSetCache) { @@ -61,10 +62,10 @@ public EvaluationSettings evaluationSettings( var cqlEngineOptions = cqlOptions.getCqlEngineOptions(); Set options = EnumSet.noneOf(CqlEngine.Options.class); - if (theAppProperties.isCqlRuntimeEnableExpressionCaching()) { + if (theCrProperties.isCqlRuntimeEnableExpressionCaching()) { options.add(CqlEngine.Options.EnableExpressionCaching); } - if (theAppProperties.isCqlRuntimeEnableValidation()) { + if (theCrProperties.isCqlRuntimeEnableValidation()) { options.add(CqlEngine.Options.EnableValidation); } cqlEngineOptions.setOptions(options); @@ -72,53 +73,52 @@ public EvaluationSettings evaluationSettings( var cqlCompilerOptions = new CqlCompilerOptions(); - if (theAppProperties.isEnableDateRangeOptimization() - ) { + if (theCrProperties.isEnableDateRangeOptimization()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableDateRangeOptimization); } - if (theAppProperties.isEnableAnnotations()) { + if (theCrProperties.isEnableAnnotations()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableAnnotations); } - if (theAppProperties.isEnableLocators()) { + if (theCrProperties.isEnableLocators()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableLocators); } - if (theAppProperties.isEnableResultsType()) { + if (theCrProperties.isEnableResultsType()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableResultTypes); } - cqlCompilerOptions.setVerifyOnly(theAppProperties.isCqlCompilerVerifyOnly()); - if (theAppProperties.isEnableDetailedErrors()) { + cqlCompilerOptions.setVerifyOnly(theCrProperties.isCqlCompilerVerifyOnly()); + if (theCrProperties.isEnableDetailedErrors()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableDetailedErrors); } - cqlCompilerOptions.setErrorLevel(theAppProperties.getCqlCompilerErrorSeverityLevel()); - if (theAppProperties.isDisableListTraversal()) { + cqlCompilerOptions.setErrorLevel(theCrProperties.getCqlCompilerErrorSeverityLevel()); + if (theCrProperties.isDisableListTraversal()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableListTraversal); } - if (theAppProperties.isDisableListDemotion()) { + if (theCrProperties.isDisableListDemotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableListDemotion); } - if (theAppProperties.isDisableListPromotion()) { + if (theCrProperties.isDisableListPromotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableListPromotion); } - if (theAppProperties.isEnableIntervalDemotion()) { + if (theCrProperties.isEnableIntervalDemotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableIntervalDemotion); } - if (theAppProperties.isEnableIntervalPromotion()) { + if (theCrProperties.isEnableIntervalPromotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableIntervalPromotion); } - if (theAppProperties.isDisableMethodInvocation()) { + if (theCrProperties.isDisableMethodInvocation()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableMethodInvocation); } - if (theAppProperties.isRequireFromKeyword()) { + if (theCrProperties.isRequireFromKeyword()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.RequireFromKeyword); } - cqlCompilerOptions.setValidateUnits(theAppProperties.isCqlCompilerValidateUnits()); - if (theAppProperties.isDisableDefaultModelInfoLoad()) { + cqlCompilerOptions.setValidateUnits(theCrProperties.isCqlCompilerValidateUnits()); + if (theCrProperties.isDisableDefaultModelInfoLoad()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableDefaultModelInfoLoad); } - cqlCompilerOptions.setSignatureLevel(theAppProperties.getCqlCompilerSignatureLevel()); - cqlCompilerOptions.setCompatibilityLevel(theAppProperties.getCqlCompilerCompatibilityLevel()); - cqlCompilerOptions.setAnalyzeDataRequirements(theAppProperties.isCqlCompilerAnalyzeDataRequirements()); - cqlCompilerOptions.setCollapseDataRequirements(theAppProperties.isCqlCompilerCollapseDataRequirements()); + cqlCompilerOptions.setSignatureLevel(theCrProperties.getCqlCompilerSignatureLevel()); + cqlCompilerOptions.setCompatibilityLevel(theCrProperties.getCqlCompilerCompatibilityLevel()); + cqlCompilerOptions.setAnalyzeDataRequirements(theCrProperties.isCqlCompilerAnalyzeDataRequirements()); + cqlCompilerOptions.setCollapseDataRequirements(theCrProperties.isCqlCompilerCollapseDataRequirements()); cqlOptions.setCqlCompilerOptions(cqlCompilerOptions); evaluationSettings.setLibraryCache(theGlobalLibraryCache); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java index 46e4abe4119..a562e584ab8 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java @@ -1,10 +1,15 @@ package ca.uhn.fhir.jpa.starter.cr; +import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig; +import ca.uhn.fhir.cr.config.r4.CrR4Config; +import ca.uhn.fhir.cr.config.r4.ExtractOperationConfig; +import ca.uhn.fhir.cr.config.r4.PackageOperationConfig; +import ca.uhn.fhir.cr.config.r4.PopulateOperationConfig; import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; import ca.uhn.fhir.cr.common.CqlThreadFactory; -import ca.uhn.fhir.jpa.starter.AppProperties; + import org.cqframework.cql.cql2elm.CqlCompilerOptions; import org.cqframework.cql.cql2elm.model.CompiledLibrary; import org.cqframework.cql.cql2elm.model.Model; @@ -18,7 +23,11 @@ import org.opencds.cqf.fhir.utility.ValidationProfile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.*; +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.security.concurrent.DelegatingSecurityContextExecutorService; import java.util.EnumSet; @@ -30,7 +39,14 @@ @Configuration @Conditional({ OnR4Condition.class, CrConfigCondition.class }) -@Import({BaseCrConfig.class, CrR4Config.class}) +@Import({ + BaseCrConfig.class, + CrR4Config.class, + ApplyOperationConfig.class, + ExtractOperationConfig.class, + PackageOperationConfig.class, + PopulateOperationConfig.class +}) public class StarterCrR4Config { private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrR4Config.class); @@ -47,11 +63,11 @@ public ExecutorService cqlExecutor() { } @Bean - CareGapsProperties careGapsProperties(AppProperties theAppProperties) { + CareGapsProperties careGapsProperties(CrProperties theCrProperties) { var careGapsProperties = new CareGapsProperties(); careGapsProperties.setThreadedCareGapsEnabled(false); - careGapsProperties.setCareGapsReporter(theAppProperties.getCareGapsReporter()); - careGapsProperties.setCareGapsCompositionSectionAuthor(theAppProperties.getCareGapsSectionAuthor()); + careGapsProperties.setCareGapsReporter(theCrProperties.getCareGapsReporter()); + careGapsProperties.setCareGapsCompositionSectionAuthor(theCrProperties.getCareGapsSectionAuthor()); return careGapsProperties; } @@ -67,7 +83,7 @@ MeasureEvaluationOptions measureEvaluationOptions(EvaluationSettings theEvaluati @Bean public EvaluationSettings evaluationSettings( - AppProperties theAppProperties, + CrProperties theCrProperties, Map theGlobalLibraryCache, Map theGlobalModelCache, Map> theGlobalValueSetCache) { @@ -76,10 +92,10 @@ public EvaluationSettings evaluationSettings( var cqlEngineOptions = cqlOptions.getCqlEngineOptions(); Set options = EnumSet.noneOf(CqlEngine.Options.class); - if (theAppProperties.isCqlRuntimeEnableExpressionCaching()) { + if (theCrProperties.isCqlRuntimeEnableExpressionCaching()) { options.add(CqlEngine.Options.EnableExpressionCaching); } - if (theAppProperties.isCqlRuntimeEnableValidation()) { + if (theCrProperties.isCqlRuntimeEnableValidation()) { options.add(CqlEngine.Options.EnableValidation); } cqlEngineOptions.setOptions(options); @@ -87,53 +103,52 @@ public EvaluationSettings evaluationSettings( var cqlCompilerOptions = new CqlCompilerOptions(); - if (theAppProperties.isEnableDateRangeOptimization() - ) { + if (theCrProperties.isEnableDateRangeOptimization()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableDateRangeOptimization); } - if (theAppProperties.isEnableAnnotations()) { + if (theCrProperties.isEnableAnnotations()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableAnnotations); } - if (theAppProperties.isEnableLocators()) { + if (theCrProperties.isEnableLocators()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableLocators); } - if (theAppProperties.isEnableResultsType()) { + if (theCrProperties.isEnableResultsType()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableResultTypes); } - cqlCompilerOptions.setVerifyOnly(theAppProperties.isCqlCompilerVerifyOnly()); - if (theAppProperties.isEnableDetailedErrors()) { + cqlCompilerOptions.setVerifyOnly(theCrProperties.isCqlCompilerVerifyOnly()); + if (theCrProperties.isEnableDetailedErrors()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableDetailedErrors); } - cqlCompilerOptions.setErrorLevel(theAppProperties.getCqlCompilerErrorSeverityLevel()); - if (theAppProperties.isDisableListTraversal()) { + cqlCompilerOptions.setErrorLevel(theCrProperties.getCqlCompilerErrorSeverityLevel()); + if (theCrProperties.isDisableListTraversal()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableListTraversal); } - if (theAppProperties.isDisableListDemotion()) { + if (theCrProperties.isDisableListDemotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableListDemotion); } - if (theAppProperties.isDisableListPromotion()) { + if (theCrProperties.isDisableListPromotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableListPromotion); } - if (theAppProperties.isEnableIntervalDemotion()) { + if (theCrProperties.isEnableIntervalDemotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableIntervalDemotion); } - if (theAppProperties.isEnableIntervalPromotion()) { + if (theCrProperties.isEnableIntervalPromotion()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.EnableIntervalPromotion); } - if (theAppProperties.isDisableMethodInvocation()) { + if (theCrProperties.isDisableMethodInvocation()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableMethodInvocation); } - if (theAppProperties.isRequireFromKeyword()) { + if (theCrProperties.isRequireFromKeyword()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.RequireFromKeyword); } - cqlCompilerOptions.setValidateUnits(theAppProperties.isCqlCompilerValidateUnits()); - if (theAppProperties.isDisableDefaultModelInfoLoad()) { + cqlCompilerOptions.setValidateUnits(theCrProperties.isCqlCompilerValidateUnits()); + if (theCrProperties.isDisableDefaultModelInfoLoad()) { cqlCompilerOptions.setOptions(CqlCompilerOptions.Options.DisableDefaultModelInfoLoad); } - cqlCompilerOptions.setSignatureLevel(theAppProperties.getCqlCompilerSignatureLevel()); - cqlCompilerOptions.setCompatibilityLevel(theAppProperties.getCqlCompilerCompatibilityLevel()); - cqlCompilerOptions.setAnalyzeDataRequirements(theAppProperties.isCqlCompilerAnalyzeDataRequirements()); - cqlCompilerOptions.setCollapseDataRequirements(theAppProperties.isCqlCompilerCollapseDataRequirements()); + cqlCompilerOptions.setSignatureLevel(theCrProperties.getCqlCompilerSignatureLevel()); + cqlCompilerOptions.setCompatibilityLevel(theCrProperties.getCqlCompilerCompatibilityLevel()); + cqlCompilerOptions.setAnalyzeDataRequirements(theCrProperties.isCqlCompilerAnalyzeDataRequirements()); + cqlCompilerOptions.setCollapseDataRequirements(theCrProperties.isCqlCompilerCollapseDataRequirements()); cqlOptions.setCqlCompilerOptions(cqlCompilerOptions); evaluationSettings.setLibraryCache(theGlobalLibraryCache); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index a0755d48042..c065191d3db 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -53,14 +53,19 @@ spring: # hibernate.search.backend.analysis.configurer: ca.uhn.fhir.jpa.search.HapiHSearchAnalysisConfigurers$HapiElasticAnalysisConfigurer hapi: fhir: + ### This flag when enabled to true, will avail evaluate measure operations from CR Module. + ### Flag is false by default, can be passed as command line argument to override. + cr: + enabled: true + + cdshooks: + enabled: true + clientIdHeaderName: client_id ### This enables the swagger-ui at /fhir/swagger-ui/index.html as well as the /fhir/api-docs (see https://hapifhir.io/hapi-fhir/docs/server_plain/openapi.html) openapi_enabled: true ### This is the FHIR version. Choose between, DSTU2, DSTU3, R4 or R5 fhir_version: R4 - ### This flag when enabled to true, will avail evaluate measure operations from CR Module. - ### Flag is false by default, can be passed as command line argument to override. - cr_enabled: true ### enable to use the ApacheProxyAddressStrategy which uses X-Forwarded-* headers ### to determine the FHIR server address @@ -104,7 +109,6 @@ hapi: # auto_create_placeholder_reference_targets: false ### tells the server to automatically append the current version of the target resource to references at these paths # auto_version_reference_at_paths: Device.patient, Device.location, Device.parent, DeviceMetric.parent, DeviceMetric.source, Observation.device, Observation.subject - # cr_enabled: true # ips_enabled: false # default_encoding: JSON # default_pretty_print: true 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 e058a61bd93..be96839eb92 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java @@ -3,6 +3,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.jpa.searchparam.config.NicknameServiceConfig; +import ca.uhn.fhir.jpa.starter.cr.CrProperties; import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.MethodOutcome; @@ -42,9 +43,9 @@ "hapi.fhir.fhir_version=r4", //"hapi.fhir.subscription.websocket_enabled=true", //"hapi.fhir.mdm_enabled=true", - "hapi.fhir.cr_enabled=true", - "hapi.fhir.caregaps_section_author=Organization/alphora-author", - "hapi.fhir.caregaps_reporter=Organization/alphora", + "hapi.fhir.cr.enabled=true", + "hapi.fhir.cr.caregaps_section_author=Organization/alphora-author", + "hapi.fhir.cr.caregaps_reporter=Organization/alphora", "hapi.fhir.implementationguides.dk-core.name=hl7.fhir.dk.core", "hapi.fhir.implementationguides.dk-core.version=1.1.0", "hapi.fhir.auto_create_placeholder_reference_targets=true", @@ -57,7 +58,7 @@ class ExampleServerR4IT implements IServerSupport{ private IGenericClient ourClient; private FhirContext ourCtx; - @Autowired private AppProperties appProperties; + @Autowired private CrProperties crProperties; @LocalServerPort private int port; @@ -253,8 +254,8 @@ void testWebsocketSubscription() throws Exception { @Test void testCareGaps() throws IOException { - var reporter = appProperties.getCareGapsReporter(); - var author = appProperties.getCareGapsSectionAuthor(); + var reporter = crProperties.getCareGapsReporter(); + var author = crProperties.getCareGapsSectionAuthor(); assertTrue(reporter.equals("Organization/alphora")); assertTrue(author.equals("Organization/alphora-author"));