Compile fixes

This commit is contained in:
jamesagnew
2021-05-19 08:45:03 -04:00
parent a452286b5d
commit 415f2461e8
4 changed files with 360 additions and 364 deletions

View File

@@ -14,8 +14,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<!-- FIMXME KBD Change this to 5.3.0 BEFORE merging this code to master ! --> <version>5.4.0</version>
<version>5.4.0-PRE2-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-jpaserver-starter</artifactId> <artifactId>hapi-fhir-jpaserver-starter</artifactId>

View File

@@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.starter.AppProperties;
import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.api.IMdmSettings;
import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator;
import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.mdm.rules.config.MdmSettings;
import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -29,17 +29,17 @@ import java.io.IOException;
@Import({MdmConsumerConfig.class, MdmSubmitterConfig.class}) @Import({MdmConsumerConfig.class, MdmSubmitterConfig.class})
public class MdmConfig { public class MdmConfig {
@Bean @Bean
MdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRetriever theSearchParamRetriever) { MdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRegistry theSearchParamRegistry) {
return new MdmRuleValidator(theFhirContext, theSearchParamRetriever); return new MdmRuleValidator(theFhirContext, theSearchParamRegistry);
} }
@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(), Charsets.UTF_8); String json = IOUtils.toString(resource.getInputStream(), Charsets.UTF_8);
return new MdmSettings(theMdmRuleValidator).setEnabled(appProperties.getMdm_enabled()).setScriptText(json); return new MdmSettings(theMdmRuleValidator).setEnabled(appProperties.getMdm_enabled()).setScriptText(json);
} }
} }

View File

