spotless apply formatting

This commit is contained in:
Justin McKelvy
2023-11-28 07:19:13 -07:00
parent 8c18c7dbc7
commit 0aa001b6f6
47 changed files with 757 additions and 668 deletions

View File

@@ -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. 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 ## 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. 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: 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 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 2) classes will be instantiated via reflection if no matching Bean is found

View File

@@ -1,7 +1,5 @@
package ca.uhn.fhir.jpa.starter; package ca.uhn.fhir.jpa.starter;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings.ClientIdStrategyEnum; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings.ClientIdStrategyEnum;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
@@ -23,7 +21,7 @@ import java.util.Set;
@Configuration @Configuration
@EnableConfigurationProperties @EnableConfigurationProperties
public class AppProperties { public class AppProperties {
private Boolean ips_enabled = false; private Boolean ips_enabled = false;
private Boolean openapi_enabled = false; private Boolean openapi_enabled = false;
private Boolean mdm_enabled = false; private Boolean mdm_enabled = false;
@@ -76,12 +74,13 @@ public class AppProperties {
private Boolean reload_existing_implementationguides = false; private Boolean reload_existing_implementationguides = false;
private Map<String, PackageInstallationSpec> implementationGuides = null; private Map<String, PackageInstallationSpec> implementationGuides = null;
private Boolean cr_enabled = false; 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 staticLocation = null;
private String staticLocationPrefix = "/static"; private String staticLocationPrefix = "/static";
private Boolean lastn_enabled = false; private Boolean lastn_enabled = false;
private boolean store_resource_in_lucene_index_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 = false;
private Boolean use_apache_address_strategy_https = false; private Boolean use_apache_address_strategy_https = false;
private Integer bundle_batch_pool_size = 20; private Integer bundle_batch_pool_size = 20;
@@ -97,12 +96,10 @@ public class AppProperties {
this.staticLocationPrefix = staticLocationPrefix; this.staticLocationPrefix = staticLocationPrefix;
} }
public List<String> getCustomInterceptorClasses() { public List<String> getCustomInterceptorClasses() {
return custom_interceptor_classes; return custom_interceptor_classes;
} }
public String getStaticLocation() { public String getStaticLocation() {
return staticLocation; return staticLocation;
} }
@@ -111,7 +108,6 @@ public class AppProperties {
this.staticLocation = staticLocation; this.staticLocation = staticLocation;
} }
public Boolean getOpenapi_enabled() { public Boolean getOpenapi_enabled() {
return openapi_enabled; return openapi_enabled;
} }
@@ -168,7 +164,6 @@ public class AppProperties {
this.ips_enabled = ips_enabled; this.ips_enabled = ips_enabled;
} }
public Boolean getMdm_enabled() { public Boolean getMdm_enabled() {
return mdm_enabled; return mdm_enabled;
} }
@@ -245,8 +240,7 @@ public class AppProperties {
return client_id_strategy; return client_id_strategy;
} }
public void setClient_id_strategy( public void setClient_id_strategy(ClientIdStrategyEnum client_id_strategy) {
ClientIdStrategyEnum client_id_strategy) {
this.client_id_strategy = client_id_strategy; this.client_id_strategy = client_id_strategy;
} }
@@ -294,8 +288,7 @@ public class AppProperties {
return allow_override_default_search_params; return allow_override_default_search_params;
} }
public void setAllow_override_default_search_params( public void setAllow_override_default_search_params(Boolean allow_override_default_search_params) {
Boolean allow_override_default_search_params) {
this.allow_override_default_search_params = 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; return auto_create_placeholder_reference_targets;
} }
public void setAuto_create_placeholder_reference_targets( public void setAuto_create_placeholder_reference_targets(Boolean auto_create_placeholder_reference_targets) {
Boolean auto_create_placeholder_reference_targets) {
this.auto_create_placeholder_reference_targets = 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; return enforce_referential_integrity_on_delete;
} }
public void setEnforce_referential_integrity_on_delete( public void setEnforce_referential_integrity_on_delete(Boolean enforce_referential_integrity_on_delete) {
Boolean enforce_referential_integrity_on_delete) {
this.enforce_referential_integrity_on_delete = 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; return enforce_referential_integrity_on_write;
} }
public void setEnforce_referential_integrity_on_write( public void setEnforce_referential_integrity_on_write(Boolean enforce_referential_integrity_on_write) {
Boolean enforce_referential_integrity_on_write) {
this.enforce_referential_integrity_on_write = 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; this.tester = tester;
} }
public Boolean getNarrative_enabled() public Boolean getNarrative_enabled() {
{
return narrative_enabled; return narrative_enabled;
} }
public void setNarrative_enabled(Boolean narrative_enabled) public void setNarrative_enabled(Boolean narrative_enabled) {
{
this.narrative_enabled = narrative_enabled; this.narrative_enabled = narrative_enabled;
} }
@@ -607,15 +595,14 @@ public class AppProperties {
public void setAllow_Credentials(Boolean allow_Credentials) { public void setAllow_Credentials(Boolean allow_Credentials) {
this.allow_Credentials = allow_Credentials; this.allow_Credentials = allow_Credentials;
} }
} }
public static class Logger { public static class Logger {
private String name = "fhirtest.access"; private String name = "fhirtest.access";
private String error_format = "ERROR - ${requestVerb} ${requestUrl}"; 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; private Boolean log_exceptions = true;
public String getName() { public String getName() {
@@ -651,7 +638,6 @@ public class AppProperties {
} }
} }
public static class Tester { public static class Tester {
private String name; private String name;
@@ -692,7 +678,6 @@ public class AppProperties {
} }
} }
public static class Validation { public static class Validation {
private Boolean requests_enabled = false; 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) { public void setPartitioning_include_in_search_hashes(Boolean partitioning_include_in_search_hashes) {
this.partitioning_include_in_search_hashes = partitioning_include_in_search_hashes; this.partitioning_include_in_search_hashes = partitioning_include_in_search_hashes;
} }
public Boolean getAllow_references_across_partitions() { public Boolean getAllow_references_across_partitions() {
return allow_references_across_partitions; return allow_references_across_partitions;
} }
@@ -766,7 +752,6 @@ public class AppProperties {
this.email = email; this.email = email;
} }
public static class Email { public static class Email {
public String getFrom() { public String getFrom() {
return from; return from;
@@ -859,4 +844,4 @@ public class AppProperties {
public void setEnable_index_of_type(boolean enable_index_of_type) { public void setEnable_index_of_type(boolean enable_index_of_type) {
this.enable_index_of_type = enable_index_of_type; this.enable_index_of_type = enable_index_of_type;
} }
} }

View File

@@ -1,9 +1,6 @@
package ca.uhn.fhir.jpa.starter; package ca.uhn.fhir.jpa.starter;
import ca.uhn.fhir.batch2.jobs.config.Batch2JobsConfig; 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.batch2.JpaBatch2Config;
import ca.uhn.fhir.jpa.starter.annotations.OnEitherVersion; import ca.uhn.fhir.jpa.starter.annotations.OnEitherVersion;
import ca.uhn.fhir.jpa.starter.cdshooks.StarterCdsHooksConfig; 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.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.DispatcherServlet;
@ServletComponentScan(basePackageClasses = { RestfulServer.class }) @ServletComponentScan(basePackageClasses = {RestfulServer.class})
@SpringBootApplication(exclude = { ElasticsearchRestClientAutoConfiguration.class, ThymeleafAutoConfiguration.class }) @SpringBootApplication(exclude = {ElasticsearchRestClientAutoConfiguration.class, ThymeleafAutoConfiguration.class})
@Import({ @Import({
StarterCrR4Config.class, StarterCrR4Config.class,
StarterCrDstu3Config.class, StarterCrDstu3Config.class,
StarterCdsHooksConfig.class, StarterCdsHooksConfig.class,
SubscriptionSubmitterConfig.class, SubscriptionSubmitterConfig.class,
SubscriptionProcessorConfig.class, SubscriptionProcessorConfig.class,
SubscriptionChannelConfig.class, SubscriptionChannelConfig.class,
WebsocketDispatcherConfig.class, WebsocketDispatcherConfig.class,
MdmConfig.class, MdmConfig.class,
JpaBatch2Config.class, JpaBatch2Config.class,
Batch2JobsConfig.class Batch2JobsConfig.class
}) })
public class Application extends SpringBootServletInitializer { public class Application extends SpringBootServletInitializer {
@@ -57,8 +54,7 @@ public class Application extends SpringBootServletInitializer {
} }
@Override @Override
protected SpringApplicationBuilder configure( protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
SpringApplicationBuilder builder) {
return builder.sources(Application.class); return builder.sources(Application.class);
} }
@@ -80,11 +76,11 @@ public class Application extends SpringBootServletInitializer {
@Bean @Bean
public ServletRegistrationBean overlayRegistrationBean() { public ServletRegistrationBean overlayRegistrationBean() {
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext(); AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext =
new AnnotationConfigWebApplicationContext();
annotationConfigWebApplicationContext.register(FhirTesterConfig.class); annotationConfigWebApplicationContext.register(FhirTesterConfig.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet( DispatcherServlet dispatcherServlet = new DispatcherServlet(annotationConfigWebApplicationContext);
annotationConfigWebApplicationContext);
dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class); dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
dispatcherServlet.setContextConfigLocation(FhirTesterConfig.class.getName()); dispatcherServlet.setContextConfigLocation(FhirTesterConfig.class.getName());
@@ -93,11 +89,10 @@ public class Application extends SpringBootServletInitializer {
registrationBean.addUrlMappings("/*"); registrationBean.addUrlMappings("/*");
registrationBean.setLoadOnStartup(1); registrationBean.setLoadOnStartup(1);
return registrationBean; return registrationBean;
} }
// @Bean // @Bean
// IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) { // IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) {
// return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer); // return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer);
// } // }
} }

View File

@@ -19,33 +19,32 @@ public class ExtraStaticFilesConfigurer implements WebMvcConfigurer {
public ExtraStaticFilesConfigurer(AppProperties appProperties) { public ExtraStaticFilesConfigurer(AppProperties appProperties) {
rootContextPath = appProperties.getStaticLocationPrefix(); rootContextPath = appProperties.getStaticLocationPrefix();
if(rootContextPath.endsWith("/")) if (rootContextPath.endsWith("/"))
rootContextPath = rootContextPath.substring(0, rootContextPath.lastIndexOf('/')); rootContextPath = rootContextPath.substring(0, rootContextPath.lastIndexOf('/'));
staticLocation = appProperties.getStaticLocation(); staticLocation = appProperties.getStaticLocation();
if(staticLocation.endsWith("/")) if (staticLocation.endsWith("/")) staticLocation = staticLocation.substring(0, staticLocation.lastIndexOf('/'));
staticLocation = staticLocation.substring(0, staticLocation.lastIndexOf('/'));
} }
@Override
public void addResourceHandlers(ResourceHandlerRegistry theRegistry) {
theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation);
}
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry theRegistry) { public void addViewControllers(ViewControllerRegistry registry) {
theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation); String path = URI.create(staticLocation).getPath();
} String lastSegment = path.substring(path.lastIndexOf('/') + 1);
@Override registry.addViewController(rootContextPath)
public void addViewControllers(ViewControllerRegistry registry) { .setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html");
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 + "/" + lastSegment + "/")
.setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html");
registry.addViewController(rootContextPath + "/" + lastSegment + "/").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
registry.setOrder(Ordered.HIGHEST_PRECEDENCE); }
}
}

View File

