Compile fixes
This commit is contained in:
3
pom.xml
3
pom.xml
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user