@@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.starter;
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.cql.common.provider.CqlProviderLoader; import ca.uhn.fhir.cql.common.provider.CqlProviderLoader;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.IInterceptorService; import ca.uhn.fhir.interceptor.api.IInterceptorService;
@@ -9,31 +10,38 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; 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.binstore.BinaryStorageInterceptor; import ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.bulk.provider.BulkDataExportProvider; import ca.uhn.fhir.jpa.bulk.export.provider.BulkDataExportProvider;
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor; import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc; import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.packages.PackageInstallOutcomeJson;
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.GraphQLProvider;
import ca.uhn.fhir.jpa.provider.IJpaSystemProvider;
import ca.uhn.fhir.jpa.provider.JpaCapabilityStatementProvider;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
import ca.uhn.fhir.jpa.provider.r5.JpaConformanceProviderR5;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.narrative2.NullNarrativeGenerator; import ca.uhn.fhir.narrative2.NullNarrativeGenerator;
import ca.uhn.fhir.rest.server.ApacheProxyAddressStrategy;
import ca.uhn.fhir.rest.server.ETagSupportEnum; import ca.uhn.fhir.rest.server.ETagSupportEnum;
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy; import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
import ca.uhn.fhir.rest.server.ApacheProxyAddressStrategy;
import ca.uhn.fhir.rest.server.IncomingRequestAddressStrategy; import ca.uhn.fhir.rest.server.IncomingRequestAddressStrategy;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.*; import ca.uhn.fhir.rest.server.interceptor.CorsInterceptor;
import ca.uhn.fhir.rest.server.interceptor.FhirPathFilterInterceptor;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor; 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.validation.IValidatorModule; import ca.uhn.fhir.validation.IValidatorModule;
import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.ResultSeverityEnum;
import com.google.common.base.Strings; import com.google.common.base.Strings;
@@ -44,347 +52,334 @@ import org.springframework.http.HttpHeaders;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import java.util.*; import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class BaseJpaRestfulServer extends RestfulServer { public class BaseJpaRestfulServer extends RestfulServer {
@Autowired private static final long serialVersionUID = 1L;
DaoRegistry daoRegistry; @Autowired
DaoRegistry daoRegistry;
@Autowired @Autowired
DaoConfig daoConfig; DaoConfig daoConfig;
@Autowired
@Autowired ISearchParamRegistry searchParamRegistry;
ISearchParamRegistry searchParamRegistry; @Autowired
IFhirSystemDao fhirSystemDao;
@Autowired @Autowired
IFhirSystemDao fhirSystemDao; ResourceProviderFactory resourceProviders;
@Autowired
@Autowired IJpaSystemProvider jpaSystemProvider;
ResourceProviderFactory resourceProviders; @Autowired
IInterceptorBroadcaster interceptorBroadcaster;
@Autowired @Autowired
IJpaSystemProvider jpaSystemProvider; DatabaseBackedPagingProvider databaseBackedPagingProvider;
@Autowired
@Autowired IInterceptorService interceptorService;
IInterceptorBroadcaster interceptorBroadcaster; @Autowired
IValidatorModule validatorModule;
@Autowired @Autowired
DatabaseBackedPagingProvider databaseBackedPagingProvider; Optional<GraphQLProvider> graphQLProvider;
@Autowired
@Autowired BulkDataExportProvider bulkDataExportProvider;
IInterceptorService interceptorService; @Autowired
PartitionManagementProvider partitionManagementProvider;
@Autowired @Autowired
IValidatorModule validatorModule; BinaryStorageInterceptor binaryStorageInterceptor;
@Autowired
@Autowired IPackageInstallerSvc packageInstallerSvc;
Optional<GraphQLProvider> graphQLProvider; @Autowired
AppProperties appProperties;
@Autowired @Autowired
BulkDataExportProvider bulkDataExportProvider; ApplicationContext myApplicationContext;
@Autowired(required = false)
@Autowired IRepositoryValidationInterceptorFactory factory;
PartitionManagementProvider partitionManagementProvider; // These are set only if the features are enabled
private CqlProviderLoader cqlProviderLoader;
@Autowired @Autowired
BinaryStorageInterceptor binaryStorageInterceptor; private IValidationSupport myValidationSupport;
@Autowired public BaseJpaRestfulServer() {
IPackageInstallerSvc packageInstallerSvc; }
@Autowired @SuppressWarnings("unchecked")
AppProperties appProperties; @Override
protected void initialize() throws ServletException {
@Autowired super.initialize();
ApplicationContext myApplicationContext;
/*
@Autowired(required = false) * Create a FhirContext object that uses the version of FHIR
IRepositoryValidationInterceptorFactory factory; * specified in the properties file.
*/
// These are set only if the features are enabled // Customize supported resource types
private CqlProviderLoader cqlProviderLoader; List<String> supportedResourceTypes = appProperties.getSupported_resource_types();
public BaseJpaRestfulServer() { if (!supportedResourceTypes.isEmpty() && !supportedResourceTypes.contains("SearchParameter")) {
} supportedResourceTypes.add("SearchParameter");
daoRegistry.setSupportedResourceTypes(supportedResourceTypes);
private static final long serialVersionUID = 1L; }
@SuppressWarnings("unchecked") setFhirContext(fhirSystemDao.getContext());
@Override
protected void initialize() throws ServletException { registerProviders(resourceProviders.createProviders());
super.initialize(); registerProvider(jpaSystemProvider);
/* /*
* Create a FhirContext object that uses the version of FHIR * The conformance provider exports the supported resources, search parameters, etc for
* specified in the properties file. * this server. The JPA version adds resourceProviders counts to the exported statement, so it
*/ * is a nice addition.
// Customize supported resource types *
List<String> supportedResourceTypes = appProperties.getSupported_resource_types(); * You can also create your own subclass of the conformance provider if you need to
* provide further customization of your server's CapabilityStatement
if (!supportedResourceTypes.isEmpty() && !supportedResourceTypes.contains("SearchParameter")) { */
supportedResourceTypes.add("SearchParameter");
daoRegistry.setSupportedResourceTypes(supportedResourceTypes); FhirVersionEnum fhirVersion = fhirSystemDao.getContext().getVersion().getVersion();
} if (fhirVersion == FhirVersionEnum.DSTU2) {
setFhirContext(fhirSystemDao.getContext()); JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, fhirSystemDao,
daoConfig);
registerProviders(resourceProviders.createProviders()); confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server");
registerProvider(jpaSystemProvider); setServerConformanceProvider(confProvider);
} else {
/* if (fhirVersion == FhirVersionEnum.DSTU3) {
* The conformance provider exports the supported resources, search parameters, etc for
* this server. The JPA version adds resourceProviders counts to the exported statement, so it JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, fhirSystemDao,
* is a nice addition. daoConfig, searchParamRegistry);
* confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server");
* You can also create your own subclass of the conformance provider if you need to setServerConformanceProvider(confProvider);
* provide further customization of your server's CapabilityStatement } else if (fhirVersion == FhirVersionEnum.R4) {
*/
JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(this, fhirSystemDao,
FhirVersionEnum fhirVersion = fhirSystemDao.getContext().getVersion().getVersion(); daoConfig, searchParamRegistry, myValidationSupport);
if (fhirVersion == FhirVersionEnum.DSTU2) { confProvider.setImplementationDescription("HAPI FHIR R4 Server");
setServerConformanceProvider(confProvider);
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, fhirSystemDao, } else if (fhirVersion == FhirVersionEnum.R5) {
daoConfig);
confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server"); JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(this, fhirSystemDao,
setServerConformanceProvider(confProvider); daoConfig, searchParamRegistry, myValidationSupport);
} else { confProvider.setImplementationDescription("HAPI FHIR R5 Server");
if (fhirVersion == FhirVersionEnum.DSTU3) { setServerConformanceProvider(confProvider);
} else {
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, fhirSystemDao, throw new IllegalStateException();
daoConfig, searchParamRegistry); }
confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server"); }
setServerConformanceProvider(confProvider);
} else if (fhirVersion == FhirVersionEnum.R4) { /*
* ETag Support
JpaConformanceProviderR4 confProvider = new JpaConformanceProviderR4(this, fhirSystemDao, */
daoConfig, searchParamRegistry);
confProvider.setImplementationDescription("HAPI FHIR R4 Server"); if (appProperties.getEtag_support_enabled() == false)
setServerConformanceProvider(confProvider); setETagSupport(ETagSupportEnum.DISABLED);
} else if (fhirVersion == FhirVersionEnum.R5) {
JpaConformanceProviderR5 confProvider = new JpaConformanceProviderR5(this, fhirSystemDao, /*
daoConfig, searchParamRegistry); * This server tries to dynamically generate narratives
confProvider.setImplementationDescription("HAPI FHIR R5 Server"); */
setServerConformanceProvider(confProvider); FhirContext ctx = getFhirContext();
} else { INarrativeGenerator theNarrativeGenerator =
throw new IllegalStateException(); appProperties.getNarrative_enabled() ?
} new DefaultThymeleafNarrativeGenerator() :
} new NullNarrativeGenerator();
ctx.setNarrativeGenerator(theNarrativeGenerator);
/*
* ETag Support /*
*/ * Default to JSON and pretty printing
*/
if (appProperties.getEtag_support_enabled() == false) setDefaultPrettyPrint(appProperties.getDefault_pretty_print());
setETagSupport(ETagSupportEnum.DISABLED);
/*
* Default encoding
/* */
* This server tries to dynamically generate narratives setDefaultResponseEncoding(appProperties.getDefault_encoding());
*/
FhirContext ctx = getFhirContext(); /*
INarrativeGenerator theNarrativeGenerator = * This configures the server to page search results to and from
appProperties.getNarrative_enabled() ? * the database, instead of only paging them to memory. This may mean
new DefaultThymeleafNarrativeGenerator() : * a performance hit when performing searches that return lots of results,
new NullNarrativeGenerator(); * but makes the server much more scalable.
ctx.setNarrativeGenerator(theNarrativeGenerator); */
/* setPagingProvider(databaseBackedPagingProvider);
* Default to JSON and pretty printing
*/ /*
setDefaultPrettyPrint(appProperties.getDefault_pretty_print()); * This interceptor formats the output using nice colourful
* HTML output when the request is detected to come from a
/* * browser.
* Default encoding */
*/ ResponseHighlighterInterceptor responseHighlighterInterceptor = new ResponseHighlighterInterceptor();
setDefaultResponseEncoding(appProperties.getDefault_encoding()); this.registerInterceptor(responseHighlighterInterceptor);
/* if (appProperties.getFhirpath_interceptor_enabled()) {
* This configures the server to page search results to and from registerInterceptor(new FhirPathFilterInterceptor());
* the database, instead of only paging them to memory. This may mean }
* a performance hit when performing searches that return lots of results,
* but makes the server much more scalable. /*
*/ * Add some logging for each request
*/
setPagingProvider(databaseBackedPagingProvider); LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
loggingInterceptor.setLoggerName(appProperties.getLogger().getName());
/* loggingInterceptor.setMessageFormat(appProperties.getLogger().getFormat());
* This interceptor formats the output using nice colourful loggingInterceptor.setErrorMessageFormat(appProperties.getLogger().getError_format());
* HTML output when the request is detected to come from a loggingInterceptor.setLogExceptions(appProperties.getLogger().getLog_exceptions());
* browser. this.registerInterceptor(loggingInterceptor);
*/
ResponseHighlighterInterceptor responseHighlighterInterceptor = new ResponseHighlighterInterceptor(); /*
this.registerInterceptor(responseHighlighterInterceptor); * If you are hosting this server at a specific DNS name, the server will try to
* figure out the FHIR base URL based on what the web container tells it, but
if (appProperties.getFhirpath_interceptor_enabled()) { * this doesn't always work. If you are setting links in your search bundles that
registerInterceptor(new FhirPathFilterInterceptor()); * just refer to "localhost", you might want to use a server address strategy:
} */
String serverAddress = appProperties.getServer_address();
/* if (!Strings.isNullOrEmpty(serverAddress)) {
* Add some logging for each request setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress));
*/ } else if (appProperties.getUse_apache_address_strategy()) {
LoggingInterceptor loggingInterceptor = new LoggingInterceptor(); boolean useHttps = appProperties.getUse_apache_address_strategy_https();
loggingInterceptor.setLoggerName(appProperties.getLogger().getName()); setServerAddressStrategy(useHttps ? ApacheProxyAddressStrategy.forHttps() :
loggingInterceptor.setMessageFormat(appProperties.getLogger().getFormat()); ApacheProxyAddressStrategy.forHttp());
loggingInterceptor.setErrorMessageFormat(appProperties.getLogger().getError_format()); } else {
loggingInterceptor.setLogExceptions(appProperties.getLogger().getLog_exceptions()); setServerAddressStrategy(new IncomingRequestAddressStrategy());
this.registerInterceptor(loggingInterceptor); }
/* /*
* If you are hosting this server at a specific DNS name, the server will try to * If you are using DSTU3+, you may want to add a terminology uploader, which allows
* figure out the FHIR base URL based on what the web container tells it, but * uploading of external terminologies such as Snomed CT. Note that this uploader
* this doesn't always work. If you are setting links in your search bundles that * does not have any security attached (any anonymous user may use it by default)
* just refer to "localhost", you might want to use a server address strategy: * so it is a potential security vulnerability. Consider using an AuthorizationInterceptor
*/ * with this feature.
String serverAddress = appProperties.getServer_address(); */
if (!Strings.isNullOrEmpty(serverAddress)) { if (ctx.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { // <-- ENABLED RIGHT NOW
setServerAddressStrategy(new HardcodedServerAddressStrategy(serverAddress)); registerProvider(myApplicationContext.getBean(TerminologyUploaderProvider.class));
} else if (appProperties.getUse_apache_address_strategy()) { }
boolean useHttps = appProperties.getUse_apache_address_strategy_https();
setServerAddressStrategy(useHttps ? ApacheProxyAddressStrategy.forHttps() : // If you want to enable the $trigger-subscription operation to allow
ApacheProxyAddressStrategy.forHttp()); // manual triggering of a subscription delivery, enable this provider
} else { if (true) { // <-- ENABLED RIGHT NOW
setServerAddressStrategy(new IncomingRequestAddressStrategy()); registerProvider(myApplicationContext.getBean(SubscriptionTriggeringProvider.class));
} }
/* // Define your CORS configuration. This is an example
* If you are using DSTU3+, you may want to add a terminology uploader, which allows // showing a typical setup. You should customize this
* uploading of external terminologies such as Snomed CT. Note that this uploader // to your specific needs
* does not have any security attached (any anonymous user may use it by default) if (appProperties.getCors() != null) {
* so it is a potential security vulnerability. Consider using an AuthorizationInterceptor CorsConfiguration config = new CorsConfiguration();
* with this feature. config.addAllowedHeader(HttpHeaders.ORIGIN);
*/ config.addAllowedHeader(HttpHeaders.ACCEPT);
if (ctx.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { // <-- ENABLED RIGHT NOW config.addAllowedHeader(HttpHeaders.CONTENT_TYPE);
registerProvider(myApplicationContext.getBean(TerminologyUploaderProvider.class)); config.addAllowedHeader(HttpHeaders.AUTHORIZATION);
} config.addAllowedHeader(HttpHeaders.CACHE_CONTROL);
config.addAllowedHeader("x-fhir-starter");
// If you want to enable the $trigger-subscription operation to allow config.addAllowedHeader("X-Requested-With");
// manual triggering of a subscription delivery, enable this provider config.addAllowedHeader("Prefer");
if (true) { // <-- ENABLED RIGHT NOW List<String> allAllowedCORSOrigins = appProperties.getCors().getAllowed_origin();
registerProvider(myApplicationContext.getBean(SubscriptionTriggeringProvider.class)); allAllowedCORSOrigins.forEach(config::addAllowedOrigin);
}
// Define your CORS configuration. This is an example config.addExposedHeader("Location");
// showing a typical setup. You should customize this config.addExposedHeader("Content-Location");
// to your specific needs config.setAllowedMethods(
if (appProperties.getCors() != null) { Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD"));
CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(appProperties.getCors().getAllow_Credentials());
config.addAllowedHeader(HttpHeaders.ORIGIN);
config.addAllowedHeader(HttpHeaders.ACCEPT); // Create the interceptor and register it
config.addAllowedHeader(HttpHeaders.CONTENT_TYPE); CorsInterceptor interceptor = new CorsInterceptor(config);
config.addAllowedHeader(HttpHeaders.AUTHORIZATION); registerInterceptor(interceptor);
config.addAllowedHeader(HttpHeaders.CACHE_CONTROL); }
config.addAllowedHeader("x-fhir-starter");
config.addAllowedHeader("X-Requested-With"); // If subscriptions are enabled, we want to register the interceptor that
config.addAllowedHeader("Prefer"); // will activate them and match results against them
List<String> allAllowedCORSOrigins = appProperties.getCors().getAllowed_origin(); if (appProperties.getSubscription() != null) {
allAllowedCORSOrigins.forEach(config::addAllowedOrigin); // Subscription debug logging
interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor());
}
config.addExposedHeader("Location");
config.addExposedHeader("Content-Location"); // Cascading deletes
config.setAllowedMethods(
Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD"));
config.setAllowCredentials(appProperties.getCors().getAllow_Credentials()); if (appProperties.getAllow_cascading_deletes()) {
CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor(ctx,
// Create the interceptor and register it daoRegistry, interceptorBroadcaster);
CorsInterceptor interceptor = new CorsInterceptor(config); getInterceptorService().registerInterceptor(cascadingDeleteInterceptor);
registerInterceptor(interceptor); }
}
// Binary Storage
// If subscriptions are enabled, we want to register the interceptor that if (appProperties.getBinary_storage_enabled()) {
// will activate them and match results against them getInterceptorService().registerInterceptor(binaryStorageInterceptor);
if (appProperties.getSubscription() != null) { }
// Subscription debug logging
interceptorService.registerInterceptor(new SubscriptionDebugLogInterceptor()); // Validation
}
if (validatorModule != null) {
// Cascading deletes if (appProperties.getValidation().getRequests_enabled()) {
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor();
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
if (appProperties.getAllow_cascading_deletes()) { interceptor.setValidatorModules(Collections.singletonList(validatorModule));
CascadingDeleteInterceptor cascadingDeleteInterceptor = new CascadingDeleteInterceptor(ctx, registerInterceptor(interceptor);
daoRegistry, interceptorBroadcaster); }
getInterceptorService().registerInterceptor(cascadingDeleteInterceptor); if (appProperties.getValidation().getResponses_enabled()) {
} ResponseValidatingInterceptor interceptor = new ResponseValidatingInterceptor();
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
// Binary Storage interceptor.setValidatorModules(Collections.singletonList(validatorModule));
if (appProperties.getBinary_storage_enabled()) { registerInterceptor(interceptor);
getInterceptorService().registerInterceptor(binaryStorageInterceptor); }
} }
// Validation // GraphQL
if (appProperties.getGraphql_enabled()) {
if (validatorModule != null) { if (fhirVersion.isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
if (appProperties.getValidation().getRequests_enabled()) { registerProvider(graphQLProvider.get());
RequestValidatingInterceptor interceptor = new RequestValidatingInterceptor(); }
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR); }
interceptor.setValidatorModules(Collections.singletonList(validatorModule));
registerInterceptor(interceptor); if (appProperties.getAllowed_bundle_types() != null) {
} daoConfig.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet()));
if (appProperties.getValidation().getResponses_enabled()) { }
ResponseValidatingInterceptor interceptor = new ResponseValidatingInterceptor();
interceptor.setFailOnSeverity(ResultSeverityEnum.ERROR); daoConfig.setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size());
interceptor.setValidatorModules(Collections.singletonList(validatorModule));
registerInterceptor(interceptor); // Bulk Export
} if (appProperties.getBulk_export_enabled()) {
} registerProvider(bulkDataExportProvider);
}
// GraphQL
if (appProperties.getGraphql_enabled()) { // Partitioning
if (fhirVersion.isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { if (appProperties.getPartitioning() != null) {
registerProvider(graphQLProvider.get()); registerInterceptor(new RequestTenantPartitionInterceptor());
} setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
} registerProviders(partitionManagementProvider);
}
if (appProperties.getAllowed_bundle_types() != null) {
daoConfig.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet())); if (appProperties.getClient_id_strategy() == DaoConfig.ClientIdStrategyEnum.ANY) {
} daoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID);
daoConfig.setResourceClientIdStrategy(appProperties.getClient_id_strategy());
daoConfig.setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size()); }
// Bulk Export if (appProperties.getImplementationGuides() != null) {
if (appProperties.getBulk_export_enabled()) { Map<String, AppProperties.ImplementationGuide> guides = appProperties.getImplementationGuides();
registerProvider(bulkDataExportProvider); for (Map.Entry<String, AppProperties.ImplementationGuide> guide : guides.entrySet()) {
} packageInstallerSvc.install(new PackageInstallationSpec()
.setPackageUrl(guide.getValue().getUrl())
// Partitioning .setName(guide.getValue().getName())
if (appProperties.getPartitioning() != null) { .setVersion(guide.getValue().getVersion())
registerInterceptor(new RequestTenantPartitionInterceptor()); .setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL));
setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
registerProviders(partitionManagementProvider); }
} }
if (appProperties.getClient_id_strategy() == DaoConfig.ClientIdStrategyEnum.ANY) { if (factory != null) {
daoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID); interceptorService.registerInterceptor(factory.buildUsingStoredStructureDefinitions());
daoConfig.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); }
}
if (appProperties.getImplementationGuides() != null) { if (appProperties.getLastn_enabled()) {
Map<String, AppProperties.ImplementationGuide> guides = appProperties.getImplementationGuides(); daoConfig.setLastNEnabled(true);
for (Map.Entry<String, AppProperties.ImplementationGuide> guide : guides.entrySet()) { }
packageInstallerSvc.install(new PackageInstallationSpec()
.setPackageUrl(guide.getValue().getUrl()) daoConfig.getModelConfig().setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level());
.setName(guide.getValue().getName())
.setVersion(guide.getValue().getVersion()) daoConfig.getModelConfig().setIndexOnContainedResources(appProperties.getEnable_index_contained_resource());
.setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL)); }
}
}
if(factory != null) {
interceptorService.registerInterceptor(factory.buildUsingStoredStructureDefinitions());
}
if (appProperties.getLastn_enabled()) {
daoConfig.setLastNEnabled(true);
}
daoConfig.getModelConfig().setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level());
daoConfig.getModelConfig().setIndexOnContainedResources(appProperties.getEnable_index_contained_resource());
}
} }

View File

@@ -67,16 +67,18 @@ public class ExampleServerR5IT {
public void testWebsocketSubscription() throws Exception { public void testWebsocketSubscription() throws Exception {
/* /*
* Create topic * Create topic (will be contained in subscription)
*/ */
SubscriptionTopic topic = new SubscriptionTopic(); SubscriptionTopic topic = new SubscriptionTopic();
topic.getResourceTrigger().getQueryCriteria().setCurrent("Observation?status=final"); topic.setId("#1");
topic.getResourceTriggerFirstRep().getQueryCriteria().setCurrent("Observation?status=final");
/* /*
* Create subscription * Create subscription
*/ */
Subscription subscription = new Subscription(); Subscription subscription = new Subscription();
subscription.getTopic().setResource(topic); subscription.getContained().add(topic);
subscription.setTopic("#1");
subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)"); subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)");
subscription.setStatus(Enumerations.SubscriptionState.REQUESTED); subscription.setStatus(Enumerations.SubscriptionState.REQUESTED);
subscription.getChannelType() subscription.getChannelType()