@@ -10,9 +10,11 @@ public class OnCorsPresent implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { 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 == null) return false;
if (config.getCors() == null) return false; if (config.getCors() == null) return false;
return true; return true;
} }
} }

View File

@@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
public class OnDSTU2Condition implements Condition { public class OnDSTU2Condition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext
getEnvironment() .getEnvironment()
.getProperty("hapi.fhir.fhir_version") .getProperty("hapi.fhir.fhir_version")
.toUpperCase()); .toUpperCase());
return version == FhirVersionEnum.DSTU2; return version == FhirVersionEnum.DSTU2;
}
}
} }

View File

@@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
public class OnDSTU3Condition implements Condition { public class OnDSTU3Condition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext
getEnvironment() .getEnvironment()
.getProperty("hapi.fhir.fhir_version") .getProperty("hapi.fhir.fhir_version")
.toUpperCase()); .toUpperCase());
return version == FhirVersionEnum.DSTU3; return version == FhirVersionEnum.DSTU3;
}
}
} }

View File

@@ -6,34 +6,28 @@ import org.springframework.context.annotation.Conditional;
public class OnEitherVersion extends AnyNestedCondition { public class OnEitherVersion extends AnyNestedCondition {
OnEitherVersion() { OnEitherVersion() {
super(ConfigurationPhase.REGISTER_BEAN); 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 {
} }
@Conditional(OnR5Condition.class) @Override
static class OnR5 { 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 {}
@Conditional(OnR5Condition.class)
static class OnR5 {}
}

View File

@@ -10,9 +10,11 @@ public class OnImplementationGuidesPresent implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { 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 == null) return false;
if (config.getImplementationGuides() == null) return false; if (config.getImplementationGuides() == null) return false;
return !config.getImplementationGuides().isEmpty(); return !config.getImplementationGuides().isEmpty();
} }
} }

View File

@@ -8,10 +8,10 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
public class OnR4BCondition implements Condition { public class OnR4BCondition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
String version = conditionContext. String version = conditionContext
getEnvironment() .getEnvironment()
.getProperty("hapi.fhir.fhir_version") .getProperty("hapi.fhir.fhir_version")
.toUpperCase(); .toUpperCase();
return FhirVersionEnum.R4B.name().equals(version); return FhirVersionEnum.R4B.name().equals(version);
} }

View File

@@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
public class OnR4Condition implements Condition { public class OnR4Condition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext
getEnvironment() .getEnvironment()
.getProperty("hapi.fhir.fhir_version") .getProperty("hapi.fhir.fhir_version")
.toUpperCase()); .toUpperCase());
return version == FhirVersionEnum.R4; return version == FhirVersionEnum.R4;
}
}
} }

View File

@@ -6,14 +6,13 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
public class OnR5Condition implements Condition { public class OnR5Condition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext. FhirVersionEnum version = FhirVersionEnum.forVersionString(conditionContext
getEnvironment() .getEnvironment()
.getProperty("hapi.fhir.fhir_version") .getProperty("hapi.fhir.fhir_version")
.toUpperCase()); .toUpperCase());
return version == FhirVersionEnum.R5; return version == FhirVersionEnum.R5;
}
}
} }

View File

@@ -6,9 +6,9 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
public class CdsHooksConfigCondition implements Condition { public class CdsHooksConfigCondition implements Condition {
@Override @Override
public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) {
String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cdshooks.enabled"); String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cdshooks.enabled");
return Boolean.parseBoolean(property); return Boolean.parseBoolean(property);
} }
} }

View File

@@ -3,7 +3,5 @@ package ca.uhn.fhir.jpa.starter.cdshooks;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson; import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties({ "extension" }) @JsonIgnoreProperties({"extension"})
public class CdsHooksRequest extends CdsServiceRequestJson { public class CdsHooksRequest extends CdsServiceRequestJson {}
}

View File

