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

@@ -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;
@@ -81,7 +79,8 @@ public class AppProperties {
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;

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,8 +29,8 @@ 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,
@@ -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,16 +19,13 @@ 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 @Override
public void addResourceHandlers(ResourceHandlerRegistry theRegistry) { public void addResourceHandlers(ResourceHandlerRegistry theRegistry) {
theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation); theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation);
@@ -39,13 +36,15 @@ public class ExtraStaticFilesConfigurer implements WebMvcConfigurer {
String path = URI.create(staticLocation).getPath(); String path = URI.create(staticLocation).getPath();
String lastSegment = path.substring(path.lastIndexOf('/') + 1); String lastSegment = path.substring(path.lastIndexOf('/') + 1);
registry.addViewController(rootContextPath).setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); registry.addViewController(rootContextPath)
.setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html");
registry.addViewController(rootContextPath + "/*").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); registry.addViewController(rootContextPath + "/*")
.setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html");
registry.addViewController(rootContextPath + "/" + lastSegment + "/").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); registry.addViewController(rootContextPath + "/" + lastSegment + "/")
.setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE); registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
} }
} }

View File

@@ -10,7 +10,9 @@ 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

@@ -8,12 +8,11 @@ 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

@@ -8,12 +8,11 @@ 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

@@ -17,23 +17,17 @@ public class OnEitherVersion extends AnyNestedCondition {
} }
@Conditional(OnDSTU2Condition.class) @Conditional(OnDSTU2Condition.class)
static class OnDSTU2 { static class OnDSTU2 {}
}
@Conditional(OnDSTU3Condition.class) @Conditional(OnDSTU3Condition.class)
static class OnDSTU3 { static class OnDSTU3 {}
}
@Conditional(OnR4Condition.class) @Conditional(OnR4Condition.class)
static class OnR4 { static class OnR4 {}
}
@Conditional(OnR4BCondition.class) @Conditional(OnR4BCondition.class)
static class OnR4B { static class OnR4B {}
}
@Conditional(OnR5Condition.class) @Conditional(OnR5Condition.class)
static class OnR5 { static class OnR5 {}
}
} }

View File

@@ -10,7 +10,9 @@ 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,8 +8,8 @@ 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();

View File

@@ -8,12 +8,11 @@ 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

@@ -8,12 +8,11 @@ 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

