diff --git a/README.md b/README.md index 75f18c2..6bc5789 100644 --- a/README.md +++ b/README.md @@ -336,12 +336,12 @@ NOTE: MS SQL Server by default uses a case-insensitive codepage. This will cause It is recommended to deploy a case-sensitive database prior to running HAPI FHIR when using MS SQL Server to avoid these and potentially other issues. ## Adding custom interceptors -Custom interceptors can be registered with the server by including the property `hapi.fhir.custom-interceptor-classes`. This will take a comma separated list of fully-qualified class names which will be registered with the server. -Interceptors will be discovered in one of two ways: +Custom interceptors can be registered with the server by including the property `hapi.fhir.custom-interceptor-classes`. This will take a comma separated list of fully-qualified class names which will be registered with the server. +Interceptors will be discovered in one of two ways: 1) discovered from the Spring application context as existing Beans (can be used in conjunction with `hapi.fhir.custom-bean-packages`) or registered with Spring via other methods -or +or 2) classes will be instantiated via reflection if no matching Bean is found 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 4eef8da..2ab6181 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -1,7 +1,5 @@ package ca.uhn.fhir.jpa.starter; - - import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings.ClientIdStrategyEnum; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; @@ -23,7 +21,7 @@ import java.util.Set; @Configuration @EnableConfigurationProperties public class AppProperties { - + private Boolean ips_enabled = false; private Boolean openapi_enabled = false; private Boolean mdm_enabled = false; @@ -76,12 +74,13 @@ public class AppProperties { private Boolean reload_existing_implementationguides = false; private Map implementationGuides = null; private Boolean cr_enabled = false; - private Boolean ig_runtime_upload_enabled = false; + private Boolean ig_runtime_upload_enabled = false; private String staticLocation = null; private String staticLocationPrefix = "/static"; private Boolean lastn_enabled = false; private boolean store_resource_in_lucene_index_enabled = false; - private NormalizedQuantitySearchLevel normalized_quantity_search_level = NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED; + private NormalizedQuantitySearchLevel normalized_quantity_search_level = + NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED; private Boolean use_apache_address_strategy = false; private Boolean use_apache_address_strategy_https = false; private Integer bundle_batch_pool_size = 20; @@ -97,12 +96,10 @@ public class AppProperties { this.staticLocationPrefix = staticLocationPrefix; } - public List getCustomInterceptorClasses() { return custom_interceptor_classes; } - public String getStaticLocation() { return staticLocation; } @@ -111,7 +108,6 @@ public class AppProperties { this.staticLocation = staticLocation; } - public Boolean getOpenapi_enabled() { return openapi_enabled; } @@ -168,7 +164,6 @@ public class AppProperties { this.ips_enabled = ips_enabled; } - public Boolean getMdm_enabled() { return mdm_enabled; } @@ -245,8 +240,7 @@ public class AppProperties { return client_id_strategy; } - public void setClient_id_strategy( - ClientIdStrategyEnum client_id_strategy) { + public void setClient_id_strategy(ClientIdStrategyEnum client_id_strategy) { this.client_id_strategy = client_id_strategy; } @@ -294,8 +288,7 @@ public class AppProperties { return allow_override_default_search_params; } - public void setAllow_override_default_search_params( - Boolean allow_override_default_search_params) { + public void setAllow_override_default_search_params(Boolean allow_override_default_search_params) { this.allow_override_default_search_params = allow_override_default_search_params; } @@ -303,8 +296,7 @@ public class AppProperties { return auto_create_placeholder_reference_targets; } - public void setAuto_create_placeholder_reference_targets( - Boolean auto_create_placeholder_reference_targets) { + public void setAuto_create_placeholder_reference_targets(Boolean auto_create_placeholder_reference_targets) { this.auto_create_placeholder_reference_targets = auto_create_placeholder_reference_targets; } @@ -364,8 +356,7 @@ public class AppProperties { return enforce_referential_integrity_on_delete; } - public void setEnforce_referential_integrity_on_delete( - Boolean enforce_referential_integrity_on_delete) { + public void setEnforce_referential_integrity_on_delete(Boolean enforce_referential_integrity_on_delete) { this.enforce_referential_integrity_on_delete = enforce_referential_integrity_on_delete; } @@ -373,8 +364,7 @@ public class AppProperties { return enforce_referential_integrity_on_write; } - public void setEnforce_referential_integrity_on_write( - Boolean enforce_referential_integrity_on_write) { + public void setEnforce_referential_integrity_on_write(Boolean enforce_referential_integrity_on_write) { this.enforce_referential_integrity_on_write = enforce_referential_integrity_on_write; } @@ -510,13 +500,11 @@ public class AppProperties { this.tester = tester; } - public Boolean getNarrative_enabled() - { + public Boolean getNarrative_enabled() { return narrative_enabled; } - public void setNarrative_enabled(Boolean narrative_enabled) - { + public void setNarrative_enabled(Boolean narrative_enabled) { this.narrative_enabled = narrative_enabled; } @@ -607,15 +595,14 @@ public class AppProperties { public void setAllow_Credentials(Boolean allow_Credentials) { this.allow_Credentials = allow_Credentials; } - - } public static class Logger { private String name = "fhirtest.access"; private String error_format = "ERROR - ${requestVerb} ${requestUrl}"; - private String format = "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]"; + private String format = + "Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]"; private Boolean log_exceptions = true; public String getName() { @@ -651,7 +638,6 @@ public class AppProperties { } } - public static class Tester { private String name; @@ -692,7 +678,6 @@ public class AppProperties { } } - public static class Validation { private Boolean requests_enabled = false; @@ -727,6 +712,7 @@ public class AppProperties { public void setPartitioning_include_in_search_hashes(Boolean partitioning_include_in_search_hashes) { this.partitioning_include_in_search_hashes = partitioning_include_in_search_hashes; } + public Boolean getAllow_references_across_partitions() { return allow_references_across_partitions; } @@ -766,7 +752,6 @@ public class AppProperties { this.email = email; } - public static class Email { public String getFrom() { return from; @@ -859,4 +844,4 @@ public class AppProperties { public void setEnable_index_of_type(boolean enable_index_of_type) { this.enable_index_of_type = enable_index_of_type; } -} \ No newline at end of file +} 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 81fb73b..9131f8d 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java @@ -1,9 +1,6 @@ package ca.uhn.fhir.jpa.starter; import ca.uhn.fhir.batch2.jobs.config.Batch2JobsConfig; -import ca.uhn.fhir.cr.common.IRepositoryFactory; -import ca.uhn.fhir.cr.repo.HapiFhirRepository; -import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.batch2.JpaBatch2Config; import ca.uhn.fhir.jpa.starter.annotations.OnEitherVersion; import ca.uhn.fhir.jpa.starter.cdshooks.StarterCdsHooksConfig; @@ -32,19 +29,19 @@ import org.springframework.context.annotation.Import; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; -@ServletComponentScan(basePackageClasses = { RestfulServer.class }) -@SpringBootApplication(exclude = { ElasticsearchRestClientAutoConfiguration.class, ThymeleafAutoConfiguration.class }) +@ServletComponentScan(basePackageClasses = {RestfulServer.class}) +@SpringBootApplication(exclude = {ElasticsearchRestClientAutoConfiguration.class, ThymeleafAutoConfiguration.class}) @Import({ - StarterCrR4Config.class, - StarterCrDstu3Config.class, - StarterCdsHooksConfig.class, - SubscriptionSubmitterConfig.class, - SubscriptionProcessorConfig.class, - SubscriptionChannelConfig.class, - WebsocketDispatcherConfig.class, - MdmConfig.class, - JpaBatch2Config.class, - Batch2JobsConfig.class + StarterCrR4Config.class, + StarterCrDstu3Config.class, + StarterCdsHooksConfig.class, + SubscriptionSubmitterConfig.class, + SubscriptionProcessorConfig.class, + SubscriptionChannelConfig.class, + WebsocketDispatcherConfig.class, + MdmConfig.class, + JpaBatch2Config.class, + Batch2JobsConfig.class }) public class Application extends SpringBootServletInitializer { @@ -57,8 +54,7 @@ public class Application extends SpringBootServletInitializer { } @Override - protected SpringApplicationBuilder configure( - SpringApplicationBuilder builder) { + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(Application.class); } @@ -80,11 +76,11 @@ public class Application extends SpringBootServletInitializer { @Bean public ServletRegistrationBean overlayRegistrationBean() { - AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext(); + AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = + new AnnotationConfigWebApplicationContext(); annotationConfigWebApplicationContext.register(FhirTesterConfig.class); - DispatcherServlet dispatcherServlet = new DispatcherServlet( - annotationConfigWebApplicationContext); + DispatcherServlet dispatcherServlet = new DispatcherServlet(annotationConfigWebApplicationContext); dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class); dispatcherServlet.setContextConfigLocation(FhirTesterConfig.class.getName()); @@ -93,11 +89,10 @@ public class Application extends SpringBootServletInitializer { registrationBean.addUrlMappings("/*"); registrationBean.setLoadOnStartup(1); return registrationBean; - } -// @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/ExtraStaticFilesConfigurer.java b/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java index a3b528c..2edb3aa 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java @@ -19,33 +19,32 @@ public class ExtraStaticFilesConfigurer implements WebMvcConfigurer { public ExtraStaticFilesConfigurer(AppProperties appProperties) { rootContextPath = appProperties.getStaticLocationPrefix(); - if(rootContextPath.endsWith("/")) + if (rootContextPath.endsWith("/")) rootContextPath = rootContextPath.substring(0, rootContextPath.lastIndexOf('/')); staticLocation = appProperties.getStaticLocation(); - if(staticLocation.endsWith("/")) - staticLocation = staticLocation.substring(0, staticLocation.lastIndexOf('/')); - + if (staticLocation.endsWith("/")) staticLocation = staticLocation.substring(0, staticLocation.lastIndexOf('/')); } + @Override + public void addResourceHandlers(ResourceHandlerRegistry theRegistry) { + theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation); + } @Override - public void addResourceHandlers(ResourceHandlerRegistry theRegistry) { - theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation); - } + public void addViewControllers(ViewControllerRegistry registry) { + String path = URI.create(staticLocation).getPath(); + String lastSegment = path.substring(path.lastIndexOf('/') + 1); - @Override - public void addViewControllers(ViewControllerRegistry registry) { - String path = URI.create(staticLocation).getPath(); - String lastSegment = path.substring(path.lastIndexOf('/') + 1); + registry.addViewController(rootContextPath) + .setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); - registry.addViewController(rootContextPath).setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); + registry.addViewController(rootContextPath + "/*") + .setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); - registry.addViewController(rootContextPath + "/*").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); + registry.addViewController(rootContextPath + "/" + lastSegment + "/") + .setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); - registry.addViewController(rootContextPath + "/" + lastSegment + "/").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); - - registry.setOrder(Ordered.HIGHEST_PRECEDENCE); - } - -} \ No newline at end of file + registry.setOrder(Ordered.HIGHEST_PRECEDENCE); + } +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnCorsPresent.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnCorsPresent.java index e4a44d7..15a2490 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnCorsPresent.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnCorsPresent.java @@ -10,9 +10,11 @@ public class OnCorsPresent implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - AppProperties config = Binder.get(conditionContext.getEnvironment()).bind("hapi.fhir", AppProperties.class).orElse(null); + AppProperties config = Binder.get(conditionContext.getEnvironment()) + .bind("hapi.fhir", AppProperties.class) + .orElse(null); if (config == null) return false; if (config.getCors() == null) return false; return true; } -} \ No newline at end of file +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU2Condition.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU2Condition.java index 2c2419c..2f27323 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU2Condition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU2Condition.java @@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class OnDSTU2Condition implements Condition { - @Override - public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. - getEnvironment() - .getProperty("hapi.fhir.fhir_version") - .toUpperCase()); + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { + FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext + .getEnvironment() + .getProperty("hapi.fhir.fhir_version") + .toUpperCase()); - return version == FhirVersionEnum.DSTU2; - - } + return version == FhirVersionEnum.DSTU2; + } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU3Condition.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU3Condition.java index 1196245..7e5e117 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU3Condition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnDSTU3Condition.java @@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class OnDSTU3Condition implements Condition { - @Override - public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. - getEnvironment() - .getProperty("hapi.fhir.fhir_version") - .toUpperCase()); + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { + FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext + .getEnvironment() + .getProperty("hapi.fhir.fhir_version") + .toUpperCase()); - return version == FhirVersionEnum.DSTU3; - - } + return version == FhirVersionEnum.DSTU3; + } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnEitherVersion.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnEitherVersion.java index 463f779..98af287 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnEitherVersion.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnEitherVersion.java @@ -6,34 +6,28 @@ import org.springframework.context.annotation.Conditional; public class OnEitherVersion extends AnyNestedCondition { - OnEitherVersion() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @Override - protected ConditionOutcome getFinalMatchOutcome(MemberMatchOutcomes memberOutcomes) { - ConditionOutcome result = super.getFinalMatchOutcome(memberOutcomes); - return result; - } - - @Conditional(OnDSTU2Condition.class) - static class OnDSTU2 { - } - - @Conditional(OnDSTU3Condition.class) - static class OnDSTU3 { - } - - @Conditional(OnR4Condition.class) - static class OnR4 { - } - - @Conditional(OnR4BCondition.class) - static class OnR4B { + OnEitherVersion() { + super(ConfigurationPhase.REGISTER_BEAN); } - @Conditional(OnR5Condition.class) - static class OnR5 { - } + @Override + protected ConditionOutcome getFinalMatchOutcome(MemberMatchOutcomes memberOutcomes) { + ConditionOutcome result = super.getFinalMatchOutcome(memberOutcomes); + return result; + } -} \ No newline at end of file + @Conditional(OnDSTU2Condition.class) + static class OnDSTU2 {} + + @Conditional(OnDSTU3Condition.class) + static class OnDSTU3 {} + + @Conditional(OnR4Condition.class) + static class OnR4 {} + + @Conditional(OnR4BCondition.class) + static class OnR4B {} + + @Conditional(OnR5Condition.class) + static class OnR5 {} +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnImplementationGuidesPresent.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnImplementationGuidesPresent.java index 7b11df1..c320801 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnImplementationGuidesPresent.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnImplementationGuidesPresent.java @@ -10,9 +10,11 @@ public class OnImplementationGuidesPresent implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - AppProperties config = Binder.get(conditionContext.getEnvironment()).bind("hapi.fhir", AppProperties.class).orElse(null); + AppProperties config = Binder.get(conditionContext.getEnvironment()) + .bind("hapi.fhir", AppProperties.class) + .orElse(null); if (config == null) return false; if (config.getImplementationGuides() == null) return false; return !config.getImplementationGuides().isEmpty(); } -} \ No newline at end of file +} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4BCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4BCondition.java index e323a22..76833cf 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4BCondition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4BCondition.java @@ -8,10 +8,10 @@ import org.springframework.core.type.AnnotatedTypeMetadata; public class OnR4BCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - String version = conditionContext. - getEnvironment() - .getProperty("hapi.fhir.fhir_version") - .toUpperCase(); + String version = conditionContext + .getEnvironment() + .getProperty("hapi.fhir.fhir_version") + .toUpperCase(); return FhirVersionEnum.R4B.name().equals(version); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4Condition.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4Condition.java index e362aea..73f6061 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4Condition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR4Condition.java @@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class OnR4Condition implements Condition { - @Override - public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. - getEnvironment() - .getProperty("hapi.fhir.fhir_version") - .toUpperCase()); + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { + FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext + .getEnvironment() + .getProperty("hapi.fhir.fhir_version") + .toUpperCase()); - return version == FhirVersionEnum.R4; - - } + return version == FhirVersionEnum.R4; + } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR5Condition.java b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR5Condition.java index 1ecca66..f30d9dc 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR5Condition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/annotations/OnR5Condition.java @@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class OnR5Condition implements Condition { - @Override - public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. - getEnvironment() - .getProperty("hapi.fhir.fhir_version") - .toUpperCase()); + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { + FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext + .getEnvironment() + .getProperty("hapi.fhir.fhir_version") + .toUpperCase()); - return version == FhirVersionEnum.R5; - - } + return version == FhirVersionEnum.R5; + } } 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 index 5553419..b90e1db 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksConfigCondition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksConfigCondition.java @@ -6,9 +6,9 @@ import org.springframework.core.type.AnnotatedTypeMetadata; public class CdsHooksConfigCondition implements Condition { - @Override - public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { + @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/CdsHooksRequest.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksRequest.java index 1007dba..088eab2 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksRequest.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksRequest.java @@ -3,7 +3,5 @@ package ca.uhn.fhir.jpa.starter.cdshooks; import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -@JsonIgnoreProperties({ "extension" }) -public class CdsHooksRequest extends CdsServiceRequestJson { - -} +@JsonIgnoreProperties({"extension"}) +public class CdsHooksRequest extends CdsServiceRequestJson {} 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 f8a324c..5849ec5 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 @@ -1,24 +1,5 @@ package ca.uhn.fhir.jpa.starter.cdshooks; -import java.io.IOException; -import java.util.stream.Collectors; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.http.entity.ContentType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Configurable; -import org.springframework.beans.factory.annotation.Qualifier; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParser; - import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; @@ -26,6 +7,22 @@ import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry; import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson; import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson; import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServicesJson; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParser; +import org.apache.http.entity.ContentType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.beans.factory.annotation.Qualifier; + +import java.io.IOException; +import java.util.stream.Collectors; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import static ca.uhn.hapi.fhir.cdshooks.config.CdsHooksConfig.CDS_HOOKS_OBJECT_MAPPER_FACTORY; @@ -36,12 +33,16 @@ public class CdsHooksServlet extends HttpServlet { @Autowired private AppProperties appProperties; + @Autowired private ProviderConfiguration providerConfiguration; + @Autowired ICdsServiceRegistry cdsServiceRegistry; + @Autowired RestfulServer restfulServer; + @Autowired @Qualifier(CDS_HOOKS_OBJECT_MAPPER_FACTORY) ObjectMapper objectMapper; @@ -70,8 +71,11 @@ public class CdsHooksServlet extends HttpServlet { } ErrorHandling.setAccessControlHeaders(response, appProperties); response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType()); - response.getWriter().println(new GsonBuilder().setPrettyPrinting().create().toJson( - JsonParser.parseString(objectMapper.writeValueAsString(getServices())))); + response.getWriter() + .println(new GsonBuilder() + .setPrettyPrinting() + .create() + .toJson(JsonParser.parseString(objectMapper.writeValueAsString(getServices())))); } @Override @@ -79,8 +83,8 @@ public class CdsHooksServlet extends HttpServlet { throws ServletException, IOException { try { if (request.getContentType() == null || !request.getContentType().startsWith("application/json")) { - throw new ServletException(String.format("Invalid content type %s. Please use application/json.", - request.getContentType())); + throw new ServletException(String.format( + "Invalid content type %s. Please use application/json.", request.getContentType())); } logger.info(request.getRequestURI()); String service = request.getPathInfo().replace("/", ""); @@ -92,7 +96,10 @@ public class CdsHooksServlet extends HttpServlet { CdsServiceResponseJson serviceResponseJson = cdsServiceRegistry.callService(service, cdsHooksRequest); // Using GSON pretty print format as Jackson's is ugly - String jsonResponse = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create() + String jsonResponse = new GsonBuilder() + .disableHtmlEscaping() + .setPrettyPrinting() + .create() .toJson(JsonParser.parseString(objectMapper.writeValueAsString(serviceResponseJson))); logger.info(jsonResponse); response.setContentType("text/json;charset=UTF-8"); @@ -111,7 +118,9 @@ public class CdsHooksServlet extends HttpServlet { logger.info("cds-hooks hook instance: {}", request.getHookInstance()); 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() { diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ErrorHandling.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ErrorHandling.java index 203a1ef..38e8d7b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ErrorHandling.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ErrorHandling.java @@ -1,91 +1,105 @@ package ca.uhn.fhir.jpa.starter.cdshooks; +import ca.uhn.fhir.jpa.starter.AppProperties; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; + import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; - import javax.servlet.http.HttpServletResponse; -import ca.uhn.fhir.jpa.starter.AppProperties; -import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; - public class ErrorHandling { private ErrorHandling() {} - public static void handleError(HttpServletResponse response, String message, - Exception e, AppProperties myAppProperties) - throws IOException { - setAccessControlHeaders(response, myAppProperties); - response.setStatus(500); // This will be overwritten with the correct status code downstream if needed. - response.getWriter().println(message); - printMessageAndCause(e, response); - if (e instanceof BaseServerResponseException) { - handleServerResponseException((BaseServerResponseException) e, response); - } else if (e.getCause() instanceof BaseServerResponseException) { - handleServerResponseException((BaseServerResponseException) e.getCause(), response); - } - printStackTrack(e, response); - } + public static void handleError( + HttpServletResponse response, String message, Exception e, AppProperties myAppProperties) + throws IOException { + setAccessControlHeaders(response, myAppProperties); + response.setStatus(500); // This will be overwritten with the correct status code downstream if needed. + response.getWriter().println(message); + printMessageAndCause(e, response); + if (e instanceof BaseServerResponseException) { + handleServerResponseException((BaseServerResponseException) e, response); + } else if (e.getCause() instanceof BaseServerResponseException) { + handleServerResponseException((BaseServerResponseException) e.getCause(), response); + } + printStackTrack(e, response); + } - private static void handleServerResponseException(BaseServerResponseException e, HttpServletResponse response) - throws IOException { - switch (e.getStatusCode()) { - case 401: - case 403: - response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode()); - response.getWriter().println( - "Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access."); - response.setStatus(412); - break; - case 404: - response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode()); - response.getWriter().println("Ensure the resource exists on the remote server."); - response.setStatus(412); - break; - default: - response.getWriter().println("Unhandled Error in Remote FHIR server: " + e.getStatusCode()); - } - } + private static void handleServerResponseException(BaseServerResponseException e, HttpServletResponse response) + throws IOException { + switch (e.getStatusCode()) { + case 401: + case 403: + response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode()); + response.getWriter() + .println( + "Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access."); + response.setStatus(412); + break; + case 404: + response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode()); + response.getWriter().println("Ensure the resource exists on the remote server."); + response.setStatus(412); + break; + default: + response.getWriter().println("Unhandled Error in Remote FHIR server: " + e.getStatusCode()); + } + } - private static void printMessageAndCause(Exception e, HttpServletResponse response) throws IOException { - if (e.getMessage() != null) { - response.getWriter().println(e.getMessage()); - } + private static void printMessageAndCause(Exception e, HttpServletResponse response) throws IOException { + if (e.getMessage() != null) { + response.getWriter().println(e.getMessage()); + } - if (e.getCause() != null && e.getCause().getMessage() != null) { - response.getWriter().println(e.getCause().getMessage()); - } - } + if (e.getCause() != null && e.getCause().getMessage() != null) { + response.getWriter().println(e.getCause().getMessage()); + } + } - private static void printStackTrack(Exception e, HttpServletResponse response) throws IOException { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - String exceptionAsString = sw.toString(); - response.getWriter().println(exceptionAsString); - } + private static void printStackTrack(Exception e, HttpServletResponse response) throws IOException { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + String exceptionAsString = sw.toString(); + response.getWriter().println(exceptionAsString); + } - public static void setAccessControlHeaders(HttpServletResponse resp, AppProperties myAppProperties) { - if (myAppProperties.getCors() != null) { - if (myAppProperties.getCors().getAllow_Credentials()) { - resp.setHeader("Access-Control-Allow-Origin", - myAppProperties.getCors().getAllowed_origin().stream().findFirst().get()); - resp.setHeader("Access-Control-Allow-Methods", - String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS"))); - resp.setHeader("Access-Control-Allow-Headers", - String.join(", ", Arrays.asList("x-fhir-starter", "Origin", - "Accept", "X-Requested-With", "Content-Type", "Authorization", "Cache-Control"))); - resp.setHeader("Access-Control-Expose-Headers", - String.join(", ", Arrays.asList("Location", "Content-Location"))); - resp.setHeader("Access-Control-Max-Age", "86400"); - } - } - } + public static void setAccessControlHeaders(HttpServletResponse resp, AppProperties myAppProperties) { + if (myAppProperties.getCors() != null) { + if (myAppProperties.getCors().getAllow_Credentials()) { + resp.setHeader( + "Access-Control-Allow-Origin", + myAppProperties.getCors().getAllowed_origin().stream() + .findFirst() + .get()); + resp.setHeader( + "Access-Control-Allow-Methods", + String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS"))); + resp.setHeader( + "Access-Control-Allow-Headers", + String.join( + ", ", + Arrays.asList( + "x-fhir-starter", + "Origin", + "Accept", + "X-Requested-With", + "Content-Type", + "Authorization", + "Cache-Control"))); + resp.setHeader( + "Access-Control-Expose-Headers", + String.join(", ", Arrays.asList("Location", "Content-Location"))); + resp.setHeader("Access-Control-Max-Age", "86400"); + } + } + } - public static class CdsHooksError extends RuntimeException { - public CdsHooksError(String message) { - super(message); - } - } + public static class CdsHooksError extends RuntimeException { + public CdsHooksError(String message) { + super(message); + } + } } 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 index bd62b00..edb4a89 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java @@ -4,7 +4,8 @@ import ca.uhn.fhir.jpa.starter.cr.CrProperties; public class ProviderConfiguration { - public static final ProviderConfiguration DEFAULT_PROVIDER_CONFIGURATION = new ProviderConfiguration(false, "client_id"); + public static final ProviderConfiguration DEFAULT_PROVIDER_CONFIGURATION = + new ProviderConfiguration(false, "client_id"); private final String clientIdHeaderName; private final boolean 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 59e7412..cb1371f 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 @@ -1,5 +1,11 @@ package ca.uhn.fhir.jpa.starter.cdshooks; +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; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.boot.web.servlet.ServletRegistrationBean; @@ -8,15 +14,8 @@ 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 }) +@Conditional({CdsHooksConfigCondition.class, CrConfigCondition.class}) @Import(CdsHooksConfig.class) public class StarterCdsHooksConfig { @Bean diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/ElasticsearchConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/ElasticsearchConfig.java index 78de890..df8ce49 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/ElasticsearchConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/ElasticsearchConfig.java @@ -10,18 +10,20 @@ import org.springframework.core.env.ConfigurableEnvironment; @Configuration public class ElasticsearchConfig { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ElasticsearchConfig.class); + @Bean public ElasticsearchSvcImpl elasticsearchSvc(ConfigurableEnvironment configurableEnvironment) { if (EnvironmentHelper.isElasticsearchEnabled(configurableEnvironment)) { String elasticsearchUrl = EnvironmentHelper.getElasticsearchServerUrl(configurableEnvironment); if (elasticsearchUrl.startsWith("http")) { - elasticsearchUrl =elasticsearchUrl.substring(elasticsearchUrl.indexOf("://") + 3); + elasticsearchUrl = elasticsearchUrl.substring(elasticsearchUrl.indexOf("://") + 3); } String elasticsearchProtocol = EnvironmentHelper.getElasticsearchServerProtocol(configurableEnvironment); String elasticsearchUsername = EnvironmentHelper.getElasticsearchServerUsername(configurableEnvironment); String elasticsearchPassword = EnvironmentHelper.getElasticsearchServerPassword(configurableEnvironment); ourLog.info("Configuring elasticsearch {} {}", elasticsearchProtocol, elasticsearchUrl); - return new ElasticsearchSvcImpl(elasticsearchProtocol, elasticsearchUrl, elasticsearchUsername, elasticsearchPassword); + return new ElasticsearchSvcImpl( + elasticsearchProtocol, elasticsearchUrl, elasticsearchUsername, elasticsearchPassword); } else { return null; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java index b8d3f0f..b0267d4 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java @@ -13,12 +13,8 @@ import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl; import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender; import ca.uhn.fhir.rest.server.mail.MailConfig; import ca.uhn.fhir.rest.server.mail.MailSvc; -import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; - import com.google.common.base.Strings; -import org.cqframework.cql.cql2elm.CqlTranslatorOptions; import org.hl7.fhir.r4.model.Bundle.BundleType; -import org.springframework.beans.factory.FactoryBean; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,21 +35,34 @@ public class FhirServerConfigCommon { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class); - public FhirServerConfigCommon(AppProperties appProperties) { - ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny") + " contains searches"); - ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny") + " multiple deletes"); - ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny") + " external references"); - ourLog.info("Server configured to " + (appProperties.getDao_scheduling_enabled() ? "enable" : "disable") + " DAO scheduling"); - ourLog.info("Server configured to " + (appProperties.getDelete_expunge_enabled() ? "enable" : "disable") + " delete expunges"); - ourLog.info("Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges"); - ourLog.info("Server configured to " + (appProperties.getAllow_override_default_search_params() ? "allow" : "deny") + " overriding default search params"); - ourLog.info("Server configured to " + (appProperties.getAuto_create_placeholder_reference_targets() ? "allow" : "disable") + " auto-creating placeholder references"); - ourLog.info("Server configured to auto-version references at paths {}", appProperties.getAuto_version_reference_at_paths()); + public FhirServerConfigCommon(AppProperties appProperties) { + ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny") + + " contains searches"); + ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny") + + " multiple deletes"); + ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny") + + " external references"); + ourLog.info("Server configured to " + (appProperties.getDao_scheduling_enabled() ? "enable" : "disable") + + " DAO scheduling"); + ourLog.info("Server configured to " + (appProperties.getDelete_expunge_enabled() ? "enable" : "disable") + + " delete expunges"); + ourLog.info( + "Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges"); + ourLog.info( + "Server configured to " + (appProperties.getAllow_override_default_search_params() ? "allow" : "deny") + + " overriding default search params"); + ourLog.info("Server configured to " + + (appProperties.getAuto_create_placeholder_reference_targets() ? "allow" : "disable") + + " auto-creating placeholder references"); + ourLog.info( + "Server configured to auto-version references at paths {}", + appProperties.getAuto_version_reference_at_paths()); if (appProperties.getSubscription().getEmail() != null) { - AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail(); - ourLog.info( - "Server is configured to enable email with host '" + email.getHost() + "' and port " + email.getPort()); + AppProperties.Subscription.Email email = + appProperties.getSubscription().getEmail(); + ourLog.info("Server is configured to enable email with host '" + email.getHost() + "' and port " + + email.getPort()); ourLog.info("Server will use '" + email.getFrom() + "' as the from email address"); if (!Strings.isNullOrEmpty(email.getUsername())) { @@ -85,19 +94,27 @@ public class FhirServerConfigCommon { public JpaStorageSettings jpaStorageSettings(AppProperties appProperties) { JpaStorageSettings jpaStorageSettings = new JpaStorageSettings(); - jpaStorageSettings.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? StorageSettings.IndexEnabledEnum.ENABLED : StorageSettings.IndexEnabledEnum.DISABLED); - jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets()); - jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); - jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write()); - jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete()); - jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); - jpaStorageSettings.setAllowMultipleDelete(appProperties.getAllow_multiple_delete()); - jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); - jpaStorageSettings.setSchedulingDisabled(!appProperties.getDao_scheduling_enabled()); - jpaStorageSettings.setDeleteExpungeEnabled(appProperties.getDelete_expunge_enabled()); - jpaStorageSettings.setExpungeEnabled(appProperties.getExpunge_enabled()); - if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) - jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); + jpaStorageSettings.setIndexMissingFields( + appProperties.getEnable_index_missing_fields() + ? StorageSettings.IndexEnabledEnum.ENABLED + : StorageSettings.IndexEnabledEnum.DISABLED); + jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets( + appProperties.getAuto_create_placeholder_reference_targets()); + jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); + jpaStorageSettings.setEnforceReferentialIntegrityOnWrite( + appProperties.getEnforce_referential_integrity_on_write()); + jpaStorageSettings.setEnforceReferentialIntegrityOnDelete( + appProperties.getEnforce_referential_integrity_on_delete()); + jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); + jpaStorageSettings.setAllowMultipleDelete(appProperties.getAllow_multiple_delete()); + jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); + jpaStorageSettings.setSchedulingDisabled(!appProperties.getDao_scheduling_enabled()); + jpaStorageSettings.setDeleteExpungeEnabled(appProperties.getDelete_expunge_enabled()); + jpaStorageSettings.setExpungeEnabled(appProperties.getExpunge_enabled()); + if (appProperties.getSubscription() != null + && appProperties.getSubscription().getEmail() != null) + jpaStorageSettings.setEmailFromAddress( + appProperties.getSubscription().getEmail().getFrom()); Integer maxFetchSize = appProperties.getMax_page_size(); jpaStorageSettings.setFetchSizeDefaultMaximum(maxFetchSize); @@ -115,13 +132,13 @@ public class FhirServerConfigCommon { // Subscriptions are enabled by channel type if (appProperties.getSubscription().getResthook_enabled()) { ourLog.info("Enabling REST-hook subscriptions"); - jpaStorageSettings - .addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK); + jpaStorageSettings.addSupportedSubscriptionType( + org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK); } if (appProperties.getSubscription().getEmail() != null) { ourLog.info("Enabling email subscriptions"); - jpaStorageSettings - .addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL); + jpaStorageSettings.addSupportedSubscriptionType( + org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL); } if (appProperties.getSubscription().getWebsocket_enabled()) { ourLog.info("Enabling websocket subscriptions"); @@ -130,120 +147,125 @@ public class FhirServerConfigCommon { } } - jpaStorageSettings.setFilterParameterEnabled(appProperties.getFilter_search_enabled()); - jpaStorageSettings.setAdvancedHSearchIndexing(appProperties.getAdvanced_lucene_indexing()); - jpaStorageSettings.setTreatBaseUrlsAsLocal(new HashSet<>(appProperties.getLocal_base_urls())); + jpaStorageSettings.setFilterParameterEnabled(appProperties.getFilter_search_enabled()); + jpaStorageSettings.setAdvancedHSearchIndexing(appProperties.getAdvanced_lucene_indexing()); + jpaStorageSettings.setTreatBaseUrlsAsLocal(new HashSet<>(appProperties.getLocal_base_urls())); - if (appProperties.getLastn_enabled()) { - jpaStorageSettings.setLastNEnabled(true); - } + if (appProperties.getLastn_enabled()) { + jpaStorageSettings.setLastNEnabled(true); + } - if(appProperties.getInline_resource_storage_below_size() != 0){ - jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size()); - } + if (appProperties.getInline_resource_storage_below_size() != 0) { + jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size()); + } - jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled()); - jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); - jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); + jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled()); + jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); + jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); + if (appProperties.getAllowed_bundle_types() != null) { + jpaStorageSettings.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream() + .map(BundleType::toCode) + .collect(Collectors.toSet())); + } + jpaStorageSettings.setDeferIndexingForCodesystemsOfSize( + appProperties.getDefer_indexing_for_codesystems_of_size()); - if (appProperties.getAllowed_bundle_types() != null) { - jpaStorageSettings.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet())); - } + if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) { + jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID); + jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); + } + // Parallel Batch GET execution settings + jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size()); + jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size()); - jpaStorageSettings.setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size()); + storageSettings(appProperties, jpaStorageSettings); + return jpaStorageSettings; + } + @Bean + public YamlPropertySourceLoader yamlPropertySourceLoader() { + return new YamlPropertySourceLoader(); + } - if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) { - jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID); - jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); - } - //Parallel Batch GET execution settings - jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size()); - jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size()); + @Bean + public PartitionSettings partitionSettings(AppProperties appProperties) { + PartitionSettings retVal = new PartitionSettings(); - storageSettings(appProperties, jpaStorageSettings); - return jpaStorageSettings; - } + // Partitioning + if (appProperties.getPartitioning() != null) { + retVal.setPartitioningEnabled(true); + retVal.setIncludePartitionInSearchHashes( + appProperties.getPartitioning().getPartitioning_include_in_search_hashes()); + if (appProperties.getPartitioning().getAllow_references_across_partitions()) { + retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED); + } else { + retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED); + } + } - @Bean - public YamlPropertySourceLoader yamlPropertySourceLoader() { - return new YamlPropertySourceLoader(); - } + return retVal; + } - @Bean - public PartitionSettings partitionSettings(AppProperties appProperties) { - PartitionSettings retVal = new PartitionSettings(); + @Primary + @Bean + public HibernatePropertiesProvider jpaStarterDialectProvider( + LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { + return new JpaHibernatePropertiesProvider(myEntityManagerFactory); + } - // Partitioning - if (appProperties.getPartitioning() != null) { - retVal.setPartitioningEnabled(true); - retVal.setIncludePartitionInSearchHashes(appProperties.getPartitioning().getPartitioning_include_in_search_hashes()); - if(appProperties.getPartitioning().getAllow_references_across_partitions()) { - retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED); - } else { - retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED); - } - } + protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) { + jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); + jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); + jpaStorageSettings.setDefaultSearchParamsCanBeOverridden( + appProperties.getAllow_override_default_search_params()); + if (appProperties.getSubscription() != null + && appProperties.getSubscription().getEmail() != null) + jpaStorageSettings.setEmailFromAddress( + appProperties.getSubscription().getEmail().getFrom()); - return retVal; - } + jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); + jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); + jpaStorageSettings.setIndexIdentifierOfType(appProperties.getEnable_index_of_type()); + return jpaStorageSettings; + } - @Primary - @Bean - public HibernatePropertiesProvider jpaStarterDialectProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { - return new JpaHibernatePropertiesProvider(myEntityManagerFactory); - } + @Lazy + @Bean + public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) { + DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl(); + if (appProperties.getMax_binary_size() != null) { + binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size()); + } - protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) { - jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); - jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); - jpaStorageSettings.setDefaultSearchParamsCanBeOverridden(appProperties.getAllow_override_default_search_params()); - if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) - jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); + return binaryStorageSvc; + } - jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); + @Bean + public IEmailSender emailSender(AppProperties appProperties) { + if (appProperties.getSubscription() != null + && appProperties.getSubscription().getEmail() != null) { - jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); - jpaStorageSettings.setIndexIdentifierOfType(appProperties.getEnable_index_of_type()); - return jpaStorageSettings; - } + return buildEmailSender(appProperties.getSubscription().getEmail()); + } - @Lazy - @Bean - public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) { - DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl(); - - if (appProperties.getMax_binary_size() != null) { - binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size()); - } - - return binaryStorageSvc; - } - - @Bean - public IEmailSender emailSender(AppProperties appProperties) { - if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) { - - return buildEmailSender(appProperties.getSubscription().getEmail()); - } - - // Return a dummy anonymous function instead of null. Spring does not like null beans. - // TODO Get the signature of ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory - // changed so it does not require an instance of an IEmailSender - return theDetails -> {}; - } + // Return a dummy anonymous function instead of null. Spring does not like null beans. + // TODO Get the signature of + // ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory + // changed so it does not require an instance of an IEmailSender + return theDetails -> {}; + } private static IEmailSender buildEmailSender(AppProperties.Subscription.Email email) { return new EmailSenderImpl(new MailSvc(new MailConfig() - .setSmtpHostname(email.getHost()) - .setSmtpPort(email.getPort()) - .setSmtpUsername(email.getUsername()) - .setSmtpPassword(email.getPassword()) - .setSmtpUseStartTLS(email.getStartTlsEnable()))); + .setSmtpHostname(email.getHost()) + .setSmtpPort(email.getPort()) + .setSmtpUsername(email.getUsername()) + .setSmtpPassword(email.getPassword()) + .setSmtpUseStartTLS(email.getStartTlsEnable()))); } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu2.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu2.java index 9416d28..0047fa4 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu2.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu2.java @@ -13,14 +13,11 @@ import org.springframework.context.annotation.Import; @Configuration @Conditional(OnDSTU2Condition.class) -@Import({ - JpaDstu2Config.class, - StarterJpaConfig.class -}) +@Import({JpaDstu2Config.class, StarterJpaConfig.class}) public class FhirServerConfigDstu2 { @Bean - public ITermLoaderSvc termLoaderService(ITermDeferredStorageSvc theDeferredStorageSvc, ITermCodeSystemStorageSvc theCodeSystemStorageSvc) { + public ITermLoaderSvc termLoaderService( + ITermDeferredStorageSvc theDeferredStorageSvc, ITermCodeSystemStorageSvc theCodeSystemStorageSvc) { return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc); } - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu3.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu3.java index 085764d..a029d11 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu3.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigDstu3.java @@ -9,10 +9,5 @@ import org.springframework.context.annotation.Import; @Configuration @Conditional(OnDSTU3Condition.class) -@Import({ - JpaDstu3Config.class, - StarterJpaConfig.class, - StarterCrDstu3Config.class, - ElasticsearchConfig.class}) -public class FhirServerConfigDstu3 { -} +@Import({JpaDstu3Config.class, StarterJpaConfig.class, StarterCrDstu3Config.class, ElasticsearchConfig.class}) +public class FhirServerConfigDstu3 {} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4.java index 61dbab5..55dce56 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4.java @@ -4,7 +4,6 @@ import ca.uhn.fhir.jpa.config.r4.JpaR4Config; import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition; import ca.uhn.fhir.jpa.starter.cr.StarterCrR4Config; import ca.uhn.fhir.jpa.starter.ips.StarterIpsConfig; - import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -18,5 +17,4 @@ import org.springframework.context.annotation.Import; ElasticsearchConfig.class, StarterIpsConfig.class }) -public class FhirServerConfigR4 { -} +public class FhirServerConfigR4 {} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4B.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4B.java index 4272017..ab267de 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4B.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR4B.java @@ -9,11 +9,5 @@ import org.springframework.context.annotation.Import; @Configuration @Conditional(OnR4BCondition.class) -@Import({ - JpaR4BConfig.class, - SubscriptionTopicConfig.class, - StarterJpaConfig.class, - ElasticsearchConfig.class -}) -public class FhirServerConfigR4B { -} +@Import({JpaR4BConfig.class, SubscriptionTopicConfig.class, StarterJpaConfig.class, ElasticsearchConfig.class}) +public class FhirServerConfigR4B {} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR5.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR5.java index 5e2e430..0aaa650 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR5.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigR5.java @@ -9,11 +9,5 @@ import org.springframework.context.annotation.Import; @Configuration @Conditional(OnR5Condition.class) -@Import({ - StarterJpaConfig.class, - JpaR5Config.class, - SubscriptionTopicConfig.class, - ElasticsearchConfig.class -}) -public class FhirServerConfigR5 { -} +@Import({StarterJpaConfig.class, JpaR5Config.class, SubscriptionTopicConfig.class, ElasticsearchConfig.class}) +public class FhirServerConfigR5 {} diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java index 56ea5b7..7e2b679 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java @@ -4,11 +4,10 @@ import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.to.FhirTesterMvcConfig; import ca.uhn.fhir.to.TesterConfig; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -//@formatter:off +// @formatter:off /** * This spring config file configures the web testing module. It serves two * purposes: @@ -19,7 +18,7 @@ import org.springframework.context.annotation.Import; */ @Configuration @Import(FhirTesterMvcConfig.class) -//@Conditional(FhirTesterConfigCondition.class) +// @Conditional(FhirTesterConfigCondition.class) public class FhirTesterConfig { /** @@ -36,22 +35,18 @@ public class FhirTesterConfig { * deploying your server to a place with a fully qualified domain name, * you might want to use that instead of using the variable. */ - @Bean - public TesterConfig testerConfig(AppProperties appProperties) { - TesterConfig retVal = new TesterConfig(); - appProperties.getTester().forEach((key, value) -> { - retVal - .addServer() - .withId(key) - .withFhirVersion(value.getFhir_version()) - .withBaseUrl(value.getServer_address()) - .withName(value.getName()); - retVal.setRefuseToFetchThirdPartyUrls( - value.getRefuse_to_fetch_third_party_urls()); - - }); - return retVal; - } - + @Bean + public TesterConfig testerConfig(AppProperties appProperties) { + TesterConfig retVal = new TesterConfig(); + appProperties.getTester().forEach((key, value) -> { + retVal.addServer() + .withId(key) + .withFhirVersion(value.getFhir_version()) + .withBaseUrl(value.getServer_address()) + .withName(value.getName()); + retVal.setRefuseToFetchThirdPartyUrls(value.getRefuse_to_fetch_third_party_urls()); + }); + return retVal; + } } -//@formatter:on +// @formatter:on diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java index f5670d9..e385b1c 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java @@ -9,8 +9,9 @@ import org.springframework.core.type.AnnotatedTypeMetadata; public class FhirTesterConfigCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - - var properties = EnvironmentHelper.getPropertiesStartingWith((ConfigurableEnvironment) conditionContext.getEnvironment(), "hapi.fhir.tester"); + + var properties = EnvironmentHelper.getPropertiesStartingWith( + (ConfigurableEnvironment) conditionContext.getEnvironment(), "hapi.fhir.tester"); return !properties.isEmpty(); } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java index c71a666..cc8eb18 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java @@ -1,6 +1,7 @@ package ca.uhn.fhir.jpa.starter.common; import ca.uhn.fhir.batch2.coordinator.JobDefinitionRegistry; +import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider; import ca.uhn.fhir.batch2.jobs.imprt.BulkDataImportProvider; import ca.uhn.fhir.batch2.jobs.reindex.ReindexJobParameters; import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider; @@ -9,7 +10,6 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.support.IValidationSupport; - import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.jpa.api.IDaoRegistry; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; @@ -18,7 +18,6 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor; import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider; -import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider; import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil; import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil; import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil; @@ -34,8 +33,8 @@ import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; 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.*; import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; +import ca.uhn.fhir.jpa.provider.*; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl; @@ -43,8 +42,8 @@ import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.jpa.starter.annotations.OnCorsPresent; import ca.uhn.fhir.jpa.starter.annotations.OnImplementationGuidesPresent; import ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory; -import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper; import ca.uhn.fhir.jpa.starter.ig.IImplementationGuideOperationProvider; +import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper; import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain; @@ -53,9 +52,9 @@ import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative2.NullNarrativeGenerator; import ca.uhn.fhir.rest.api.IResourceSupportedSvc; import ca.uhn.fhir.rest.openapi.OpenApiInterceptor; +import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor; 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.ResourceProviderFactory; import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; @@ -75,18 +74,16 @@ import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.web.cors.CorsConfiguration; +import java.util.*; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; -import java.util.*; import static ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory.ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR; @Configuration -//allow users to configure custom packages to scan for additional beans -@ComponentScan(basePackages = { "${hapi.fhir.custom-bean-packages:}" }) -@Import( - ThreadPoolFactoryConfig.class -) +// allow users to configure custom packages to scan for additional beans +@ComponentScan(basePackages = {"${hapi.fhir.custom-bean-packages:}"}) +@Import(ThreadPoolFactoryConfig.class) public class StarterJpaConfig { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StarterJpaConfig.class); @@ -107,12 +104,9 @@ public class StarterJpaConfig { return ValidationSupportConfigUtil.newCachingValidationSupport(theJpaValidationSupportChain); } - @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. @@ -125,7 +119,6 @@ public class StarterJpaConfig { return pagingProvider; } - @Bean public IResourceSupportedSvc resourceSupportedSvc(IDaoRegistry theDaoRegistry) { return new DaoRegistryResourceSupportedSvc(theDaoRegistry); @@ -138,8 +131,12 @@ public class StarterJpaConfig { @Primary @Bean - public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource myDataSource, ConfigurableListableBeanFactory myConfigurableListableBeanFactory, FhirContext theFhirContext) { - LocalContainerEntityManagerFactoryBean retVal = HapiEntityManagerFactoryUtil.newEntityManagerFactory(myConfigurableListableBeanFactory, theFhirContext); + public LocalContainerEntityManagerFactoryBean entityManagerFactory( + DataSource myDataSource, + ConfigurableListableBeanFactory myConfigurableListableBeanFactory, + FhirContext theFhirContext) { + LocalContainerEntityManagerFactoryBean retVal = + HapiEntityManagerFactoryUtil.newEntityManagerFactory(myConfigurableListableBeanFactory, theFhirContext); retVal.setPersistenceUnitName("HAPI_PU"); try { @@ -147,7 +144,8 @@ public class StarterJpaConfig { } catch (Exception e) { throw new ConfigurationException("Could not set the data source due to a configuration issue", e); } - retVal.setJpaProperties(EnvironmentHelper.getHibernateProperties(configurableEnvironment, myConfigurableListableBeanFactory)); + retVal.setJpaProperties( + EnvironmentHelper.getHibernateProperties(configurableEnvironment, myConfigurableListableBeanFactory)); return retVal; } @@ -164,10 +162,10 @@ public class StarterJpaConfig { return new HSearchSortHelperImpl(mySearchParamRegistry); } - @Bean @ConditionalOnProperty(prefix = "hapi.fhir", name = ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR, havingValue = "true") - public RepositoryValidatingInterceptor repositoryValidatingInterceptor(IRepositoryValidationInterceptorFactory factory) { + public RepositoryValidatingInterceptor repositoryValidatingInterceptor( + IRepositoryValidationInterceptorFactory factory) { return factory.buildUsingStoredStructureDefinitions(); } @@ -189,8 +187,11 @@ public class StarterJpaConfig { @Bean("packageInstaller") @Primary @Conditional(OnImplementationGuidesPresent.class) - public IPackageInstallerSvc packageInstaller(AppProperties appProperties, JobDefinition reindexJobParametersJobDefinition, JobDefinitionRegistry jobDefinitionRegistry, IPackageInstallerSvc packageInstallerSvc) - { + public IPackageInstallerSvc packageInstaller( + AppProperties appProperties, + JobDefinition reindexJobParametersJobDefinition, + JobDefinitionRegistry jobDefinitionRegistry, + IPackageInstallerSvc packageInstallerSvc) { jobDefinitionRegistry.addJobDefinitionIfNotRegistered(reindexJobParametersJobDefinition); if (appProperties.getImplementationGuides() != null) { @@ -199,10 +200,11 @@ public class StarterJpaConfig { PackageInstallationSpec packageInstallationSpec = guidesEntry.getValue(); if (appProperties.getInstall_transitive_ig_dependencies()) { - packageInstallationSpec.addDependencyExclude("hl7.fhir.r2.core") - .addDependencyExclude("hl7.fhir.r3.core") - .addDependencyExclude("hl7.fhir.r4.core") - .addDependencyExclude("hl7.fhir.r5.core"); + packageInstallationSpec + .addDependencyExclude("hl7.fhir.r2.core") + .addDependencyExclude("hl7.fhir.r3.core") + .addDependencyExclude("hl7.fhir.r4.core") + .addDependencyExclude("hl7.fhir.r5.core"); } packageInstallerSvc.install(packageInstallationSpec); } @@ -238,11 +240,40 @@ public class StarterJpaConfig { // Create the interceptor and register it return new CorsInterceptor(config); - } @Bean - public RestfulServer restfulServer(IFhirSystemDao fhirSystemDao, AppProperties appProperties, DaoRegistry daoRegistry, Optional mdmProviderProvider, IJpaSystemProvider jpaSystemProvider, ResourceProviderFactory resourceProviderFactory, JpaStorageSettings jpaStorageSettings, ISearchParamRegistry searchParamRegistry, IValidationSupport theValidationSupport, DatabaseBackedPagingProvider databaseBackedPagingProvider, LoggingInterceptor loggingInterceptor, Optional terminologyUploaderProvider, Optional subscriptionTriggeringProvider, Optional corsInterceptor, IInterceptorBroadcaster interceptorBroadcaster, Optional binaryAccessProvider, BinaryStorageInterceptor binaryStorageInterceptor, IValidatorModule validatorModule, Optional graphQLProvider, BulkDataExportProvider bulkDataExportProvider, BulkDataImportProvider bulkDataImportProvider, ValueSetOperationProvider theValueSetOperationProvider, ReindexProvider reindexProvider, PartitionManagementProvider partitionManagementProvider, Optional repositoryValidatingInterceptor, IPackageInstallerSvc packageInstallerSvc, ThreadSafeResourceDeleterSvc theThreadSafeResourceDeleterSvc, ApplicationContext appContext, Optional theIpsOperationProvider, Optional implementationGuideOperationProvider) { + public RestfulServer restfulServer( + IFhirSystemDao fhirSystemDao, + AppProperties appProperties, + DaoRegistry daoRegistry, + Optional mdmProviderProvider, + IJpaSystemProvider jpaSystemProvider, + ResourceProviderFactory resourceProviderFactory, + JpaStorageSettings jpaStorageSettings, + ISearchParamRegistry searchParamRegistry, + IValidationSupport theValidationSupport, + DatabaseBackedPagingProvider databaseBackedPagingProvider, + LoggingInterceptor loggingInterceptor, + Optional terminologyUploaderProvider, + Optional subscriptionTriggeringProvider, + Optional corsInterceptor, + IInterceptorBroadcaster interceptorBroadcaster, + Optional binaryAccessProvider, + BinaryStorageInterceptor binaryStorageInterceptor, + IValidatorModule validatorModule, + Optional graphQLProvider, + BulkDataExportProvider bulkDataExportProvider, + BulkDataImportProvider bulkDataImportProvider, + ValueSetOperationProvider theValueSetOperationProvider, + ReindexProvider reindexProvider, + PartitionManagementProvider partitionManagementProvider, + Optional repositoryValidatingInterceptor, + IPackageInstallerSvc packageInstallerSvc, + ThreadSafeResourceDeleterSvc theThreadSafeResourceDeleterSvc, + ApplicationContext appContext, + Optional theIpsOperationProvider, + Optional implementationGuideOperationProvider) { RestfulServer fhirServer = new RestfulServer(fhirSystemDao.getContext()); List supportedResourceTypes = appProperties.getSupported_resource_types(); @@ -264,7 +295,8 @@ public class StarterJpaConfig { fhirServer.registerProviders(resourceProviderFactory.createProviders()); fhirServer.registerProvider(jpaSystemProvider); - fhirServer.setServerConformanceProvider(calculateConformanceProvider(fhirSystemDao, fhirServer, jpaStorageSettings, searchParamRegistry, theValidationSupport)); + fhirServer.setServerConformanceProvider(calculateConformanceProvider( + fhirSystemDao, fhirServer, jpaStorageSettings, searchParamRegistry, theValidationSupport)); /* * ETag Support @@ -272,7 +304,6 @@ public class StarterJpaConfig { if (!appProperties.getEtag_support_enabled()) fhirServer.setETagSupport(ETagSupportEnum.DISABLED); - /* * Default to JSON and pretty printing */ @@ -318,7 +349,8 @@ public class StarterJpaConfig { fhirServer.setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress)); } else if (appProperties.getUse_apache_address_strategy()) { boolean useHttps = appProperties.getUse_apache_address_strategy_https(); - fhirServer.setServerAddressStrategy(useHttps ? ApacheProxyAddressStrategy.forHttps() : ApacheProxyAddressStrategy.forHttp()); + fhirServer.setServerAddressStrategy( + useHttps ? ApacheProxyAddressStrategy.forHttps() : ApacheProxyAddressStrategy.forHttp()); } else { fhirServer.setServerAddressStrategy(new IncomingRequestAddressStrategy()); } @@ -330,7 +362,11 @@ public class StarterJpaConfig { * so it is a potential security vulnerability. Consider using an AuthorizationInterceptor * with this feature. */ - if (fhirSystemDao.getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { // <-- ENABLED RIGHT NOW + if (fhirSystemDao + .getContext() + .getVersion() + .getVersion() + .isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { // <-- ENABLED RIGHT NOW fhirServer.registerProvider(terminologyUploaderProvider.get()); } @@ -348,7 +384,8 @@ public class StarterJpaConfig { } if (appProperties.getAllow_cascading_deletes()) { - CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor(fhirSystemDao.getContext(), daoRegistry, interceptorBroadcaster, theThreadSafeResourceDeleterSvc); + CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor( + fhirSystemDao.getContext(), daoRegistry, interceptorBroadcaster, theThreadSafeResourceDeleterSvc); fhirServer.registerInterceptor(cascadingDeleteInterceptor); } @@ -391,16 +428,15 @@ public class StarterJpaConfig { fhirServer.registerProvider(bulkDataExportProvider); } - //Bulk Import + // Bulk Import if (appProperties.getBulk_import_enabled()) { fhirServer.registerProvider(bulkDataImportProvider); } - // valueSet Operations i.e $expand fhirServer.registerProvider(theValueSetOperationProvider); - //reindex Provider $reindex + // reindex Provider $reindex fhirServer.registerProvider(reindexProvider); // Partitioning @@ -414,8 +450,7 @@ public class StarterJpaConfig { // register custom interceptors registerCustomInterceptors(fhirServer, appContext, appProperties.getCustomInterceptorClasses()); - - //register the IPS Provider + // register the IPS Provider if (!theIpsOperationProvider.isEmpty()) { fhirServer.registerProvider(theIpsOperationProvider.get()); } @@ -426,8 +461,9 @@ public class StarterJpaConfig { /** * check the properties for custom interceptor classes and registers them. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - private void registerCustomInterceptors(RestfulServer fhirServer, ApplicationContext theAppContext, List customInterceptorClasses) { + @SuppressWarnings({"unchecked", "rawtypes"}) + private void registerCustomInterceptors( + RestfulServer fhirServer, ApplicationContext theAppContext, List customInterceptorClasses) { if (customInterceptorClasses == null) { return; @@ -461,30 +497,40 @@ public class StarterJpaConfig { } } - public static IServerConformanceProvider calculateConformanceProvider(IFhirSystemDao fhirSystemDao, RestfulServer fhirServer, JpaStorageSettings jpaStorageSettings, ISearchParamRegistry searchParamRegistry, IValidationSupport theValidationSupport) { + public static IServerConformanceProvider calculateConformanceProvider( + IFhirSystemDao fhirSystemDao, + RestfulServer fhirServer, + JpaStorageSettings jpaStorageSettings, + ISearchParamRegistry searchParamRegistry, + IValidationSupport theValidationSupport) { FhirVersionEnum fhirVersion = fhirSystemDao.getContext().getVersion().getVersion(); if (fhirVersion == FhirVersionEnum.DSTU2) { - JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(fhirServer, fhirSystemDao, jpaStorageSettings); + JpaConformanceProviderDstu2 confProvider = + new JpaConformanceProviderDstu2(fhirServer, fhirSystemDao, jpaStorageSettings); confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server"); return confProvider; } else if (fhirVersion == FhirVersionEnum.DSTU3) { - JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry); + JpaConformanceProviderDstu3 confProvider = + new JpaConformanceProviderDstu3(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry); confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server"); return confProvider; } else if (fhirVersion == FhirVersionEnum.R4) { - JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport); + JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider( + fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport); confProvider.setImplementationDescription("HAPI FHIR R4 Server"); return confProvider; } else if (fhirVersion == FhirVersionEnum.R4B) { - JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport); + JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider( + fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport); confProvider.setImplementationDescription("HAPI FHIR R4B Server"); return confProvider; } else if (fhirVersion == FhirVersionEnum.R5) { - JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport); + JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider( + fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport); confProvider.setImplementationDescription("HAPI FHIR R5 Server"); return confProvider; } else { diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/IRepositoryValidationInterceptorFactory.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/IRepositoryValidationInterceptorFactory.java index 67a40c7..640a5c5 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/IRepositoryValidationInterceptorFactory.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/IRepositoryValidationInterceptorFactory.java @@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor; public interface IRepositoryValidationInterceptorFactory { String ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR = "enable_repository_validating_interceptor"; + RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions(); RepositoryValidatingInterceptor build(); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java index edaade7..f276b86 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java @@ -37,24 +37,28 @@ public class RepositoryValidationInterceptorFactoryDstu3 implements IRepositoryV private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final IFhirResourceDao structureDefinitionResourceProvider; - public RepositoryValidationInterceptorFactoryDstu3(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + public RepositoryValidationInterceptorFactoryDstu3( + RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.fhirContext = daoRegistry.getSystemDao().getContext(); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); - } public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { - IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefinitions = results.getResources(0, results.size()) - .stream() - .map(StructureDefinition.class::cast) - .collect(Collectors.groupingBy(StructureDefinition::getType)); + IBundleProvider results = structureDefinitionResourceProvider.search( + new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefinitions = results.getResources(0, results.size()).stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); structureDefinitions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); - repositoryValidatingRuleBuilder.forResourcesOfType(key).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType(key) + .requireAtLeastOneProfileOf(urls) + .and() + .requireValidationToDeclaredProfiles(); }); List rules = repositoryValidatingRuleBuilder.build(); @@ -65,11 +69,14 @@ public class RepositoryValidationInterceptorFactoryDstu3 implements IRepositoryV // Customize the ruleBuilder here to have the rules you want! We will give a simple example // of enabling validation for all Patient resources - repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType("Patient") + .requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient") + .and() + .requireValidationToDeclaredProfiles(); // Do not customize below this line List rules = repositoryValidatingRuleBuilder.build(); return new RepositoryValidatingInterceptor(fhirContext, rules); } - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java index c4fca01..b7df8b9 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java @@ -37,25 +37,29 @@ public class RepositoryValidationInterceptorFactoryR4 implements IRepositoryVali private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final IFhirResourceDao structureDefinitionResourceProvider; - public RepositoryValidationInterceptorFactoryR4(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + public RepositoryValidationInterceptorFactoryR4( + RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.fhirContext = daoRegistry.getSystemDao().getContext(); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); - } @Override public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { - IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()) - .stream() - .map(StructureDefinition.class::cast) - .collect(Collectors.groupingBy(StructureDefinition::getType)); + IBundleProvider results = structureDefinitionResourceProvider.search( + new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefintions = results.getResources(0, results.size()).stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); structureDefintions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); - repositoryValidatingRuleBuilder.forResourcesOfType(key).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType(key) + .requireAtLeastOneProfileOf(urls) + .and() + .requireValidationToDeclaredProfiles(); }); List rules = repositoryValidatingRuleBuilder.build(); @@ -67,11 +71,14 @@ public class RepositoryValidationInterceptorFactoryR4 implements IRepositoryVali // Customize the ruleBuilder here to have the rules you want! We will give a simple example // of enabling validation for all Patient resources - repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType("Patient") + .requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient") + .and() + .requireValidationToDeclaredProfiles(); // Do not customize below this line List rules = repositoryValidatingRuleBuilder.build(); return new RepositoryValidatingInterceptor(fhirContext, rules); } - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java index 277af2f..6f6847e 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java @@ -37,25 +37,29 @@ public class RepositoryValidationInterceptorFactoryR4B implements IRepositoryVal private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final IFhirResourceDao structureDefinitionResourceProvider; - public RepositoryValidationInterceptorFactoryR4B(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + public RepositoryValidationInterceptorFactoryR4B( + RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.fhirContext = daoRegistry.getSystemDao().getContext(); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); - } @Override public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { - IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()) - .stream() - .map(StructureDefinition.class::cast) - .collect(Collectors.groupingBy(StructureDefinition::getType)); + IBundleProvider results = structureDefinitionResourceProvider.search( + new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefintions = results.getResources(0, results.size()).stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); structureDefintions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); - repositoryValidatingRuleBuilder.forResourcesOfType(key).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType(key) + .requireAtLeastOneProfileOf(urls) + .and() + .requireValidationToDeclaredProfiles(); }); List rules = repositoryValidatingRuleBuilder.build(); @@ -67,11 +71,14 @@ public class RepositoryValidationInterceptorFactoryR4B implements IRepositoryVal // Customize the ruleBuilder here to have the rules you want! We will give a simple example // of enabling validation for all Patient resources - repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType("Patient") + .requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient") + .and() + .requireValidationToDeclaredProfiles(); // Do not customize below this line List rules = repositoryValidatingRuleBuilder.build(); return new RepositoryValidatingInterceptor(fhirContext, rules); } - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java index 594800d..7f3b38b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java @@ -37,24 +37,28 @@ public class RepositoryValidationInterceptorFactoryR5 implements IRepositoryVali private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final IFhirResourceDao structureDefinitionResourceProvider; - public RepositoryValidationInterceptorFactoryR5(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { + public RepositoryValidationInterceptorFactoryR5( + RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.fhirContext = daoRegistry.getSystemDao().getContext(); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); - } public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { - IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()) - .stream() - .map(StructureDefinition.class::cast) - .collect(Collectors.groupingBy(StructureDefinition::getType)); + IBundleProvider results = structureDefinitionResourceProvider.search( + new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); + Map> structureDefintions = results.getResources(0, results.size()).stream() + .map(StructureDefinition.class::cast) + .collect(Collectors.groupingBy(StructureDefinition::getType)); structureDefintions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); - repositoryValidatingRuleBuilder.forResourcesOfType(key).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType(key) + .requireAtLeastOneProfileOf(urls) + .and() + .requireValidationToDeclaredProfiles(); }); List rules = repositoryValidatingRuleBuilder.build(); @@ -65,11 +69,14 @@ public class RepositoryValidationInterceptorFactoryR5 implements IRepositoryVali // Customize the ruleBuilder here to have the rules you want! We will give a simple example // of enabling validation for all Patient resources - repositoryValidatingRuleBuilder.forResourcesOfType("Patient").requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient").and().requireValidationToDeclaredProfiles(); + repositoryValidatingRuleBuilder + .forResourcesOfType("Patient") + .requireAtLeastProfile("http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient") + .and() + .requireValidationToDeclaredProfiles(); // Do not customize below this line List rules = repositoryValidatingRuleBuilder.build(); return new RepositoryValidatingInterceptor(fhirContext, rules); } - } 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 c9ac4b9..edbe2f7 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 @@ -10,5 +10,5 @@ public class CrConfigCondition implements Condition { 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 index c0a2fd2..967dea9 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java @@ -8,7 +8,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "hapi.fhir.cr") public class CrProperties { private Boolean enabled; - //cql settings + // cql settings private Boolean cql_use_embedded_libraries = true; private Boolean cql_runtime_debug_logging_enabled = false; private Boolean cql_runtime_enable_validation = false; @@ -37,7 +37,7 @@ public class CrProperties { // Care-gaps Settings private String caregaps_reporter = "default"; private String caregaps_section_author = "default"; - + public Boolean getEnabled() { return enabled; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java index a42c160..a82c876 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java @@ -1,14 +1,13 @@ package ca.uhn.fhir.jpa.starter.cr; -import java.util.function.Supplier; - import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.provider.IResourceProviderFactoryObserver; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; +import java.util.function.Supplier; + public class PostInitProviderRegisterer { - public PostInitProviderRegisterer(RestfulServer restfulServer, - ResourceProviderFactory resourceProviderFactory) { + public PostInitProviderRegisterer(RestfulServer restfulServer, ResourceProviderFactory resourceProviderFactory) { resourceProviderFactory.attach(new Observer(restfulServer)); } @@ -30,7 +29,6 @@ public class PostInitProviderRegisterer { } this.restfulServer.registerProvider(provider); - } public void remove(Supplier theSupplier) { @@ -45,7 +43,5 @@ public class PostInitProviderRegisterer { this.restfulServer.unregisterProvider(provider); } - } - } 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 2ad1e15..c0743d6 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 @@ -35,9 +35,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Configuration -@Conditional({ OnDSTU3Condition.class, CrConfigCondition.class }) +@Conditional({OnDSTU3Condition.class, CrConfigCondition.class}) @Import({ - //BaseCrConfig.class, + // BaseCrConfig.class, CrDstu3Config.class, ApplyOperationConfig.class, ExtractOperationConfig.class, @@ -48,11 +48,12 @@ public class StarterCrDstu3Config { private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrDstu3Config.class); @Bean - MeasureEvaluationOptions measureEvaluationOptions(EvaluationSettings theEvaluationSettings, Map theValidationProfiles){ + MeasureEvaluationOptions measureEvaluationOptions( + EvaluationSettings theEvaluationSettings, Map theValidationProfiles) { MeasureEvaluationOptions measureEvalOptions = new MeasureEvaluationOptions(); measureEvalOptions.setEvaluationSettings(theEvaluationSettings); - if(measureEvalOptions.isValidationEnabled()) { + if (measureEvalOptions.isValidationEnabled()) { measureEvalOptions.setValidationProfiles(theValidationProfiles); } return measureEvalOptions; @@ -60,10 +61,10 @@ public class StarterCrDstu3Config { @Bean public EvaluationSettings evaluationSettings( - CrProperties theCrProperties, - Map theGlobalLibraryCache, - Map theGlobalModelCache, - Map> theGlobalValueSetCache) { + CrProperties theCrProperties, + Map theGlobalLibraryCache, + Map theGlobalModelCache, + Map> theGlobalValueSetCache) { var evaluationSettings = EvaluationSettings.getDefault(); var cqlOptions = evaluationSettings.getCqlOptions(); @@ -135,9 +136,10 @@ public class StarterCrDstu3Config { } @Bean - public PostInitProviderRegisterer postInitProviderRegisterer(RestfulServer theRestfulServer, - ResourceProviderFactory theResourceProviderFactory) { - return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory);} + public PostInitProviderRegisterer postInitProviderRegisterer( + RestfulServer theRestfulServer, ResourceProviderFactory theResourceProviderFactory) { + return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory); + } @Bean public CrProperties crProperties() { @@ -161,26 +163,27 @@ public class StarterCrDstu3Config { @Bean public ElmCacheResourceChangeListener elmCacheResourceChangeListener( - IResourceChangeListenerRegistry theResourceChangeListenerRegistry, - DaoRegistry theDaoRegistry, - EvaluationSettings theEvaluationSettings) { + IResourceChangeListenerRegistry theResourceChangeListenerRegistry, + DaoRegistry theDaoRegistry, + EvaluationSettings theEvaluationSettings) { ElmCacheResourceChangeListener listener = - new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache()); + new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache()); theResourceChangeListenerRegistry.registerResourceResourceChangeListener( - "Library", SearchParameterMap.newSynchronous(), listener, 1000); + "Library", SearchParameterMap.newSynchronous(), listener, 1000); return listener; } @Bean public CodeCacheResourceChangeListener codeCacheResourceChangeListener( - IResourceChangeListenerRegistry theResourceChangeListenerRegistry, - EvaluationSettings theEvaluationSettings, - DaoRegistry theDaoRegistry) { + IResourceChangeListenerRegistry theResourceChangeListenerRegistry, + EvaluationSettings theEvaluationSettings, + DaoRegistry theDaoRegistry) { - CodeCacheResourceChangeListener listener = new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache()); - //registry + CodeCacheResourceChangeListener listener = + new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache()); + // registry theResourceChangeListenerRegistry.registerResourceResourceChangeListener( - "ValueSet", SearchParameterMap.newSynchronous(), listener,1000); + "ValueSet", SearchParameterMap.newSynchronous(), listener, 1000); return listener; } 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 c42f44a..fd9af65 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,6 +1,7 @@ package ca.uhn.fhir.jpa.starter.cr; import ca.uhn.fhir.cr.common.CodeCacheResourceChangeListener; +import ca.uhn.fhir.cr.common.CqlThreadFactory; import ca.uhn.fhir.cr.common.ElmCacheResourceChangeListener; import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig; import ca.uhn.fhir.cr.config.r4.CrR4Config; @@ -14,8 +15,6 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 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 org.cqframework.cql.cql2elm.CqlCompilerOptions; import org.cqframework.cql.cql2elm.model.CompiledLibrary; import org.cqframework.cql.cql2elm.model.Model; @@ -45,7 +44,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @Configuration -@Conditional({ OnR4Condition.class, CrConfigCondition.class }) +@Conditional({OnR4Condition.class, CrConfigCondition.class}) @Import({ CrR4Config.class, ApplyOperationConfig.class, @@ -60,16 +59,14 @@ public class StarterCrR4Config { @Bean public ExecutorService cqlExecutor() { CqlThreadFactory factory = new CqlThreadFactory(); - ExecutorService executor = Executors. - newFixedThreadPool(2 - , factory); + ExecutorService executor = Executors.newFixedThreadPool(2, factory); executor = new DelegatingSecurityContextExecutorService(executor); return executor; } @Bean - CareGapsProperties careGapsProperties(CrProperties theCrProperties) { + CareGapsProperties careGapsProperties(CrProperties theCrProperties) { var careGapsProperties = new CareGapsProperties(); careGapsProperties.setThreadedCareGapsEnabled(false); careGapsProperties.setCareGapsReporter(theCrProperties.getCareGapsReporter()); @@ -78,10 +75,11 @@ public class StarterCrR4Config { } @Bean - MeasureEvaluationOptions measureEvaluationOptions(EvaluationSettings theEvaluationSettings, Map theValidationProfiles){ + MeasureEvaluationOptions measureEvaluationOptions( + EvaluationSettings theEvaluationSettings, Map theValidationProfiles) { MeasureEvaluationOptions measureEvalOptions = new MeasureEvaluationOptions(); measureEvalOptions.setEvaluationSettings(theEvaluationSettings); - if(measureEvalOptions.isValidationEnabled()) { + if (measureEvalOptions.isValidationEnabled()) { measureEvalOptions.setValidationProfiles(theValidationProfiles); } return measureEvalOptions; @@ -89,10 +87,10 @@ public class StarterCrR4Config { @Bean public EvaluationSettings evaluationSettings( - CrProperties theCrProperties, - Map theGlobalLibraryCache, - Map theGlobalModelCache, - Map> theGlobalValueSetCache) { + CrProperties theCrProperties, + Map theGlobalLibraryCache, + Map theGlobalModelCache, + Map> theGlobalValueSetCache) { var evaluationSettings = EvaluationSettings.getDefault(); var cqlOptions = evaluationSettings.getCqlOptions(); @@ -164,8 +162,8 @@ public class StarterCrR4Config { } @Bean - public PostInitProviderRegisterer postInitProviderRegisterer(RestfulServer theRestfulServer, - ResourceProviderFactory theResourceProviderFactory) { + public PostInitProviderRegisterer postInitProviderRegisterer( + RestfulServer theRestfulServer, ResourceProviderFactory theResourceProviderFactory) { return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory); } @@ -191,26 +189,27 @@ public class StarterCrR4Config { @Bean public ElmCacheResourceChangeListener elmCacheResourceChangeListener( - IResourceChangeListenerRegistry theResourceChangeListenerRegistry, - DaoRegistry theDaoRegistry, - EvaluationSettings theEvaluationSettings) { + IResourceChangeListenerRegistry theResourceChangeListenerRegistry, + DaoRegistry theDaoRegistry, + EvaluationSettings theEvaluationSettings) { ElmCacheResourceChangeListener listener = - new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache()); + new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache()); theResourceChangeListenerRegistry.registerResourceResourceChangeListener( - "Library", SearchParameterMap.newSynchronous(), listener, 1000); + "Library", SearchParameterMap.newSynchronous(), listener, 1000); return listener; } @Bean public CodeCacheResourceChangeListener codeCacheResourceChangeListener( - IResourceChangeListenerRegistry theResourceChangeListenerRegistry, - EvaluationSettings theEvaluationSettings, - DaoRegistry theDaoRegistry) { + IResourceChangeListenerRegistry theResourceChangeListenerRegistry, + EvaluationSettings theEvaluationSettings, + DaoRegistry theDaoRegistry) { - CodeCacheResourceChangeListener listener = new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache()); - //registry + CodeCacheResourceChangeListener listener = + new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache()); + // registry theResourceChangeListenerRegistry.registerResourceResourceChangeListener( - "ValueSet", SearchParameterMap.newSynchronous(), listener,1000); + "ValueSet", SearchParameterMap.newSynchronous(), listener, 1000); return listener; } @@ -219,5 +218,4 @@ public class StarterCrR4Config { public ResourceChangeListenerRegistryInterceptor resourceChangeListenerRegistryInterceptor() { return new ResourceChangeListenerRegistryInterceptor(); } - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ig/IImplementationGuideOperationProvider.java b/src/main/java/ca/uhn/fhir/jpa/starter/ig/IImplementationGuideOperationProvider.java index 617f762..b35b1f6 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ig/IImplementationGuideOperationProvider.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ig/IImplementationGuideOperationProvider.java @@ -9,10 +9,16 @@ import java.io.IOException; public interface IImplementationGuideOperationProvider { static PackageInstallationSpec toPackageInstallationSpec(byte[] npmPackageAsByteArray) throws IOException { NpmPackage npmPackage = NpmPackage.fromPackage(new ByteArrayInputStream(npmPackageAsByteArray)); - return new PackageInstallationSpec().setName(npmPackage.name()).setPackageContents(npmPackageAsByteArray).setVersion(npmPackage.version()).setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL).setFetchDependencies(false); + return new PackageInstallationSpec() + .setName(npmPackage.name()) + .setPackageContents(npmPackageAsByteArray) + .setVersion(npmPackage.version()) + .setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL) + .setFetchDependencies(false); } - //The following declaration is the one that counts but cannot be used across different versions as stating Base64BinaryType would bind to a separate version - //@Operation(name = "$install", typeName = "ImplementationGuide") - //Parameters install(@OperationParam(name = "npmContent",min = 1, max = 1) Base64BinaryType implementationGuide); + // The following declaration is the one that counts but cannot be used across different versions as stating + // Base64BinaryType would bind to a separate version + // @Operation(name = "$install", typeName = "ImplementationGuide") + // Parameters install(@OperationParam(name = "npmContent",min = 1, max = 1) Base64BinaryType implementationGuide); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR4OperationProvider.java b/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR4OperationProvider.java index 75dc4de..145924d 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR4OperationProvider.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR4OperationProvider.java @@ -22,14 +22,15 @@ public class ImplementationGuideR4OperationProvider implements IImplementationGu } @Operation(name = "$install", typeName = "ImplementationGuide") - public Parameters install(@OperationParam(name = "npmContent", min = 1, max = 1) Base64BinaryType implementationGuide) { + public Parameters install( + @OperationParam(name = "npmContent", min = 1, max = 1) Base64BinaryType implementationGuide) { try { - packageInstallerSvc.install(IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue())); + packageInstallerSvc.install( + IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue())); } catch (IOException e) { throw new RuntimeException(e); } return new Parameters(); } - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR5OperationProvider.java b/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR5OperationProvider.java index 233789d..794bf72 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR5OperationProvider.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ig/ImplementationGuideR5OperationProvider.java @@ -22,15 +22,15 @@ public class ImplementationGuideR5OperationProvider { } @Operation(name = "$install", typeName = "ImplementationGuide") - public Parameters install(@OperationParam(name = "npmContent", min = 1, max = 1) Base64BinaryType implementationGuide) { + public Parameters install( + @OperationParam(name = "npmContent", min = 1, max = 1) Base64BinaryType implementationGuide) { try { - packageInstallerSvc.install(IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue())); + packageInstallerSvc.install( + IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue())); } catch (IOException e) { throw new RuntimeException(e); } return new Parameters(); } - - } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ips/IpsConfigCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/ips/IpsConfigCondition.java index 973491a..ca26e48 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ips/IpsConfigCondition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ips/IpsConfigCondition.java @@ -7,8 +7,8 @@ import org.springframework.core.type.AnnotatedTypeMetadata; public class IpsConfigCondition implements Condition { @Override - public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { - String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.ips_enabled"); - return Boolean.parseBoolean(property); - } + public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { + String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.ips_enabled"); + return Boolean.parseBoolean(property); + } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java index 308a3aa..0b1db60 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java @@ -1,34 +1,30 @@ package ca.uhn.fhir.jpa.starter.ips; -import org.springframework.context.annotation.Bean; - import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy; -import ca.uhn.fhir.jpa.ips.strategy.DefaultIpsGenerationStrategy; import ca.uhn.fhir.jpa.ips.generator.IIpsGeneratorSvc; -import org.springframework.context.annotation.Conditional; -import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; import ca.uhn.fhir.jpa.ips.generator.IpsGeneratorSvcImpl; - +import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; +import ca.uhn.fhir.jpa.ips.strategy.DefaultIpsGenerationStrategy; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; @Conditional(IpsConfigCondition.class) public class StarterIpsConfig { - @Bean - IIpsGenerationStrategy ipsGenerationStrategy() - { + @Bean + IIpsGenerationStrategy ipsGenerationStrategy() { return new DefaultIpsGenerationStrategy(); } @Bean - public IpsOperationProvider ipsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc){ + public IpsOperationProvider ipsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc) { return new IpsOperationProvider(theIpsGeneratorSvc); } @Bean - public IIpsGeneratorSvc ipsGeneratorSvcImpl(FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy, DaoRegistry theDaoRegistry) - { + public IIpsGeneratorSvc ipsGeneratorSvcImpl( + FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy, DaoRegistry theDaoRegistry) { return new IpsGeneratorSvcImpl(theFhirContext, theGenerationStrategy, theDaoRegistry); } - } 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 7f0ee4c..33bb749 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 @@ -24,10 +24,13 @@ import java.nio.charset.StandardCharsets; public class MdmConfig { @Bean - IMdmSettings mdmSettings(@Autowired MdmRuleValidator theMdmRuleValidator, AppProperties appProperties) throws IOException { + IMdmSettings mdmSettings(@Autowired MdmRuleValidator theMdmRuleValidator, AppProperties appProperties) + throws IOException { DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource("mdm-rules.json"); String json = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8); - return new MdmSettings(theMdmRuleValidator).setEnabled(appProperties.getMdm_enabled()).setScriptText(json); + return new MdmSettings(theMdmRuleValidator) + .setEnabled(appProperties.getMdm_enabled()) + .setScriptText(json); } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfigCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfigCondition.java index a5c7de0..7c3bf5b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfigCondition.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfigCondition.java @@ -5,9 +5,9 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; public class MdmConfigCondition implements Condition { - @Override - public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { - String property = conditionContext.getEnvironment().getProperty("hapi.fhir.mdm_enabled"); - return Boolean.parseBoolean(property); - } + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { + String property = conditionContext.getEnvironment().getProperty("hapi.fhir.mdm_enabled"); + return Boolean.parseBoolean(property); + } } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java b/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java index 71d947a..e62b089 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java @@ -31,8 +31,8 @@ import static java.util.Objects.requireNonNullElse; public class EnvironmentHelper { - public static Properties getHibernateProperties(ConfigurableEnvironment environment, - ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { + public static Properties getHibernateProperties( + ConfigurableEnvironment environment, ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { Properties properties = new Properties(); Map jpaProps = getPropertiesStartingWith(environment, "spring.jpa.properties"); for (Map.Entry entry : jpaProps.entrySet()) { @@ -40,18 +40,23 @@ public class EnvironmentHelper { properties.put(strippedKey, entry.getValue().toString()); } - //Spring Boot Autoconfiguration defaults + // Spring Boot Autoconfiguration defaults properties.putIfAbsent(AvailableSettings.SCANNER, "org.hibernate.boot.archive.scan.internal.DisabledScanner"); - properties.putIfAbsent(AvailableSettings.IMPLICIT_NAMING_STRATEGY, SpringImplicitNamingStrategy.class.getName()); - properties.putIfAbsent(AvailableSettings.PHYSICAL_NAMING_STRATEGY, CamelCaseToUnderscoresNamingStrategy.class.getName()); - //TODO The bean factory should be added as parameter but that requires that it can be injected from the entityManagerFactory bean from xBaseConfig - //properties.putIfAbsent(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(beanFactory)); + properties.putIfAbsent( + AvailableSettings.IMPLICIT_NAMING_STRATEGY, SpringImplicitNamingStrategy.class.getName()); + properties.putIfAbsent( + AvailableSettings.PHYSICAL_NAMING_STRATEGY, CamelCaseToUnderscoresNamingStrategy.class.getName()); + // TODO The bean factory should be added as parameter but that requires that it can be injected from the + // entityManagerFactory bean from xBaseConfig + // properties.putIfAbsent(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(beanFactory)); - //hapi-fhir-jpaserver-base "sensible defaults" - Map hapiJpaPropertyMap = new HapiFhirLocalContainerEntityManagerFactoryBean(myConfigurableListableBeanFactory).getJpaPropertyMap(); + // hapi-fhir-jpaserver-base "sensible defaults" + Map hapiJpaPropertyMap = new HapiFhirLocalContainerEntityManagerFactoryBean( + myConfigurableListableBeanFactory) + .getJpaPropertyMap(); hapiJpaPropertyMap.forEach(properties::putIfAbsent); - //hapi-fhir-jpaserver-starter defaults + // hapi-fhir-jpaserver-starter defaults properties.putIfAbsent(AvailableSettings.FORMAT_SQL, false); properties.putIfAbsent(AvailableSettings.SHOW_SQL, false); properties.putIfAbsent(AvailableSettings.HBM2DDL_AUTO, "update"); @@ -61,43 +66,60 @@ public class EnvironmentHelper { properties.putIfAbsent(AvailableSettings.USE_STRUCTURED_CACHE, false); properties.putIfAbsent(AvailableSettings.USE_MINIMAL_PUTS, false); - //Hibernate Search defaults + // Hibernate Search defaults properties.putIfAbsent(HibernateOrmMapperSettings.ENABLED, false); if (Boolean.parseBoolean(String.valueOf(properties.get(HibernateOrmMapperSettings.ENABLED)))) { if (isElasticsearchEnabled(environment)) { - properties.putIfAbsent(BackendSettings.backendKey(BackendSettings.TYPE), ElasticsearchBackendSettings.TYPE_NAME); + properties.putIfAbsent( + BackendSettings.backendKey(BackendSettings.TYPE), ElasticsearchBackendSettings.TYPE_NAME); } else { - properties.putIfAbsent(BackendSettings.backendKey(BackendSettings.TYPE), LuceneBackendSettings.TYPE_NAME); + properties.putIfAbsent( + BackendSettings.backendKey(BackendSettings.TYPE), LuceneBackendSettings.TYPE_NAME); } - if (properties.get(BackendSettings.backendKey(BackendSettings.TYPE)).equals(LuceneBackendSettings.TYPE_NAME)) { - properties.putIfAbsent(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), LocalFileSystemDirectoryProvider.NAME); - properties.putIfAbsent(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), "target/lucenefiles"); - properties.putIfAbsent(BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER), - HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName()); - properties.putIfAbsent(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), Version.LATEST); + if (properties + .get(BackendSettings.backendKey(BackendSettings.TYPE)) + .equals(LuceneBackendSettings.TYPE_NAME)) { + properties.putIfAbsent( + BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), + LocalFileSystemDirectoryProvider.NAME); + properties.putIfAbsent( + BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), "target/lucenefiles"); + properties.putIfAbsent( + BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER), + HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName()); + properties.putIfAbsent( + BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), Version.LATEST); - } else if (properties.get(BackendSettings.backendKey(BackendSettings.TYPE)).equals(ElasticsearchBackendSettings.TYPE_NAME)) { + } else if (properties + .get(BackendSettings.backendKey(BackendSettings.TYPE)) + .equals(ElasticsearchBackendSettings.TYPE_NAME)) { ElasticsearchHibernatePropertiesBuilder builder = new ElasticsearchHibernatePropertiesBuilder(); - IndexStatus requiredIndexStatus = environment.getProperty("elasticsearch.required_index_status", IndexStatus.class); + IndexStatus requiredIndexStatus = + environment.getProperty("elasticsearch.required_index_status", IndexStatus.class); builder.setRequiredIndexStatus(requireNonNullElse(requiredIndexStatus, IndexStatus.YELLOW)); builder.setHosts(getElasticsearchServerUrl(environment)); builder.setUsername(getElasticsearchServerUsername(environment)); builder.setPassword(getElasticsearchServerPassword(environment)); builder.setProtocol(getElasticsearchServerProtocol(environment)); - SchemaManagementStrategyName indexSchemaManagementStrategy = environment.getProperty("elasticsearch.schema_management_strategy", SchemaManagementStrategyName.class); - builder.setIndexSchemaManagementStrategy(requireNonNullElse(indexSchemaManagementStrategy, SchemaManagementStrategyName.CREATE)); - Boolean refreshAfterWrite = environment.getProperty("elasticsearch.debug.refresh_after_write", Boolean.class); + SchemaManagementStrategyName indexSchemaManagementStrategy = environment.getProperty( + "elasticsearch.schema_management_strategy", SchemaManagementStrategyName.class); + builder.setIndexSchemaManagementStrategy( + requireNonNullElse(indexSchemaManagementStrategy, SchemaManagementStrategyName.CREATE)); + Boolean refreshAfterWrite = + environment.getProperty("elasticsearch.debug.refresh_after_write", Boolean.class); if (refreshAfterWrite == null || !refreshAfterWrite) { builder.setDebugIndexSyncStrategy(AutomaticIndexingSynchronizationStrategyNames.ASYNC); } else { builder.setDebugIndexSyncStrategy(AutomaticIndexingSynchronizationStrategyNames.READ_SYNC); } - builder.setDebugPrettyPrintJsonLog(requireNonNullElse(environment.getProperty("elasticsearch.debug.pretty_print_json_log", Boolean.class), false)); + builder.setDebugPrettyPrintJsonLog(requireNonNullElse( + environment.getProperty("elasticsearch.debug.pretty_print_json_log", Boolean.class), false)); builder.apply(properties); } else { - throw new UnsupportedOperationException("Unsupported Hibernate Search backend: " + properties.get(BackendSettings.backendKey(BackendSettings.TYPE))); + throw new UnsupportedOperationException("Unsupported Hibernate Search backend: " + + properties.get(BackendSettings.backendKey(BackendSettings.TYPE))); } } @@ -128,8 +150,7 @@ public class EnvironmentHelper { } } - public static Map getPropertiesStartingWith(ConfigurableEnvironment aEnv, - String aKeyPrefix) { + public static Map getPropertiesStartingWith(ConfigurableEnvironment aEnv, String aKeyPrefix) { Map result = new HashMap<>(); Map map = getAllProperties(aEnv); @@ -167,7 +188,6 @@ public class EnvironmentHelper { } return result; - } private static void addAll(Map aBase, Map aToBeAdded) { diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/util/JpaHibernatePropertiesProvider.java b/src/main/java/ca/uhn/fhir/jpa/starter/util/JpaHibernatePropertiesProvider.java index 696f348..9a4bc0b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/util/JpaHibernatePropertiesProvider.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/util/JpaHibernatePropertiesProvider.java @@ -7,27 +7,26 @@ import org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver; import org.hibernate.engine.jdbc.dialect.spi.DatabaseMetaDataDialectResolutionInfoAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import javax.sql.DataSource; - import java.sql.Connection; import java.sql.SQLException; +import javax.sql.DataSource; public class JpaHibernatePropertiesProvider extends HibernatePropertiesProvider { - private final Dialect dialect; + private final Dialect dialect; - public JpaHibernatePropertiesProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { - DataSource connection = myEntityManagerFactory.getDataSource(); - try ( Connection dbConnection = connection.getConnection()){ - dialect = new StandardDialectResolver() - .resolveDialect(new DatabaseMetaDataDialectResolutionInfoAdapter(dbConnection.getMetaData())); - } catch (SQLException sqlException) { - throw new ConfigurationException(sqlException.getMessage(), sqlException); - } - } + public JpaHibernatePropertiesProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { + DataSource connection = myEntityManagerFactory.getDataSource(); + try (Connection dbConnection = connection.getConnection()) { + dialect = new StandardDialectResolver() + .resolveDialect(new DatabaseMetaDataDialectResolutionInfoAdapter(dbConnection.getMetaData())); + } catch (SQLException sqlException) { + throw new ConfigurationException(sqlException.getMessage(), sqlException); + } + } - @Override - public Dialect getDialect() { - return dialect; - } + @Override + public Dialect getDialect() { + return dialect; + } }