@@ -1,24 +1,5 @@
package ca.uhn.fhir.jpa.starter.cdshooks; 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.jpa.starter.AppProperties;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; 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.CdsServiceRequestJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson; import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServicesJson; 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; import static ca.uhn.hapi.fhir.cdshooks.config.CdsHooksConfig.CDS_HOOKS_OBJECT_MAPPER_FACTORY;
@@ -36,12 +33,16 @@ public class CdsHooksServlet extends HttpServlet {
@Autowired @Autowired
private AppProperties appProperties; private AppProperties appProperties;
@Autowired @Autowired
private ProviderConfiguration providerConfiguration; private ProviderConfiguration providerConfiguration;
@Autowired @Autowired
ICdsServiceRegistry cdsServiceRegistry; ICdsServiceRegistry cdsServiceRegistry;
@Autowired @Autowired
RestfulServer restfulServer; RestfulServer restfulServer;
@Autowired @Autowired
@Qualifier(CDS_HOOKS_OBJECT_MAPPER_FACTORY) @Qualifier(CDS_HOOKS_OBJECT_MAPPER_FACTORY)
ObjectMapper objectMapper; ObjectMapper objectMapper;
@@ -70,8 +71,11 @@ public class CdsHooksServlet extends HttpServlet {
} }
ErrorHandling.setAccessControlHeaders(response, appProperties); ErrorHandling.setAccessControlHeaders(response, appProperties);
response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType()); response.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
response.getWriter().println(new GsonBuilder().setPrettyPrinting().create().toJson( response.getWriter()
JsonParser.parseString(objectMapper.writeValueAsString(getServices())))); .println(new GsonBuilder()
.setPrettyPrinting()
.create()
.toJson(JsonParser.parseString(objectMapper.writeValueAsString(getServices()))));
} }
@Override @Override
@@ -79,8 +83,8 @@ public class CdsHooksServlet extends HttpServlet {
throws ServletException, IOException { throws ServletException, IOException {
try { try {
if (request.getContentType() == null || !request.getContentType().startsWith("application/json")) { if (request.getContentType() == null || !request.getContentType().startsWith("application/json")) {
throw new ServletException(String.format("Invalid content type %s. Please use application/json.", throw new ServletException(String.format(
request.getContentType())); "Invalid content type %s. Please use application/json.", request.getContentType()));
} }
logger.info(request.getRequestURI()); logger.info(request.getRequestURI());
String service = request.getPathInfo().replace("/", ""); String service = request.getPathInfo().replace("/", "");
@@ -92,7 +96,10 @@ public class CdsHooksServlet extends HttpServlet {
CdsServiceResponseJson serviceResponseJson = cdsServiceRegistry.callService(service, cdsHooksRequest); CdsServiceResponseJson serviceResponseJson = cdsServiceRegistry.callService(service, cdsHooksRequest);
// Using GSON pretty print format as Jackson's is ugly // 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))); .toJson(JsonParser.parseString(objectMapper.writeValueAsString(serviceResponseJson)));
logger.info(jsonResponse); logger.info(jsonResponse);
response.setContentType("text/json;charset=UTF-8"); 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 hook instance: {}", request.getHookInstance());
logger.info("cds-hooks local server address: {}", appProperties.getServer_address()); logger.info("cds-hooks local server address: {}", appProperties.getServer_address());
logger.info("cds-hooks fhir server address: {}", request.getFhirServer()); 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() { private CdsServicesJson getServices() {

View File

@@ -1,91 +1,105 @@
package ca.uhn.fhir.jpa.starter.cdshooks; 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.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Arrays; import java.util.Arrays;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.jpa.starter.AppProperties;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
public class ErrorHandling { public class ErrorHandling {
private ErrorHandling() {} private ErrorHandling() {}
public static void handleError(HttpServletResponse response, String message, public static void handleError(
Exception e, AppProperties myAppProperties) HttpServletResponse response, String message, Exception e, AppProperties myAppProperties)
throws IOException { throws IOException {
setAccessControlHeaders(response, myAppProperties); setAccessControlHeaders(response, myAppProperties);
response.setStatus(500); // This will be overwritten with the correct status code downstream if needed. response.setStatus(500); // This will be overwritten with the correct status code downstream if needed.
response.getWriter().println(message); response.getWriter().println(message);
printMessageAndCause(e, response); printMessageAndCause(e, response);
if (e instanceof BaseServerResponseException) { if (e instanceof BaseServerResponseException) {
handleServerResponseException((BaseServerResponseException) e, response); handleServerResponseException((BaseServerResponseException) e, response);
} else if (e.getCause() instanceof BaseServerResponseException) { } else if (e.getCause() instanceof BaseServerResponseException) {
handleServerResponseException((BaseServerResponseException) e.getCause(), response); handleServerResponseException((BaseServerResponseException) e.getCause(), response);
} }
printStackTrack(e, response); printStackTrack(e, response);
} }
private static void handleServerResponseException(BaseServerResponseException e, HttpServletResponse response) private static void handleServerResponseException(BaseServerResponseException e, HttpServletResponse response)
throws IOException { throws IOException {
switch (e.getStatusCode()) { switch (e.getStatusCode()) {
case 401: case 401:
case 403: case 403:
response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode()); response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode());
response.getWriter().println( response.getWriter()
"Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access."); .println(
response.setStatus(412); "Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access.");
break; response.setStatus(412);
case 404: break;
response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode()); case 404:
response.getWriter().println("Ensure the resource exists on the remote server."); response.getWriter().println("Precondition Failed. Remote FHIR server returned: " + e.getStatusCode());
response.setStatus(412); response.getWriter().println("Ensure the resource exists on the remote server.");
break; response.setStatus(412);
default: break;
response.getWriter().println("Unhandled Error in Remote FHIR server: " + e.getStatusCode()); default:
} response.getWriter().println("Unhandled Error in Remote FHIR server: " + e.getStatusCode());
} }
}
private static void printMessageAndCause(Exception e, HttpServletResponse response) throws IOException { private static void printMessageAndCause(Exception e, HttpServletResponse response) throws IOException {
if (e.getMessage() != null) { if (e.getMessage() != null) {
response.getWriter().println(e.getMessage()); response.getWriter().println(e.getMessage());
} }
if (e.getCause() != null && e.getCause().getMessage() != null) { if (e.getCause() != null && e.getCause().getMessage() != null) {
response.getWriter().println(e.getCause().getMessage()); response.getWriter().println(e.getCause().getMessage());
} }
} }
private static void printStackTrack(Exception e, HttpServletResponse response) throws IOException { private static void printStackTrack(Exception e, HttpServletResponse response) throws IOException {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw)); e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString(); String exceptionAsString = sw.toString();
response.getWriter().println(exceptionAsString); response.getWriter().println(exceptionAsString);
} }
public static void setAccessControlHeaders(HttpServletResponse resp, AppProperties myAppProperties) { public static void setAccessControlHeaders(HttpServletResponse resp, AppProperties myAppProperties) {
if (myAppProperties.getCors() != null) { if (myAppProperties.getCors() != null) {
if (myAppProperties.getCors().getAllow_Credentials()) { if (myAppProperties.getCors().getAllow_Credentials()) {
resp.setHeader("Access-Control-Allow-Origin", resp.setHeader(
myAppProperties.getCors().getAllowed_origin().stream().findFirst().get()); "Access-Control-Allow-Origin",
resp.setHeader("Access-Control-Allow-Methods", myAppProperties.getCors().getAllowed_origin().stream()
String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS"))); .findFirst()
resp.setHeader("Access-Control-Allow-Headers", .get());
String.join(", ", Arrays.asList("x-fhir-starter", "Origin", resp.setHeader(
"Accept", "X-Requested-With", "Content-Type", "Authorization", "Cache-Control"))); "Access-Control-Allow-Methods",
resp.setHeader("Access-Control-Expose-Headers", String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS")));
String.join(", ", Arrays.asList("Location", "Content-Location"))); resp.setHeader(
resp.setHeader("Access-Control-Max-Age", "86400"); "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 static class CdsHooksError extends RuntimeException {
public CdsHooksError(String message) { public CdsHooksError(String message) {
super(message); super(message);
} }
} }
} }

View File

@@ -4,7 +4,8 @@ import ca.uhn.fhir.jpa.starter.cr.CrProperties;
public class ProviderConfiguration { 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 String clientIdHeaderName;
private final boolean cqlLoggingEnabled; private final boolean cqlLoggingEnabled;

View File

@@ -1,5 +1,11 @@
package ca.uhn.fhir.jpa.starter.cdshooks; 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.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean; 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.Configuration;
import org.springframework.context.annotation.Import; 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 @Configuration
@Conditional({ CdsHooksConfigCondition.class, CrConfigCondition.class }) @Conditional({CdsHooksConfigCondition.class, CrConfigCondition.class})
@Import(CdsHooksConfig.class) @Import(CdsHooksConfig.class)
public class StarterCdsHooksConfig { public class StarterCdsHooksConfig {
@Bean @Bean

View File

@@ -10,18 +10,20 @@ import org.springframework.core.env.ConfigurableEnvironment;
@Configuration @Configuration
public class ElasticsearchConfig { public class ElasticsearchConfig {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ElasticsearchConfig.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ElasticsearchConfig.class);
@Bean @Bean
public ElasticsearchSvcImpl elasticsearchSvc(ConfigurableEnvironment configurableEnvironment) { public ElasticsearchSvcImpl elasticsearchSvc(ConfigurableEnvironment configurableEnvironment) {
if (EnvironmentHelper.isElasticsearchEnabled(configurableEnvironment)) { if (EnvironmentHelper.isElasticsearchEnabled(configurableEnvironment)) {
String elasticsearchUrl = EnvironmentHelper.getElasticsearchServerUrl(configurableEnvironment); String elasticsearchUrl = EnvironmentHelper.getElasticsearchServerUrl(configurableEnvironment);
if (elasticsearchUrl.startsWith("http")) { if (elasticsearchUrl.startsWith("http")) {
elasticsearchUrl =elasticsearchUrl.substring(elasticsearchUrl.indexOf("://") + 3); elasticsearchUrl = elasticsearchUrl.substring(elasticsearchUrl.indexOf("://") + 3);
} }
String elasticsearchProtocol = EnvironmentHelper.getElasticsearchServerProtocol(configurableEnvironment); String elasticsearchProtocol = EnvironmentHelper.getElasticsearchServerProtocol(configurableEnvironment);
String elasticsearchUsername = EnvironmentHelper.getElasticsearchServerUsername(configurableEnvironment); String elasticsearchUsername = EnvironmentHelper.getElasticsearchServerUsername(configurableEnvironment);
String elasticsearchPassword = EnvironmentHelper.getElasticsearchServerPassword(configurableEnvironment); String elasticsearchPassword = EnvironmentHelper.getElasticsearchServerPassword(configurableEnvironment);
ourLog.info("Configuring elasticsearch {} {}", elasticsearchProtocol, elasticsearchUrl); ourLog.info("Configuring elasticsearch {} {}", elasticsearchProtocol, elasticsearchUrl);
return new ElasticsearchSvcImpl(elasticsearchProtocol, elasticsearchUrl, elasticsearchUsername, elasticsearchPassword); return new ElasticsearchSvcImpl(
elasticsearchProtocol, elasticsearchUrl, elasticsearchUsername, elasticsearchPassword);
} else { } else {
return null; return null;
} }

View File

@@ -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.jpa.subscription.match.deliver.email.IEmailSender;
import ca.uhn.fhir.rest.server.mail.MailConfig; import ca.uhn.fhir.rest.server.mail.MailConfig;
import ca.uhn.fhir.rest.server.mail.MailSvc; import ca.uhn.fhir.rest.server.mail.MailSvc;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import org.cqframework.cql.cql2elm.CqlTranslatorOptions;
import org.hl7.fhir.r4.model.Bundle.BundleType; import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.boot.env.YamlPropertySourceLoader; import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; 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); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
public FhirServerConfigCommon(AppProperties appProperties) { public FhirServerConfigCommon(AppProperties appProperties) {
ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny") + " contains searches"); ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny")
ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny") + " multiple deletes"); + " contains searches");
ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny") + " external references"); ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny")
ourLog.info("Server configured to " + (appProperties.getDao_scheduling_enabled() ? "enable" : "disable") + " DAO scheduling"); + " multiple deletes");
ourLog.info("Server configured to " + (appProperties.getDelete_expunge_enabled() ? "enable" : "disable") + " delete expunges"); ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny")
ourLog.info("Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges"); + " external references");
ourLog.info("Server configured to " + (appProperties.getAllow_override_default_search_params() ? "allow" : "deny") + " overriding default search params"); ourLog.info("Server configured to " + (appProperties.getDao_scheduling_enabled() ? "enable" : "disable")
ourLog.info("Server configured to " + (appProperties.getAuto_create_placeholder_reference_targets() ? "allow" : "disable") + " auto-creating placeholder references"); + " DAO scheduling");
ourLog.info("Server configured to auto-version references at paths {}", appProperties.getAuto_version_reference_at_paths()); 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) { if (appProperties.getSubscription().getEmail() != null) {
AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail(); AppProperties.Subscription.Email email =
ourLog.info( appProperties.getSubscription().getEmail();
"Server is configured to enable email with host '" + email.getHost() + "' and port " + email.getPort()); 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"); ourLog.info("Server will use '" + email.getFrom() + "' as the from email address");
if (!Strings.isNullOrEmpty(email.getUsername())) { if (!Strings.isNullOrEmpty(email.getUsername())) {
@@ -85,19 +94,27 @@ public class FhirServerConfigCommon {
public JpaStorageSettings jpaStorageSettings(AppProperties appProperties) { public JpaStorageSettings jpaStorageSettings(AppProperties appProperties) {
JpaStorageSettings jpaStorageSettings = new JpaStorageSettings(); JpaStorageSettings jpaStorageSettings = new JpaStorageSettings();
jpaStorageSettings.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? StorageSettings.IndexEnabledEnum.ENABLED : StorageSettings.IndexEnabledEnum.DISABLED); jpaStorageSettings.setIndexMissingFields(
jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets()); appProperties.getEnable_index_missing_fields()
jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); ? StorageSettings.IndexEnabledEnum.ENABLED
jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write()); : StorageSettings.IndexEnabledEnum.DISABLED);
jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete()); jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(
jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); appProperties.getAuto_create_placeholder_reference_targets());
jpaStorageSettings.setAllowMultipleDelete(appProperties.getAllow_multiple_delete()); jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths());
jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(
jpaStorageSettings.setSchedulingDisabled(!appProperties.getDao_scheduling_enabled()); appProperties.getEnforce_referential_integrity_on_write());
jpaStorageSettings.setDeleteExpungeEnabled(appProperties.getDelete_expunge_enabled()); jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(
jpaStorageSettings.setExpungeEnabled(appProperties.getExpunge_enabled()); appProperties.getEnforce_referential_integrity_on_delete());
if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches());
jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); 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(); Integer maxFetchSize = appProperties.getMax_page_size();
jpaStorageSettings.setFetchSizeDefaultMaximum(maxFetchSize); jpaStorageSettings.setFetchSizeDefaultMaximum(maxFetchSize);
@@ -115,13 +132,13 @@ public class FhirServerConfigCommon {
// Subscriptions are enabled by channel type // Subscriptions are enabled by channel type
if (appProperties.getSubscription().getResthook_enabled()) { if (appProperties.getSubscription().getResthook_enabled()) {
ourLog.info("Enabling REST-hook subscriptions"); ourLog.info("Enabling REST-hook subscriptions");
jpaStorageSettings jpaStorageSettings.addSupportedSubscriptionType(
.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK); org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.RESTHOOK);
} }
if (appProperties.getSubscription().getEmail() != null) { if (appProperties.getSubscription().getEmail() != null) {
ourLog.info("Enabling email subscriptions"); ourLog.info("Enabling email subscriptions");
jpaStorageSettings jpaStorageSettings.addSupportedSubscriptionType(
.addSupportedSubscriptionType(org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL); org.hl7.fhir.dstu2.model.Subscription.SubscriptionChannelType.EMAIL);
} }
if (appProperties.getSubscription().getWebsocket_enabled()) { if (appProperties.getSubscription().getWebsocket_enabled()) {
ourLog.info("Enabling websocket subscriptions"); ourLog.info("Enabling websocket subscriptions");
@@ -130,120 +147,125 @@ public class FhirServerConfigCommon {
} }
} }
jpaStorageSettings.setFilterParameterEnabled(appProperties.getFilter_search_enabled()); jpaStorageSettings.setFilterParameterEnabled(appProperties.getFilter_search_enabled());
jpaStorageSettings.setAdvancedHSearchIndexing(appProperties.getAdvanced_lucene_indexing()); jpaStorageSettings.setAdvancedHSearchIndexing(appProperties.getAdvanced_lucene_indexing());
jpaStorageSettings.setTreatBaseUrlsAsLocal(new HashSet<>(appProperties.getLocal_base_urls())); jpaStorageSettings.setTreatBaseUrlsAsLocal(new HashSet<>(appProperties.getLocal_base_urls()));
if (appProperties.getLastn_enabled()) { if (appProperties.getLastn_enabled()) {
jpaStorageSettings.setLastNEnabled(true); jpaStorageSettings.setLastNEnabled(true);
} }
if(appProperties.getInline_resource_storage_below_size() != 0){ if (appProperties.getInline_resource_storage_below_size() != 0) {
jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size()); jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size());
} }
jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled()); jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled());
jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level());
jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); 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) { if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) {
jpaStorageSettings.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet())); 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) { @Bean
jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID); public PartitionSettings partitionSettings(AppProperties appProperties) {
jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); PartitionSettings retVal = new PartitionSettings();
}
//Parallel Batch GET execution settings
jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size());
jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size());
storageSettings(appProperties, jpaStorageSettings); // Partitioning
return jpaStorageSettings; 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 return retVal;
public YamlPropertySourceLoader yamlPropertySourceLoader() { }
return new YamlPropertySourceLoader();
}
@Bean @Primary
public PartitionSettings partitionSettings(AppProperties appProperties) { @Bean
PartitionSettings retVal = new PartitionSettings(); public HibernatePropertiesProvider jpaStarterDialectProvider(
LocalContainerEntityManagerFactoryBean myEntityManagerFactory) {
return new JpaHibernatePropertiesProvider(myEntityManagerFactory);
}
// Partitioning protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) {
if (appProperties.getPartitioning() != null) { jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches());
retVal.setPartitioningEnabled(true); jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references());
retVal.setIncludePartitionInSearchHashes(appProperties.getPartitioning().getPartitioning_include_in_search_hashes()); jpaStorageSettings.setDefaultSearchParamsCanBeOverridden(
if(appProperties.getPartitioning().getAllow_references_across_partitions()) { appProperties.getAllow_override_default_search_params());
retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED); if (appProperties.getSubscription() != null
} else { && appProperties.getSubscription().getEmail() != null)
retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED); 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 @Lazy
@Bean @Bean
public HibernatePropertiesProvider jpaStarterDialectProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) {
return new JpaHibernatePropertiesProvider(myEntityManagerFactory); DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl();
}
if (appProperties.getMax_binary_size() != null) {
binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size());
}
protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) { return binaryStorageSvc;
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());
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()); return buildEmailSender(appProperties.getSubscription().getEmail());
jpaStorageSettings.setIndexIdentifierOfType(appProperties.getEnable_index_of_type()); }
return jpaStorageSettings;
}
@Lazy // Return a dummy anonymous function instead of null. Spring does not like null beans.
@Bean // TODO Get the signature of
public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) { // ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory
DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl(); // changed so it does not require an instance of an IEmailSender
return theDetails -> {};
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 -> {};
}
private static IEmailSender buildEmailSender(AppProperties.Subscription.Email email) { private static IEmailSender buildEmailSender(AppProperties.Subscription.Email email) {
return new EmailSenderImpl(new MailSvc(new MailConfig() return new EmailSenderImpl(new MailSvc(new MailConfig()
.setSmtpHostname(email.getHost()) .setSmtpHostname(email.getHost())
.setSmtpPort(email.getPort()) .setSmtpPort(email.getPort())
.setSmtpUsername(email.getUsername()) .setSmtpUsername(email.getUsername())
.setSmtpPassword(email.getPassword()) .setSmtpPassword(email.getPassword())
.setSmtpUseStartTLS(email.getStartTlsEnable()))); .setSmtpUseStartTLS(email.getStartTlsEnable())));
} }
} }