@@ -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,21 +1,20 @@
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.
@@ -35,7 +34,8 @@ public class ErrorHandling {
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()
.println(
"Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access."); "Ensure that the fhirAuthorization token is set or that the remote server allows unauthenticated access.");
response.setStatus(412); response.setStatus(412);
break; break;
@@ -69,14 +69,28 @@ public class ErrorHandling {
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()
.findFirst()
.get());
resp.setHeader(
"Access-Control-Allow-Methods",
String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS"))); String.join(", ", Arrays.asList("GET", "HEAD", "POST", "OPTIONS")));
resp.setHeader("Access-Control-Allow-Headers", resp.setHeader(
String.join(", ", Arrays.asList("x-fhir-starter", "Origin", "Access-Control-Allow-Headers",
"Accept", "X-Requested-With", "Content-Type", "Authorization", "Cache-Control"))); String.join(
resp.setHeader("Access-Control-Expose-Headers", ", ",
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"))); String.join(", ", Arrays.asList("Location", "Content-Location")));
resp.setHeader("Access-Control-Max-Age", "86400"); resp.setHeader("Access-Control-Max-Age", "86400");
} }

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;
@@ -40,20 +36,33 @@ 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()
? StorageSettings.IndexEnabledEnum.ENABLED
: StorageSettings.IndexEnabledEnum.DISABLED);
jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(
appProperties.getAuto_create_placeholder_reference_targets());
jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths());
jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write()); jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(
jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete()); appProperties.getEnforce_referential_integrity_on_write());
jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(
appProperties.getEnforce_referential_integrity_on_delete());
jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches());
jpaStorageSettings.setAllowMultipleDelete(appProperties.getAllow_multiple_delete()); jpaStorageSettings.setAllowMultipleDelete(appProperties.getAllow_multiple_delete());
jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references());
jpaStorageSettings.setSchedulingDisabled(!appProperties.getDao_scheduling_enabled()); jpaStorageSettings.setSchedulingDisabled(!appProperties.getDao_scheduling_enabled());
jpaStorageSettings.setDeleteExpungeEnabled(appProperties.getDelete_expunge_enabled()); jpaStorageSettings.setDeleteExpungeEnabled(appProperties.getDelete_expunge_enabled());
jpaStorageSettings.setExpungeEnabled(appProperties.getExpunge_enabled()); jpaStorageSettings.setExpungeEnabled(appProperties.getExpunge_enabled());
if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) if (appProperties.getSubscription() != null
jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); && 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");
@@ -138,7 +155,7 @@ public class FhirServerConfigCommon {
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());
} }
@@ -146,20 +163,20 @@ public class FhirServerConfigCommon {
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) { if (appProperties.getAllowed_bundle_types() != null) {
jpaStorageSettings.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet())); jpaStorageSettings.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream()
.map(BundleType::toCode)
.collect(Collectors.toSet()));
} }
jpaStorageSettings.setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size()); jpaStorageSettings.setDeferIndexingForCodesystemsOfSize(
appProperties.getDefer_indexing_for_codesystems_of_size());
if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) { if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) {
jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID); jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID);
jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy());
} }
//Parallel Batch GET execution settings // Parallel Batch GET execution settings
jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size()); jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size());
jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size()); jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size());
@@ -179,8 +196,9 @@ public class FhirServerConfigCommon {
// Partitioning // Partitioning
if (appProperties.getPartitioning() != null) { if (appProperties.getPartitioning() != null) {
retVal.setPartitioningEnabled(true); retVal.setPartitioningEnabled(true);
retVal.setIncludePartitionInSearchHashes(appProperties.getPartitioning().getPartitioning_include_in_search_hashes()); retVal.setIncludePartitionInSearchHashes(
if(appProperties.getPartitioning().getAllow_references_across_partitions()) { appProperties.getPartitioning().getPartitioning_include_in_search_hashes());
if (appProperties.getPartitioning().getAllow_references_across_partitions()) {
retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED); retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED);
} else { } else {
retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED); retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED);
@@ -190,20 +208,22 @@ public class FhirServerConfigCommon {
return retVal; return retVal;
} }
@Primary @Primary
@Bean @Bean
public HibernatePropertiesProvider jpaStarterDialectProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { public HibernatePropertiesProvider jpaStarterDialectProvider(
LocalContainerEntityManagerFactoryBean myEntityManagerFactory) {
return new JpaHibernatePropertiesProvider(myEntityManagerFactory); return new JpaHibernatePropertiesProvider(myEntityManagerFactory);
} }
protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) { protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) {
jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches());
jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references());
jpaStorageSettings.setDefaultSearchParamsCanBeOverridden(appProperties.getAllow_override_default_search_params()); jpaStorageSettings.setDefaultSearchParamsCanBeOverridden(
if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) appProperties.getAllow_override_default_search_params());
jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); if (appProperties.getSubscription() != null
&& appProperties.getSubscription().getEmail() != null)
jpaStorageSettings.setEmailFromAddress(
appProperties.getSubscription().getEmail().getFrom());
jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level());
@@ -226,13 +246,15 @@ public class FhirServerConfigCommon {
@Bean @Bean
public IEmailSender emailSender(AppProperties appProperties) { public IEmailSender emailSender(AppProperties appProperties) {
if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) { if (appProperties.getSubscription() != null
&& appProperties.getSubscription().getEmail() != null) {
return buildEmailSender(appProperties.getSubscription().getEmail()); return buildEmailSender(appProperties.getSubscription().getEmail());
} }
// Return a dummy anonymous function instead of null. Spring does not like null beans. // 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 // TODO Get the signature of
// ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory
// changed so it does not require an instance of an IEmailSender // changed so it does not require an instance of an IEmailSender
return theDetails -> {}; return theDetails -> {};
} }

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 {
/** /**
@@ -40,18 +39,14 @@ public class FhirTesterConfig {
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( retVal.setRefuseToFetchThirdPartyUrls(value.getRefuse_to_fetch_third_party_urls());
value.getRefuse_to_fetch_third_party_urls());
}); });
return retVal; return retVal;
} }
} }
//@formatter:on // @formatter:on

View File

@@ -10,7 +10,8 @@ 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,7 +200,8 @@ 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.r2.core")
.addDependencyExclude("hl7.fhir.r3.core") .addDependencyExclude("hl7.fhir.r3.core")
.addDependencyExclude("hl7.fhir.r4.core") .addDependencyExclude("hl7.fhir.r4.core")
.addDependencyExclude("hl7.fhir.r5.core"); .addDependencyExclude("hl7.fhir.r5.core");
@@ -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

@@ -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;

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;
@@ -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() {
@@ -177,10 +179,11 @@ public class StarterCrDstu3Config {
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,9 +59,7 @@ 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;
@@ -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;
@@ -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);
} }
@@ -207,10 +205,11 @@ public class StarterCrR4Config {
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

@@ -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

@@ -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(
BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_TYPE),
LocalFileSystemDirectoryProvider.NAME);
properties.putIfAbsent(
BackendSettings.backendKey(LuceneIndexSettings.DIRECTORY_ROOT), "target/lucenefiles");
properties.putIfAbsent(
BackendSettings.backendKey(LuceneBackendSettings.ANALYSIS_CONFIGURER),
HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName()); HapiHSearchAnalysisConfigurers.HapiLuceneAnalysisConfigurer.class.getName());
properties.putIfAbsent(BackendSettings.backendKey(LuceneBackendSettings.LUCENE_VERSION), Version.LATEST); 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,10 +7,9 @@ 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 {
@@ -18,7 +17,7 @@ public class JpaHibernatePropertiesProvider extends HibernatePropertiesProvider
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) {