View File

@@ -13,14 +13,11 @@ import org.springframework.context.annotation.Import;
@Configuration @Configuration
@Conditional(OnDSTU2Condition.class) @Conditional(OnDSTU2Condition.class)
@Import({ @Import({JpaDstu2Config.class, StarterJpaConfig.class})
JpaDstu2Config.class,
StarterJpaConfig.class
})
public class FhirServerConfigDstu2 { public class FhirServerConfigDstu2 {
@Bean @Bean
public ITermLoaderSvc termLoaderService(ITermDeferredStorageSvc theDeferredStorageSvc, ITermCodeSystemStorageSvc theCodeSystemStorageSvc) { public ITermLoaderSvc termLoaderService(
ITermDeferredStorageSvc theDeferredStorageSvc, ITermCodeSystemStorageSvc theCodeSystemStorageSvc) {
return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc); return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc);
} }
} }

View File

@@ -9,10 +9,5 @@ import org.springframework.context.annotation.Import;
@Configuration @Configuration
@Conditional(OnDSTU3Condition.class) @Conditional(OnDSTU3Condition.class)
@Import({ @Import({JpaDstu3Config.class, StarterJpaConfig.class, StarterCrDstu3Config.class, ElasticsearchConfig.class})
JpaDstu3Config.class, public class FhirServerConfigDstu3 {}
StarterJpaConfig.class,
StarterCrDstu3Config.class,
ElasticsearchConfig.class})
public class FhirServerConfigDstu3 {
}

View File

@@ -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.annotations.OnR4Condition;
import ca.uhn.fhir.jpa.starter.cr.StarterCrR4Config; import ca.uhn.fhir.jpa.starter.cr.StarterCrR4Config;
import ca.uhn.fhir.jpa.starter.ips.StarterIpsConfig; import ca.uhn.fhir.jpa.starter.ips.StarterIpsConfig;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@@ -18,5 +17,4 @@ import org.springframework.context.annotation.Import;
ElasticsearchConfig.class, ElasticsearchConfig.class,
StarterIpsConfig.class StarterIpsConfig.class
}) })
public class FhirServerConfigR4 { public class FhirServerConfigR4 {}
}

View File

@@ -9,11 +9,5 @@ import org.springframework.context.annotation.Import;
@Configuration @Configuration
@Conditional(OnR4BCondition.class) @Conditional(OnR4BCondition.class)
@Import({ @Import({JpaR4BConfig.class, SubscriptionTopicConfig.class, StarterJpaConfig.class, ElasticsearchConfig.class})
JpaR4BConfig.class, public class FhirServerConfigR4B {}
SubscriptionTopicConfig.class,
StarterJpaConfig.class,
ElasticsearchConfig.class
})
public class FhirServerConfigR4B {
}

View File

@@ -9,11 +9,5 @@ import org.springframework.context.annotation.Import;
@Configuration @Configuration
@Conditional(OnR5Condition.class) @Conditional(OnR5Condition.class)
@Import({ @Import({StarterJpaConfig.class, JpaR5Config.class, SubscriptionTopicConfig.class, ElasticsearchConfig.class})
StarterJpaConfig.class, public class FhirServerConfigR5 {}
JpaR5Config.class,
SubscriptionTopicConfig.class,
ElasticsearchConfig.class
})
public class FhirServerConfigR5 {
}

View File

@@ -4,11 +4,10 @@ import ca.uhn.fhir.jpa.starter.AppProperties;
import ca.uhn.fhir.to.FhirTesterMvcConfig; import ca.uhn.fhir.to.FhirTesterMvcConfig;
import ca.uhn.fhir.to.TesterConfig; import ca.uhn.fhir.to.TesterConfig;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
//@formatter:off // @formatter:off
/** /**
* This spring config file configures the web testing module. It serves two * This spring config file configures the web testing module. It serves two
* purposes: * purposes:
@@ -19,7 +18,7 @@ import org.springframework.context.annotation.Import;
*/ */
@Configuration @Configuration
@Import(FhirTesterMvcConfig.class) @Import(FhirTesterMvcConfig.class)
//@Conditional(FhirTesterConfigCondition.class) // @Conditional(FhirTesterConfigCondition.class)
public class FhirTesterConfig { public class FhirTesterConfig {
/** /**
@@ -36,22 +35,18 @@ public class FhirTesterConfig {
* deploying your server to a place with a fully qualified domain name, * deploying your server to a place with a fully qualified domain name,
* you might want to use that instead of using the variable. * you might want to use that instead of using the variable.
*/ */
@Bean @Bean
public TesterConfig testerConfig(AppProperties appProperties) { public TesterConfig testerConfig(AppProperties appProperties) {
TesterConfig retVal = new TesterConfig(); TesterConfig retVal = new TesterConfig();
appProperties.getTester().forEach((key, value) -> { appProperties.getTester().forEach((key, value) -> {
retVal retVal.addServer()
.addServer() .withId(key)
.withId(key) .withFhirVersion(value.getFhir_version())
.withFhirVersion(value.getFhir_version()) .withBaseUrl(value.getServer_address())
.withBaseUrl(value.getServer_address()) .withName(value.getName());
.withName(value.getName()); retVal.setRefuseToFetchThirdPartyUrls(value.getRefuse_to_fetch_third_party_urls());
retVal.setRefuseToFetchThirdPartyUrls( });
value.getRefuse_to_fetch_third_party_urls()); return retVal;
}
});
return retVal;
}
} }
//@formatter:on // @formatter:on

View File

@@ -9,8 +9,9 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
public class FhirTesterConfigCondition implements Condition { public class FhirTesterConfigCondition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { 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(); return !properties.isEmpty();
} }
} }

View File

@@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.starter.common; package ca.uhn.fhir.jpa.starter.common;
import ca.uhn.fhir.batch2.coordinator.JobDefinitionRegistry; 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.imprt.BulkDataImportProvider;
import ca.uhn.fhir.batch2.jobs.reindex.ReindexJobParameters; import ca.uhn.fhir.batch2.jobs.reindex.ReindexJobParameters;
import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider; 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.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.jpa.api.IDaoRegistry; import ca.uhn.fhir.jpa.api.IDaoRegistry;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; 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.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor; import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider; 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.HapiEntityManagerFactoryUtil;
import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil; import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil;
import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil; 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.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.packages.PackageInstallationSpec; import ca.uhn.fhir.jpa.packages.PackageInstallationSpec;
import ca.uhn.fhir.jpa.partition.PartitionManagementProvider; 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.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.*;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl; 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.OnCorsPresent;
import ca.uhn.fhir.jpa.starter.annotations.OnImplementationGuidesPresent; import ca.uhn.fhir.jpa.starter.annotations.OnImplementationGuidesPresent;
import ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory; 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.ig.IImplementationGuideOperationProvider;
import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper;
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain; 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.narrative2.NullNarrativeGenerator;
import ca.uhn.fhir.rest.api.IResourceSupportedSvc; import ca.uhn.fhir.rest.api.IResourceSupportedSvc;
import ca.uhn.fhir.rest.openapi.OpenApiInterceptor; 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.*;
import ca.uhn.fhir.rest.server.interceptor.*; 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.provider.ResourceProviderFactory;
import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy; import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; 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.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import java.util.*;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.*;
import static ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory.ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR; import static ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory.ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR;
@Configuration @Configuration
//allow users to configure custom packages to scan for additional beans // allow users to configure custom packages to scan for additional beans
@ComponentScan(basePackages = { "${hapi.fhir.custom-bean-packages:}" }) @ComponentScan(basePackages = {"${hapi.fhir.custom-bean-packages:}"})
@Import( @Import(ThreadPoolFactoryConfig.class)
ThreadPoolFactoryConfig.class
)
public class StarterJpaConfig { public class StarterJpaConfig {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StarterJpaConfig.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StarterJpaConfig.class);
@@ -107,12 +104,9 @@ public class StarterJpaConfig {
return ValidationSupportConfigUtil.newCachingValidationSupport(theJpaValidationSupportChain); return ValidationSupportConfigUtil.newCachingValidationSupport(theJpaValidationSupportChain);
} }
@Autowired @Autowired
private ConfigurableEnvironment configurableEnvironment; private ConfigurableEnvironment configurableEnvironment;
/** /**
* Customize the default/max page sizes for search results. You can set these however * 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. * you want, although very large page sizes will require a lot of RAM.
@@ -125,7 +119,6 @@ public class StarterJpaConfig {
return pagingProvider; return pagingProvider;
} }
@Bean @Bean
public IResourceSupportedSvc resourceSupportedSvc(IDaoRegistry theDaoRegistry) { public IResourceSupportedSvc resourceSupportedSvc(IDaoRegistry theDaoRegistry) {
return new DaoRegistryResourceSupportedSvc(theDaoRegistry); return new DaoRegistryResourceSupportedSvc(theDaoRegistry);
@@ -138,8 +131,12 @@ public class StarterJpaConfig {
@Primary @Primary
@Bean @Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource myDataSource, ConfigurableListableBeanFactory myConfigurableListableBeanFactory, FhirContext theFhirContext) { public LocalContainerEntityManagerFactoryBean entityManagerFactory(
LocalContainerEntityManagerFactoryBean retVal = HapiEntityManagerFactoryUtil.newEntityManagerFactory(myConfigurableListableBeanFactory, theFhirContext); DataSource myDataSource,
ConfigurableListableBeanFactory myConfigurableListableBeanFactory,
FhirContext theFhirContext) {
LocalContainerEntityManagerFactoryBean retVal =
HapiEntityManagerFactoryUtil.newEntityManagerFactory(myConfigurableListableBeanFactory, theFhirContext);
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
try { try {
@@ -147,7 +144,8 @@ public class StarterJpaConfig {
} catch (Exception e) { } catch (Exception e) {
throw new ConfigurationException("Could not set the data source due to a configuration issue", 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; return retVal;
} }
@@ -164,10 +162,10 @@ public class StarterJpaConfig {
return new HSearchSortHelperImpl(mySearchParamRegistry); return new HSearchSortHelperImpl(mySearchParamRegistry);
} }
@Bean @Bean
@ConditionalOnProperty(prefix = "hapi.fhir", name = ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR, havingValue = "true") @ConditionalOnProperty(prefix = "hapi.fhir", name = ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR, havingValue = "true")
public RepositoryValidatingInterceptor repositoryValidatingInterceptor(IRepositoryValidationInterceptorFactory factory) { public RepositoryValidatingInterceptor repositoryValidatingInterceptor(
IRepositoryValidationInterceptorFactory factory) {
return factory.buildUsingStoredStructureDefinitions(); return factory.buildUsingStoredStructureDefinitions();
} }
@@ -189,8 +187,11 @@ public class StarterJpaConfig {
@Bean("packageInstaller") @Bean("packageInstaller")
@Primary @Primary
@Conditional(OnImplementationGuidesPresent.class) @Conditional(OnImplementationGuidesPresent.class)
public IPackageInstallerSvc packageInstaller(AppProperties appProperties, JobDefinition<ReindexJobParameters> reindexJobParametersJobDefinition, JobDefinitionRegistry jobDefinitionRegistry, IPackageInstallerSvc packageInstallerSvc) public IPackageInstallerSvc packageInstaller(
{ AppProperties appProperties,
JobDefinition<ReindexJobParameters> reindexJobParametersJobDefinition,
JobDefinitionRegistry jobDefinitionRegistry,
IPackageInstallerSvc packageInstallerSvc) {
jobDefinitionRegistry.addJobDefinitionIfNotRegistered(reindexJobParametersJobDefinition); jobDefinitionRegistry.addJobDefinitionIfNotRegistered(reindexJobParametersJobDefinition);
if (appProperties.getImplementationGuides() != null) { if (appProperties.getImplementationGuides() != null) {
@@ -199,10 +200,11 @@ public class StarterJpaConfig {
PackageInstallationSpec packageInstallationSpec = guidesEntry.getValue(); PackageInstallationSpec packageInstallationSpec = guidesEntry.getValue();
if (appProperties.getInstall_transitive_ig_dependencies()) { if (appProperties.getInstall_transitive_ig_dependencies()) {
packageInstallationSpec.addDependencyExclude("hl7.fhir.r2.core") packageInstallationSpec
.addDependencyExclude("hl7.fhir.r3.core") .addDependencyExclude("hl7.fhir.r2.core")
.addDependencyExclude("hl7.fhir.r4.core") .addDependencyExclude("hl7.fhir.r3.core")
.addDependencyExclude("hl7.fhir.r5.core"); .addDependencyExclude("hl7.fhir.r4.core")
.addDependencyExclude("hl7.fhir.r5.core");
} }
packageInstallerSvc.install(packageInstallationSpec); packageInstallerSvc.install(packageInstallationSpec);
} }
@@ -238,11 +240,40 @@ public class StarterJpaConfig {
// Create the interceptor and register it // Create the interceptor and register it
return new CorsInterceptor(config); return new CorsInterceptor(config);
} }
@Bean @Bean
public RestfulServer restfulServer(IFhirSystemDao<?, ?> fhirSystemDao, AppProperties appProperties, DaoRegistry daoRegistry, Optional<MdmProviderLoader> mdmProviderProvider, IJpaSystemProvider jpaSystemProvider, ResourceProviderFactory resourceProviderFactory, JpaStorageSettings jpaStorageSettings, ISearchParamRegistry searchParamRegistry, IValidationSupport theValidationSupport, DatabaseBackedPagingProvider databaseBackedPagingProvider, LoggingInterceptor loggingInterceptor, Optional<TerminologyUploaderProvider> terminologyUploaderProvider, Optional<SubscriptionTriggeringProvider> subscriptionTriggeringProvider, Optional<CorsInterceptor> corsInterceptor, IInterceptorBroadcaster interceptorBroadcaster, Optional<BinaryAccessProvider> binaryAccessProvider, BinaryStorageInterceptor binaryStorageInterceptor, IValidatorModule validatorModule, Optional<GraphQLProvider> graphQLProvider, BulkDataExportProvider bulkDataExportProvider, BulkDataImportProvider bulkDataImportProvider, ValueSetOperationProvider theValueSetOperationProvider, ReindexProvider reindexProvider, PartitionManagementProvider partitionManagementProvider, Optional<RepositoryValidatingInterceptor> repositoryValidatingInterceptor, IPackageInstallerSvc packageInstallerSvc, ThreadSafeResourceDeleterSvc theThreadSafeResourceDeleterSvc, ApplicationContext appContext, Optional<IpsOperationProvider> theIpsOperationProvider, Optional<IImplementationGuideOperationProvider> implementationGuideOperationProvider) { public RestfulServer restfulServer(
IFhirSystemDao<?, ?> fhirSystemDao,
AppProperties appProperties,
DaoRegistry daoRegistry,
Optional<MdmProviderLoader> mdmProviderProvider,
IJpaSystemProvider jpaSystemProvider,
ResourceProviderFactory resourceProviderFactory,
JpaStorageSettings jpaStorageSettings,
ISearchParamRegistry searchParamRegistry,
IValidationSupport theValidationSupport,
DatabaseBackedPagingProvider databaseBackedPagingProvider,
LoggingInterceptor loggingInterceptor,
Optional<TerminologyUploaderProvider> terminologyUploaderProvider,
Optional<SubscriptionTriggeringProvider> subscriptionTriggeringProvider,
Optional<CorsInterceptor> corsInterceptor,
IInterceptorBroadcaster interceptorBroadcaster,
Optional<BinaryAccessProvider> binaryAccessProvider,
BinaryStorageInterceptor binaryStorageInterceptor,
IValidatorModule validatorModule,
Optional<GraphQLProvider> graphQLProvider,
BulkDataExportProvider bulkDataExportProvider,
BulkDataImportProvider bulkDataImportProvider,
ValueSetOperationProvider theValueSetOperationProvider,
ReindexProvider reindexProvider,
PartitionManagementProvider partitionManagementProvider,
Optional<RepositoryValidatingInterceptor> repositoryValidatingInterceptor,
IPackageInstallerSvc packageInstallerSvc,
ThreadSafeResourceDeleterSvc theThreadSafeResourceDeleterSvc,
ApplicationContext appContext,
Optional<IpsOperationProvider> theIpsOperationProvider,
Optional<IImplementationGuideOperationProvider> implementationGuideOperationProvider) {
RestfulServer fhirServer = new RestfulServer(fhirSystemDao.getContext()); RestfulServer fhirServer = new RestfulServer(fhirSystemDao.getContext());
List<String> supportedResourceTypes = appProperties.getSupported_resource_types(); List<String> supportedResourceTypes = appProperties.getSupported_resource_types();
@@ -264,7 +295,8 @@ public class StarterJpaConfig {
fhirServer.registerProviders(resourceProviderFactory.createProviders()); fhirServer.registerProviders(resourceProviderFactory.createProviders());
fhirServer.registerProvider(jpaSystemProvider); fhirServer.registerProvider(jpaSystemProvider);
fhirServer.setServerConformanceProvider(calculateConformanceProvider(fhirSystemDao, fhirServer, jpaStorageSettings, searchParamRegistry, theValidationSupport)); fhirServer.setServerConformanceProvider(calculateConformanceProvider(
fhirSystemDao, fhirServer, jpaStorageSettings, searchParamRegistry, theValidationSupport));
/* /*
* ETag Support * ETag Support
@@ -272,7 +304,6 @@ public class StarterJpaConfig {
if (!appProperties.getEtag_support_enabled()) fhirServer.setETagSupport(ETagSupportEnum.DISABLED); if (!appProperties.getEtag_support_enabled()) fhirServer.setETagSupport(ETagSupportEnum.DISABLED);
/* /*
* Default to JSON and pretty printing * Default to JSON and pretty printing
*/ */
@@ -318,7 +349,8 @@ public class StarterJpaConfig {
fhirServer.setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress)); fhirServer.setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress));
} else if (appProperties.getUse_apache_address_strategy()) { } else if (appProperties.getUse_apache_address_strategy()) {
boolean useHttps = appProperties.getUse_apache_address_strategy_https(); boolean useHttps = appProperties.getUse_apache_address_strategy_https();
fhirServer.setServerAddressStrategy(useHttps ? ApacheProxyAddressStrategy.forHttps() : ApacheProxyAddressStrategy.forHttp()); fhirServer.setServerAddressStrategy(
useHttps ? ApacheProxyAddressStrategy.forHttps() : ApacheProxyAddressStrategy.forHttp());
} else { } else {
fhirServer.setServerAddressStrategy(new IncomingRequestAddressStrategy()); fhirServer.setServerAddressStrategy(new IncomingRequestAddressStrategy());
} }
@@ -330,7 +362,11 @@ public class StarterJpaConfig {
* so it is a potential security vulnerability. Consider using an AuthorizationInterceptor * so it is a potential security vulnerability. Consider using an AuthorizationInterceptor
* with this feature. * 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()); fhirServer.registerProvider(terminologyUploaderProvider.get());
} }
@@ -348,7 +384,8 @@ public class StarterJpaConfig {
} }
if (appProperties.getAllow_cascading_deletes()) { 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); fhirServer.registerInterceptor(cascadingDeleteInterceptor);
} }
@@ -391,16 +428,15 @@ public class StarterJpaConfig {
fhirServer.registerProvider(bulkDataExportProvider); fhirServer.registerProvider(bulkDataExportProvider);
} }
//Bulk Import // Bulk Import
if (appProperties.getBulk_import_enabled()) { if (appProperties.getBulk_import_enabled()) {
fhirServer.registerProvider(bulkDataImportProvider); fhirServer.registerProvider(bulkDataImportProvider);
} }
// valueSet Operations i.e $expand // valueSet Operations i.e $expand
fhirServer.registerProvider(theValueSetOperationProvider); fhirServer.registerProvider(theValueSetOperationProvider);
//reindex Provider $reindex // reindex Provider $reindex
fhirServer.registerProvider(reindexProvider); fhirServer.registerProvider(reindexProvider);
// Partitioning // Partitioning
@@ -414,8 +450,7 @@ public class StarterJpaConfig {
// register custom interceptors // register custom interceptors
registerCustomInterceptors(fhirServer, appContext, appProperties.getCustomInterceptorClasses()); registerCustomInterceptors(fhirServer, appContext, appProperties.getCustomInterceptorClasses());
// register the IPS Provider
//register the IPS Provider
if (!theIpsOperationProvider.isEmpty()) { if (!theIpsOperationProvider.isEmpty()) {
fhirServer.registerProvider(theIpsOperationProvider.get()); fhirServer.registerProvider(theIpsOperationProvider.get());
} }
@@ -426,8 +461,9 @@ public class StarterJpaConfig {
/** /**
* check the properties for custom interceptor classes and registers them. * check the properties for custom interceptor classes and registers them.
*/ */
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({"unchecked", "rawtypes"})
private void registerCustomInterceptors(RestfulServer fhirServer, ApplicationContext theAppContext, List<String> customInterceptorClasses) { private void registerCustomInterceptors(
RestfulServer fhirServer, ApplicationContext theAppContext, List<String> customInterceptorClasses) {
if (customInterceptorClasses == null) { if (customInterceptorClasses == null) {
return; 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(); FhirVersionEnum fhirVersion = fhirSystemDao.getContext().getVersion().getVersion();
if (fhirVersion == FhirVersionEnum.DSTU2) { if (fhirVersion == FhirVersionEnum.DSTU2) {
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(fhirServer, fhirSystemDao, jpaStorageSettings); JpaConformanceProviderDstu2 confProvider =
new JpaConformanceProviderDstu2(fhirServer, fhirSystemDao, jpaStorageSettings);
confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server"); confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server");
return confProvider; return confProvider;
} else if (fhirVersion == FhirVersionEnum.DSTU3) { } 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"); confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server");
return confProvider; return confProvider;
} else if (fhirVersion == FhirVersionEnum.R4) { } 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"); confProvider.setImplementationDescription("HAPI FHIR R4 Server");
return confProvider; return confProvider;
} else if (fhirVersion == FhirVersionEnum.R4B) { } 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"); confProvider.setImplementationDescription("HAPI FHIR R4B Server");
return confProvider; return confProvider;
} else if (fhirVersion == FhirVersionEnum.R5) { } 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"); confProvider.setImplementationDescription("HAPI FHIR R5 Server");
return confProvider; return confProvider;
} else { } else {

View File

@@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingInterceptor;
public interface IRepositoryValidationInterceptorFactory { public interface IRepositoryValidationInterceptorFactory {
String ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR = "enable_repository_validating_interceptor"; String ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR = "enable_repository_validating_interceptor";
RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions(); RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions();
RepositoryValidatingInterceptor build(); RepositoryValidatingInterceptor build();

View File

@@ -37,24 +37,28 @@ public class RepositoryValidationInterceptorFactoryDstu3 implements IRepositoryV
private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder;
private final IFhirResourceDao structureDefinitionResourceProvider; private final IFhirResourceDao structureDefinitionResourceProvider;
public RepositoryValidationInterceptorFactoryDstu3(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { public RepositoryValidationInterceptorFactoryDstu3(
RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) {
this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder;
this.fhirContext = daoRegistry.getSystemDao().getContext(); this.fhirContext = daoRegistry.getSystemDao().getContext();
structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition");
} }
public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() {
IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); IBundleProvider results = structureDefinitionResourceProvider.search(
Map<String, List<StructureDefinition>> structureDefinitions = results.getResources(0, results.size()) new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource")));
.stream() Map<String, List<StructureDefinition>> structureDefinitions = results.getResources(0, results.size()).stream()
.map(StructureDefinition.class::cast) .map(StructureDefinition.class::cast)
.collect(Collectors.groupingBy(StructureDefinition::getType)); .collect(Collectors.groupingBy(StructureDefinition::getType));
structureDefinitions.forEach((key, value) -> { structureDefinitions.forEach((key, value) -> {
String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); 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<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> 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 // Customize the ruleBuilder here to have the rules you want! We will give a simple example
// of enabling validation for all Patient resources // 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 // Do not customize below this line
List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build();
return new RepositoryValidatingInterceptor(fhirContext, rules); return new RepositoryValidatingInterceptor(fhirContext, rules);
} }
} }

View File

@@ -37,25 +37,29 @@ public class RepositoryValidationInterceptorFactoryR4 implements IRepositoryVali
private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder;
private final IFhirResourceDao structureDefinitionResourceProvider; private final IFhirResourceDao structureDefinitionResourceProvider;
public RepositoryValidationInterceptorFactoryR4(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { public RepositoryValidationInterceptorFactoryR4(
RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) {
this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder;
this.fhirContext = daoRegistry.getSystemDao().getContext(); this.fhirContext = daoRegistry.getSystemDao().getContext();
structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition");
} }
@Override @Override
public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() {
IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); IBundleProvider results = structureDefinitionResourceProvider.search(
Map<String, List<StructureDefinition>> structureDefintions = results.getResources(0, results.size()) new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource")));
.stream() Map<String, List<StructureDefinition>> structureDefintions = results.getResources(0, results.size()).stream()
.map(StructureDefinition.class::cast) .map(StructureDefinition.class::cast)
.collect(Collectors.groupingBy(StructureDefinition::getType)); .collect(Collectors.groupingBy(StructureDefinition::getType));
structureDefintions.forEach((key, value) -> { structureDefintions.forEach((key, value) -> {
String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); 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<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> 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 // Customize the ruleBuilder here to have the rules you want! We will give a simple example
// of enabling validation for all Patient resources // 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 // Do not customize below this line
List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build();
return new RepositoryValidatingInterceptor(fhirContext, rules); return new RepositoryValidatingInterceptor(fhirContext, rules);
} }
} }

View File

@@ -37,25 +37,29 @@ public class RepositoryValidationInterceptorFactoryR4B implements IRepositoryVal
private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder;
private final IFhirResourceDao structureDefinitionResourceProvider; private final IFhirResourceDao structureDefinitionResourceProvider;
public RepositoryValidationInterceptorFactoryR4B(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { public RepositoryValidationInterceptorFactoryR4B(
RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) {
this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder;
this.fhirContext = daoRegistry.getSystemDao().getContext(); this.fhirContext = daoRegistry.getSystemDao().getContext();
structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition");
} }
@Override @Override
public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() {
IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); IBundleProvider results = structureDefinitionResourceProvider.search(
Map<String, List<StructureDefinition>> structureDefintions = results.getResources(0, results.size()) new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource")));
.stream() Map<String, List<StructureDefinition>> structureDefintions = results.getResources(0, results.size()).stream()
.map(StructureDefinition.class::cast) .map(StructureDefinition.class::cast)
.collect(Collectors.groupingBy(StructureDefinition::getType)); .collect(Collectors.groupingBy(StructureDefinition::getType));
structureDefintions.forEach((key, value) -> { structureDefintions.forEach((key, value) -> {
String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); 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<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> 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 // Customize the ruleBuilder here to have the rules you want! We will give a simple example
// of enabling validation for all Patient resources // 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 // Do not customize below this line
List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build();
return new RepositoryValidatingInterceptor(fhirContext, rules); return new RepositoryValidatingInterceptor(fhirContext, rules);
} }
} }

View File

@@ -37,24 +37,28 @@ public class RepositoryValidationInterceptorFactoryR5 implements IRepositoryVali
private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder; private final RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder;
private final IFhirResourceDao structureDefinitionResourceProvider; private final IFhirResourceDao structureDefinitionResourceProvider;
public RepositoryValidationInterceptorFactoryR5(RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) { public RepositoryValidationInterceptorFactoryR5(
RepositoryValidatingRuleBuilder repositoryValidatingRuleBuilder, DaoRegistry daoRegistry) {
this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder; this.repositoryValidatingRuleBuilder = repositoryValidatingRuleBuilder;
this.fhirContext = daoRegistry.getSystemDao().getContext(); this.fhirContext = daoRegistry.getSystemDao().getContext();
structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition"); structureDefinitionResourceProvider = daoRegistry.getResourceDao("StructureDefinition");
} }
public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() {
IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); IBundleProvider results = structureDefinitionResourceProvider.search(
Map<String, List<StructureDefinition>> structureDefintions = results.getResources(0, results.size()) new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource")));
.stream() Map<String, List<StructureDefinition>> structureDefintions = results.getResources(0, results.size()).stream()
.map(StructureDefinition.class::cast) .map(StructureDefinition.class::cast)
.collect(Collectors.groupingBy(StructureDefinition::getType)); .collect(Collectors.groupingBy(StructureDefinition::getType));
structureDefintions.forEach((key, value) -> { structureDefintions.forEach((key, value) -> {
String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); 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<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> 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 // Customize the ruleBuilder here to have the rules you want! We will give a simple example
// of enabling validation for all Patient resources // 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 // Do not customize below this line
List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build(); List<IRepositoryValidatingRule> rules = repositoryValidatingRuleBuilder.build();
return new RepositoryValidatingInterceptor(fhirContext, rules); return new RepositoryValidatingInterceptor(fhirContext, rules);
} }
} }

View File

@@ -10,5 +10,5 @@ public class CrConfigCondition implements Condition {
public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) {
String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cr.enabled"); String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.cr.enabled");
return Boolean.parseBoolean(property); return Boolean.parseBoolean(property);
} }
} }

View File

@@ -8,7 +8,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "hapi.fhir.cr") @ConfigurationProperties(prefix = "hapi.fhir.cr")
public class CrProperties { public class CrProperties {
private Boolean enabled; private Boolean enabled;
//cql settings // cql settings
private Boolean cql_use_embedded_libraries = true; private Boolean cql_use_embedded_libraries = true;
private Boolean cql_runtime_debug_logging_enabled = false; private Boolean cql_runtime_debug_logging_enabled = false;
private Boolean cql_runtime_enable_validation = false; private Boolean cql_runtime_enable_validation = false;
@@ -37,7 +37,7 @@ public class CrProperties {
// Care-gaps Settings // Care-gaps Settings
private String caregaps_reporter = "default"; private String caregaps_reporter = "default";
private String caregaps_section_author = "default"; private String caregaps_section_author = "default";
public Boolean getEnabled() { public Boolean getEnabled() {
return enabled; return enabled;
} }

View File

@@ -1,14 +1,13 @@
package ca.uhn.fhir.jpa.starter.cr; 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.RestfulServer;
import ca.uhn.fhir.rest.server.provider.IResourceProviderFactoryObserver; import ca.uhn.fhir.rest.server.provider.IResourceProviderFactoryObserver;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import java.util.function.Supplier;
public class PostInitProviderRegisterer { public class PostInitProviderRegisterer {
public PostInitProviderRegisterer(RestfulServer restfulServer, public PostInitProviderRegisterer(RestfulServer restfulServer, ResourceProviderFactory resourceProviderFactory) {
ResourceProviderFactory resourceProviderFactory) {
resourceProviderFactory.attach(new Observer(restfulServer)); resourceProviderFactory.attach(new Observer(restfulServer));
} }
@@ -30,7 +29,6 @@ public class PostInitProviderRegisterer {
} }
this.restfulServer.registerProvider(provider); this.restfulServer.registerProvider(provider);
} }
public void remove(Supplier<Object> theSupplier) { public void remove(Supplier<Object> theSupplier) {
@@ -45,7 +43,5 @@ public class PostInitProviderRegisterer {
this.restfulServer.unregisterProvider(provider); this.restfulServer.unregisterProvider(provider);
} }
} }
} }

View File

@@ -35,9 +35,9 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@Configuration @Configuration
@Conditional({ OnDSTU3Condition.class, CrConfigCondition.class }) @Conditional({OnDSTU3Condition.class, CrConfigCondition.class})
@Import({ @Import({
//BaseCrConfig.class, // BaseCrConfig.class,
CrDstu3Config.class, CrDstu3Config.class,
ApplyOperationConfig.class, ApplyOperationConfig.class,
ExtractOperationConfig.class, ExtractOperationConfig.class,
@@ -48,11 +48,12 @@ public class StarterCrDstu3Config {
private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrDstu3Config.class); private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrDstu3Config.class);
@Bean @Bean
MeasureEvaluationOptions measureEvaluationOptions(EvaluationSettings theEvaluationSettings, Map<String, ValidationProfile> theValidationProfiles){ MeasureEvaluationOptions measureEvaluationOptions(
EvaluationSettings theEvaluationSettings, Map<String, ValidationProfile> theValidationProfiles) {
MeasureEvaluationOptions measureEvalOptions = new MeasureEvaluationOptions(); MeasureEvaluationOptions measureEvalOptions = new MeasureEvaluationOptions();
measureEvalOptions.setEvaluationSettings(theEvaluationSettings); measureEvalOptions.setEvaluationSettings(theEvaluationSettings);
if(measureEvalOptions.isValidationEnabled()) { if (measureEvalOptions.isValidationEnabled()) {
measureEvalOptions.setValidationProfiles(theValidationProfiles); measureEvalOptions.setValidationProfiles(theValidationProfiles);
} }
return measureEvalOptions; return measureEvalOptions;
@@ -60,10 +61,10 @@ public class StarterCrDstu3Config {
@Bean @Bean
public EvaluationSettings evaluationSettings( public EvaluationSettings evaluationSettings(
CrProperties theCrProperties, CrProperties theCrProperties,
Map<VersionedIdentifier, CompiledLibrary> theGlobalLibraryCache, Map<VersionedIdentifier, CompiledLibrary> theGlobalLibraryCache,
Map<ModelIdentifier, Model> theGlobalModelCache, Map<ModelIdentifier, Model> theGlobalModelCache,
Map<String, List<Code>> theGlobalValueSetCache) { Map<String, List<Code>> theGlobalValueSetCache) {
var evaluationSettings = EvaluationSettings.getDefault(); var evaluationSettings = EvaluationSettings.getDefault();
var cqlOptions = evaluationSettings.getCqlOptions(); var cqlOptions = evaluationSettings.getCqlOptions();
@@ -135,9 +136,10 @@ public class StarterCrDstu3Config {
} }
@Bean @Bean
public PostInitProviderRegisterer postInitProviderRegisterer(RestfulServer theRestfulServer, public PostInitProviderRegisterer postInitProviderRegisterer(
ResourceProviderFactory theResourceProviderFactory) { RestfulServer theRestfulServer, ResourceProviderFactory theResourceProviderFactory) {
return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory);} return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory);
}
@Bean @Bean
public CrProperties crProperties() { public CrProperties crProperties() {
@@ -161,26 +163,27 @@ public class StarterCrDstu3Config {
@Bean @Bean
public ElmCacheResourceChangeListener elmCacheResourceChangeListener( public ElmCacheResourceChangeListener elmCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry, IResourceChangeListenerRegistry theResourceChangeListenerRegistry,
DaoRegistry theDaoRegistry, DaoRegistry theDaoRegistry,
EvaluationSettings theEvaluationSettings) { EvaluationSettings theEvaluationSettings) {
ElmCacheResourceChangeListener listener = ElmCacheResourceChangeListener listener =
new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache()); new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache());
theResourceChangeListenerRegistry.registerResourceResourceChangeListener( theResourceChangeListenerRegistry.registerResourceResourceChangeListener(
"Library", SearchParameterMap.newSynchronous(), listener, 1000); "Library", SearchParameterMap.newSynchronous(), listener, 1000);
return listener; return listener;
} }
@Bean @Bean
public CodeCacheResourceChangeListener codeCacheResourceChangeListener( public CodeCacheResourceChangeListener codeCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry, IResourceChangeListenerRegistry theResourceChangeListenerRegistry,
EvaluationSettings theEvaluationSettings, EvaluationSettings theEvaluationSettings,
DaoRegistry theDaoRegistry) { DaoRegistry theDaoRegistry) {
CodeCacheResourceChangeListener listener = new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache()); CodeCacheResourceChangeListener listener =
//registry new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache());
// registry
theResourceChangeListenerRegistry.registerResourceResourceChangeListener( theResourceChangeListenerRegistry.registerResourceResourceChangeListener(
"ValueSet", SearchParameterMap.newSynchronous(), listener,1000); "ValueSet", SearchParameterMap.newSynchronous(), listener, 1000);
return listener; return listener;
} }

View File

@@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.starter.cr; package ca.uhn.fhir.jpa.starter.cr;
import ca.uhn.fhir.cr.common.CodeCacheResourceChangeListener; 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.common.ElmCacheResourceChangeListener;
import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig; import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig;
import ca.uhn.fhir.cr.config.r4.CrR4Config; 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.jpa.starter.annotations.OnR4Condition;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; 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.CqlCompilerOptions;
import org.cqframework.cql.cql2elm.model.CompiledLibrary; import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.cqframework.cql.cql2elm.model.Model; import org.cqframework.cql.cql2elm.model.Model;
@@ -45,7 +44,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@Configuration @Configuration
@Conditional({ OnR4Condition.class, CrConfigCondition.class }) @Conditional({OnR4Condition.class, CrConfigCondition.class})
@Import({ @Import({
CrR4Config.class, CrR4Config.class,
ApplyOperationConfig.class, ApplyOperationConfig.class,
@@ -60,16 +59,14 @@ public class StarterCrR4Config {
@Bean @Bean
public ExecutorService cqlExecutor() { public ExecutorService cqlExecutor() {
CqlThreadFactory factory = new CqlThreadFactory(); CqlThreadFactory factory = new CqlThreadFactory();
ExecutorService executor = Executors. ExecutorService executor = Executors.newFixedThreadPool(2, factory);
newFixedThreadPool(2
, factory);
executor = new DelegatingSecurityContextExecutorService(executor); executor = new DelegatingSecurityContextExecutorService(executor);
return executor; return executor;
} }
@Bean @Bean
CareGapsProperties careGapsProperties(CrProperties theCrProperties) { CareGapsProperties careGapsProperties(CrProperties theCrProperties) {
var careGapsProperties = new CareGapsProperties(); var careGapsProperties = new CareGapsProperties();
careGapsProperties.setThreadedCareGapsEnabled(false); careGapsProperties.setThreadedCareGapsEnabled(false);
careGapsProperties.setCareGapsReporter(theCrProperties.getCareGapsReporter()); careGapsProperties.setCareGapsReporter(theCrProperties.getCareGapsReporter());
@@ -78,10 +75,11 @@ public class StarterCrR4Config {
} }
@Bean @Bean
MeasureEvaluationOptions measureEvaluationOptions(EvaluationSettings theEvaluationSettings, Map<String, ValidationProfile> theValidationProfiles){ MeasureEvaluationOptions measureEvaluationOptions(
EvaluationSettings theEvaluationSettings, Map<String, ValidationProfile> theValidationProfiles) {
MeasureEvaluationOptions measureEvalOptions = new MeasureEvaluationOptions(); MeasureEvaluationOptions measureEvalOptions = new MeasureEvaluationOptions();
measureEvalOptions.setEvaluationSettings(theEvaluationSettings); measureEvalOptions.setEvaluationSettings(theEvaluationSettings);
if(measureEvalOptions.isValidationEnabled()) { if (measureEvalOptions.isValidationEnabled()) {
measureEvalOptions.setValidationProfiles(theValidationProfiles); measureEvalOptions.setValidationProfiles(theValidationProfiles);
} }
return measureEvalOptions; return measureEvalOptions;
@@ -89,10 +87,10 @@ public class StarterCrR4Config {
@Bean @Bean
public EvaluationSettings evaluationSettings( public EvaluationSettings evaluationSettings(
CrProperties theCrProperties, CrProperties theCrProperties,
Map<VersionedIdentifier, CompiledLibrary> theGlobalLibraryCache, Map<VersionedIdentifier, CompiledLibrary> theGlobalLibraryCache,
Map<ModelIdentifier, Model> theGlobalModelCache, Map<ModelIdentifier, Model> theGlobalModelCache,
Map<String, List<Code>> theGlobalValueSetCache) { Map<String, List<Code>> theGlobalValueSetCache) {
var evaluationSettings = EvaluationSettings.getDefault(); var evaluationSettings = EvaluationSettings.getDefault();
var cqlOptions = evaluationSettings.getCqlOptions(); var cqlOptions = evaluationSettings.getCqlOptions();
@@ -164,8 +162,8 @@ public class StarterCrR4Config {
} }
@Bean @Bean
public PostInitProviderRegisterer postInitProviderRegisterer(RestfulServer theRestfulServer, public PostInitProviderRegisterer postInitProviderRegisterer(
ResourceProviderFactory theResourceProviderFactory) { RestfulServer theRestfulServer, ResourceProviderFactory theResourceProviderFactory) {
return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory); return new PostInitProviderRegisterer(theRestfulServer, theResourceProviderFactory);
} }
@@ -191,26 +189,27 @@ public class StarterCrR4Config {
@Bean @Bean
public ElmCacheResourceChangeListener elmCacheResourceChangeListener( public ElmCacheResourceChangeListener elmCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry, IResourceChangeListenerRegistry theResourceChangeListenerRegistry,
DaoRegistry theDaoRegistry, DaoRegistry theDaoRegistry,
EvaluationSettings theEvaluationSettings) { EvaluationSettings theEvaluationSettings) {
ElmCacheResourceChangeListener listener = ElmCacheResourceChangeListener listener =
new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache()); new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache());
theResourceChangeListenerRegistry.registerResourceResourceChangeListener( theResourceChangeListenerRegistry.registerResourceResourceChangeListener(
"Library", SearchParameterMap.newSynchronous(), listener, 1000); "Library", SearchParameterMap.newSynchronous(), listener, 1000);
return listener; return listener;
} }
@Bean @Bean
public CodeCacheResourceChangeListener codeCacheResourceChangeListener( public CodeCacheResourceChangeListener codeCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry, IResourceChangeListenerRegistry theResourceChangeListenerRegistry,
EvaluationSettings theEvaluationSettings, EvaluationSettings theEvaluationSettings,
DaoRegistry theDaoRegistry) { DaoRegistry theDaoRegistry) {
CodeCacheResourceChangeListener listener = new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache()); CodeCacheResourceChangeListener listener =
//registry new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache());
// registry
theResourceChangeListenerRegistry.registerResourceResourceChangeListener( theResourceChangeListenerRegistry.registerResourceResourceChangeListener(
"ValueSet", SearchParameterMap.newSynchronous(), listener,1000); "ValueSet", SearchParameterMap.newSynchronous(), listener, 1000);
return listener; return listener;
} }
@@ -219,5 +218,4 @@ public class StarterCrR4Config {
public ResourceChangeListenerRegistryInterceptor resourceChangeListenerRegistryInterceptor() { public ResourceChangeListenerRegistryInterceptor resourceChangeListenerRegistryInterceptor() {
return new ResourceChangeListenerRegistryInterceptor(); return new ResourceChangeListenerRegistryInterceptor();
} }
} }

View File

@@ -9,10 +9,16 @@ import java.io.IOException;
public interface IImplementationGuideOperationProvider { public interface IImplementationGuideOperationProvider {
static PackageInstallationSpec toPackageInstallationSpec(byte[] npmPackageAsByteArray) throws IOException { static PackageInstallationSpec toPackageInstallationSpec(byte[] npmPackageAsByteArray) throws IOException {
NpmPackage npmPackage = NpmPackage.fromPackage(new ByteArrayInputStream(npmPackageAsByteArray)); 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 // The following declaration is the one that counts but cannot be used across different versions as stating
//@Operation(name = "$install", typeName = "ImplementationGuide") // Base64BinaryType would bind to a separate version
//Parameters install(@OperationParam(name = "npmContent",min = 1, max = 1) Base64BinaryType implementationGuide); // @Operation(name = "$install", typeName = "ImplementationGuide")
// Parameters install(@OperationParam(name = "npmContent",min = 1, max = 1) Base64BinaryType implementationGuide);
} }

View File

@@ -22,14 +22,15 @@ public class ImplementationGuideR4OperationProvider implements IImplementationGu
} }
@Operation(name = "$install", typeName = "ImplementationGuide") @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 { try {
packageInstallerSvc.install(IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue())); packageInstallerSvc.install(
IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue()));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return new Parameters(); return new Parameters();
} }
} }

View File

@@ -22,15 +22,15 @@ public class ImplementationGuideR5OperationProvider {
} }
@Operation(name = "$install", typeName = "ImplementationGuide") @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 { try {
packageInstallerSvc.install(IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue())); packageInstallerSvc.install(
IImplementationGuideOperationProvider.toPackageInstallationSpec(implementationGuide.getValue()));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return new Parameters(); return new Parameters();
} }
} }

View File

@@ -7,8 +7,8 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
public class IpsConfigCondition implements Condition { public class IpsConfigCondition implements Condition {
@Override @Override
public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) { public boolean matches(ConditionContext theConditionContext, AnnotatedTypeMetadata theAnnotatedTypeMetadata) {
String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.ips_enabled"); String property = theConditionContext.getEnvironment().getProperty("hapi.fhir.ips_enabled");
return Boolean.parseBoolean(property); return Boolean.parseBoolean(property);
} }
} }

View File

@@ -1,34 +1,30 @@
package ca.uhn.fhir.jpa.starter.ips; package ca.uhn.fhir.jpa.starter.ips;
import org.springframework.context.annotation.Bean;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy; 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 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.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) @Conditional(IpsConfigCondition.class)
public class StarterIpsConfig { public class StarterIpsConfig {
@Bean @Bean
IIpsGenerationStrategy ipsGenerationStrategy() IIpsGenerationStrategy ipsGenerationStrategy() {
{
return new DefaultIpsGenerationStrategy(); return new DefaultIpsGenerationStrategy();
} }
@Bean @Bean
public IpsOperationProvider ipsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc){ public IpsOperationProvider ipsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc) {
return new IpsOperationProvider(theIpsGeneratorSvc); return new IpsOperationProvider(theIpsGeneratorSvc);
} }
@Bean @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); return new IpsGeneratorSvcImpl(theFhirContext, theGenerationStrategy, theDaoRegistry);
} }
} }

View File

@@ -24,10 +24,13 @@ import java.nio.charset.StandardCharsets;
public class MdmConfig { public class MdmConfig {
@Bean @Bean
IMdmSettings mdmSettings(@Autowired MdmRuleValidator theMdmRuleValidator, AppProperties appProperties) throws IOException { IMdmSettings mdmSettings(@Autowired MdmRuleValidator theMdmRuleValidator, AppProperties appProperties)
throws IOException {
DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("mdm-rules.json"); Resource resource = resourceLoader.getResource("mdm-rules.json");
String json = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8); 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);
} }
} }

View File

@@ -5,9 +5,9 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
public class MdmConfigCondition implements Condition { public class MdmConfigCondition implements Condition {
@Override @Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
String property = conditionContext.getEnvironment().getProperty("hapi.fhir.mdm_enabled"); String property = conditionContext.getEnvironment().getProperty("hapi.fhir.mdm_enabled");
return Boolean.parseBoolean(property); return Boolean.parseBoolean(property);
} }
} }

View File

@@ -31,8 +31,8 @@ import static java.util.Objects.requireNonNullElse;
public class EnvironmentHelper { public class EnvironmentHelper {
public static Properties getHibernateProperties(ConfigurableEnvironment environment, public static Properties getHibernateProperties(
ConfigurableListableBeanFactory myConfigurableListableBeanFactory) { ConfigurableEnvironment environment, ConfigurableListableBeanFactory myConfigurableListableBeanFactory) {
Properties properties = new Properties(); Properties properties = new Properties();
Map<String, Object> jpaProps = getPropertiesStartingWith(environment, "spring.jpa.properties"); Map<String, Object> jpaProps = getPropertiesStartingWith(environment, "spring.jpa.properties");
for (Map.Entry<String, Object> entry : jpaProps.entrySet()) { for (Map.Entry<String, Object> entry : jpaProps.entrySet()) {
@@ -40,18 +40,23 @@ public class EnvironmentHelper {
properties.put(strippedKey, entry.getValue().toString()); 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.SCANNER, "org.hibernate.boot.archive.scan.internal.DisabledScanner");
properties.putIfAbsent(AvailableSettings.IMPLICIT_NAMING_STRATEGY, SpringImplicitNamingStrategy.class.getName()); properties.putIfAbsent(
properties.putIfAbsent(AvailableSettings.PHYSICAL_NAMING_STRATEGY, CamelCaseToUnderscoresNamingStrategy.class.getName()); AvailableSettings.IMPLICIT_NAMING_STRATEGY, SpringImplicitNamingStrategy.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(
//properties.putIfAbsent(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(beanFactory)); 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" // hapi-fhir-jpaserver-base "sensible defaults"
Map<String, Object> hapiJpaPropertyMap = new HapiFhirLocalContainerEntityManagerFactoryBean(myConfigurableListableBeanFactory).getJpaPropertyMap(); Map<String, Object> hapiJpaPropertyMap = new HapiFhirLocalContainerEntityManagerFactoryBean(
myConfigurableListableBeanFactory)
.getJpaPropertyMap();
hapiJpaPropertyMap.forEach(properties::putIfAbsent); hapiJpaPropertyMap.forEach(properties::putIfAbsent);
//hapi-fhir-jpaserver-starter defaults // hapi-fhir-jpaserver-starter defaults
properties.putIfAbsent(AvailableSettings.FORMAT_SQL, false); properties.putIfAbsent(AvailableSettings.FORMAT_SQL, false);
properties.putIfAbsent(AvailableSettings.SHOW_SQL, false); properties.putIfAbsent(AvailableSettings.SHOW_SQL, false);
properties.putIfAbsent(AvailableSettings.HBM2DDL_AUTO, "update"); properties.putIfAbsent(AvailableSettings.HBM2DDL_AUTO, "update");
@@ -61,43 +66,60 @@ public class EnvironmentHelper {
properties.putIfAbsent(AvailableSettings.USE_STRUCTURED_CACHE, false); properties.putIfAbsent(AvailableSettings.USE_STRUCTURED_CACHE, false);
properties.putIfAbsent(AvailableSettings.USE_MINIMAL_PUTS, false); properties.putIfAbsent(AvailableSettings.USE_MINIMAL_PUTS, false);
//Hibernate Search defaults // Hibernate Search defaults
properties.putIfAbsent(HibernateOrmMapperSettings.ENABLED, false); properties.putIfAbsent(HibernateOrmMapperSettings.ENABLED, false);
if (Boolean.parseBoolean(String.valueOf(properties.get(HibernateOrmMapperSettings.ENABLED)))) { if (Boolean.parseBoolean(String.valueOf(properties.get(HibernateOrmMapperSettings.ENABLED)))) {
if (isElasticsearchEnabled(environment)) { if (isElasticsearchEnabled(environment)) {
properties.putIfAbsent(BackendSettings.backendKey(BackendSettings.TYPE), ElasticsearchBackendSettings.TYPE_NAME); properties.putIfAbsent(
BackendSettings.backendKey(BackendSettings.TYPE), ElasticsearchBackendSettings.TYPE_NAME);
} else { } 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)) { if (properties
properties.putIfAbsent(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE), LocalFileSystemDirectoryProvider.NAME); .get(BackendSettings.backendKey(BackendSettings.TYPE))
properties.putIfAbsent(BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), "target/lucenefiles"); .equals(LuceneBackendSettings.TYPE_NAME)) {
properties.putIfAbsent(BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER), properties.putIfAbsent(
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName()); BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE),
properties.putIfAbsent(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), Version.LATEST); 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(); 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.setRequiredIndexStatus(requireNonNullElse(requiredIndexStatus, IndexStatus.YELLOW));
builder.setHosts(getElasticsearchServerUrl(environment)); builder.setHosts(getElasticsearchServerUrl(environment));
builder.setUsername(getElasticsearchServerUsername(environment)); builder.setUsername(getElasticsearchServerUsername(environment));
builder.setPassword(getElasticsearchServerPassword(environment)); builder.setPassword(getElasticsearchServerPassword(environment));
builder.setProtocol(getElasticsearchServerProtocol(environment)); builder.setProtocol(getElasticsearchServerProtocol(environment));
SchemaManagementStrategyName indexSchemaManagementStrategy = environment.getProperty("elasticsearch.schema_management_strategy", SchemaManagementStrategyName.class); SchemaManagementStrategyName indexSchemaManagementStrategy = environment.getProperty(
builder.setIndexSchemaManagementStrategy(requireNonNullElse(indexSchemaManagementStrategy, SchemaManagementStrategyName.CREATE)); "elasticsearch.schema_management_strategy", SchemaManagementStrategyName.class);
Boolean refreshAfterWrite = environment.getProperty("elasticsearch.debug.refresh_after_write", Boolean.class); builder.setIndexSchemaManagementStrategy(
requireNonNullElse(indexSchemaManagementStrategy, SchemaManagementStrategyName.CREATE));
Boolean refreshAfterWrite =
environment.getProperty("elasticsearch.debug.refresh_after_write", Boolean.class);
if (refreshAfterWrite == null || !refreshAfterWrite) { if (refreshAfterWrite == null || !refreshAfterWrite) {
builder.setDebugIndexSyncStrategy(AutomaticIndexingSynchronizationStrategyNames.ASYNC); builder.setDebugIndexSyncStrategy(AutomaticIndexingSynchronizationStrategyNames.ASYNC);
} else { } else {
builder.setDebugIndexSyncStrategy(AutomaticIndexingSynchronizationStrategyNames.READ_SYNC); 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); builder.apply(properties);
} else { } 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<String, Object> getPropertiesStartingWith(ConfigurableEnvironment aEnv, public static Map<String, Object> getPropertiesStartingWith(ConfigurableEnvironment aEnv, String aKeyPrefix) {
String aKeyPrefix) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
Map<String, Object> map = getAllProperties(aEnv); Map<String, Object> map = getAllProperties(aEnv);
@@ -167,7 +188,6 @@ public class EnvironmentHelper {
} }
return result; return result;
} }
private static void addAll(Map<String, Object> aBase, Map<String, Object> aToBeAdded) { private static void addAll(Map<String, Object> aBase, Map<String, Object> aToBeAdded) {

View File

@@ -7,27 +7,26 @@ import org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver;
import org.hibernate.engine.jdbc.dialect.spi.DatabaseMetaDataDialectResolutionInfoAdapter; import org.hibernate.engine.jdbc.dialect.spi.DatabaseMetaDataDialectResolutionInfoAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import javax.sql.DataSource;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import javax.sql.DataSource;
public class JpaHibernatePropertiesProvider extends HibernatePropertiesProvider { public class JpaHibernatePropertiesProvider extends HibernatePropertiesProvider {
private final Dialect dialect; private final Dialect dialect;
public JpaHibernatePropertiesProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { public JpaHibernatePropertiesProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) {
DataSource connection = myEntityManagerFactory.getDataSource(); DataSource connection = myEntityManagerFactory.getDataSource();
try ( Connection dbConnection = connection.getConnection()){ try (Connection dbConnection = connection.getConnection()) {
dialect = new StandardDialectResolver() dialect = new StandardDialectResolver()
.resolveDialect(new DatabaseMetaDataDialectResolutionInfoAdapter(dbConnection.getMetaData())); .resolveDialect(new DatabaseMetaDataDialectResolutionInfoAdapter(dbConnection.getMetaData()));
} catch (SQLException sqlException) { } catch (SQLException sqlException) {
throw new ConfigurationException(sqlException.getMessage(), sqlException); throw new ConfigurationException(sqlException.getMessage(), sqlException);
} }
} }
@Override @Override
public Dialect getDialect() { public Dialect getDialect() {
return dialect; return dialect;
} }
} }