adding factories and beans for cr
This commit is contained in:
@@ -21,7 +21,7 @@ import java.util.Objects;
|
||||
@EnableConfigurationProperties
|
||||
public class AppProperties {
|
||||
|
||||
private Boolean cr_enabled = false;
|
||||
private Boolean cr_enabled = true;
|
||||
private Boolean ips_enabled = false;
|
||||
private Boolean openapi_enabled = false;
|
||||
private Boolean mdm_enabled = false;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package ca.uhn.fhir.jpa.starter;
|
||||
|
||||
import ca.uhn.fhir.batch2.jobs.config.Batch2JobsConfig;
|
||||
import ca.uhn.fhir.cr.config.CrR4Config;
|
||||
import ca.uhn.fhir.jpa.batch2.JpaBatch2Config;
|
||||
import ca.uhn.fhir.jpa.starter.annotations.OnEitherVersion;
|
||||
import ca.uhn.fhir.jpa.starter.common.FhirTesterConfig;
|
||||
import ca.uhn.fhir.jpa.starter.cr.StarterCrR4Config;
|
||||
import ca.uhn.fhir.jpa.starter.mdm.MdmConfig;
|
||||
import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
|
||||
import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig;
|
||||
|
||||
@@ -9,6 +9,8 @@ import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.cr.r4.measure.CareGapsOperationProvider;
|
||||
import ca.uhn.fhir.cr.r4.measure.SubmitDataProvider;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.api.IDaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||
@@ -42,7 +44,6 @@ import ca.uhn.fhir.jpa.starter.AppProperties;
|
||||
import ca.uhn.fhir.jpa.starter.annotations.OnCorsPresent;
|
||||
import ca.uhn.fhir.jpa.starter.annotations.OnImplementationGuidesPresent;
|
||||
import ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory;
|
||||
import ca.uhn.fhir.jpa.starter.cr.CrProviderLoader;
|
||||
import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper;
|
||||
import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor;
|
||||
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
||||
@@ -63,6 +64,7 @@ import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
|
||||
import org.opencds.cqf.cql.evaluator.library.EvaluationSettings;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
@@ -80,18 +82,23 @@ import javax.sql.DataSource;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static ca.uhn.fhir.context.FhirVersionEnum.DSTU3;
|
||||
import static ca.uhn.fhir.context.FhirVersionEnum.R4;
|
||||
import static ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory.ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR;
|
||||
|
||||
@Configuration
|
||||
//allow users to configure custom packages to scan for additional beans
|
||||
@ComponentScan(basePackages = { "${hapi.fhir.custom-bean-packages:}" })
|
||||
@ComponentScan(basePackages = { "${hapi.fhir.custom-bean-packages:}"})
|
||||
@Import(
|
||||
ThreadPoolFactoryConfig.class
|
||||
{ThreadPoolFactoryConfig.class}
|
||||
)
|
||||
public class StarterJpaConfig {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StarterJpaConfig.class);
|
||||
|
||||
public StarterJpaConfig() {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IFulltextSearchSvc fullTextSearchSvc() {
|
||||
return new FulltextSearchSvcImpl();
|
||||
@@ -108,13 +115,9 @@ public class StarterJpaConfig {
|
||||
return ValidationSupportConfigUtil.newCachingValidationSupport(theJpaValidationSupportChain);
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment configurableEnvironment;
|
||||
|
||||
@Autowired(required=false)
|
||||
private CrProviderLoader crProviderLoader;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -166,6 +169,70 @@ public class StarterJpaConfig {
|
||||
return new HSearchSortHelperImpl(mySearchParamRegistry);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider myR4QuestionnaireOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.dstu3.questionnaire.QuestionnaireOperationsProvider myDsu3QuestionnaireOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.dstu3.questionnaire.QuestionnaireOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider r4PlanDefinitionOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.dstu3.plandefinition.PlanDefinitionOperationsProvider myDstu3PlanDefinitionOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.dstu3.plandefinition.PlanDefinitionOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.dstu3.questionnaireresponse.QuestionnaireResponseOperationsProvider myDstu3QuestionnaireResponseOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.dstu3.questionnaireresponse.QuestionnaireResponseOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider myR4QuestionnaireResponseOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.dstu3.activitydefinition.ActivityDefinitionOperationsProvider myDstu3ActivityDefinitionOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.dstu3.activitydefinition.ActivityDefinitionOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
public ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider myR4ActivityDefinitionOperationsProvider() {
|
||||
return new ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider();
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.dstu3.IActivityDefinitionProcessorFactory myDstu3ActivityDefinitionProcessorFactory(EvaluationSettings theEvaluationSettings) {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.activitydefinition.dstu3.ActivityDefinitionProcessor(r, theEvaluationSettings);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.r4.IActivityDefinitionProcessorFactory myR4ActivityDefinitionProcessorFactory(EvaluationSettings theEvaluationSettings) {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.activitydefinition.r4.ActivityDefinitionProcessor(r, theEvaluationSettings);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.dstu3.IQuestionnaireResponseProcessorFactory myDstu3QuestionnaireResponseProcessorFactory() {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.questionnaireresponse.dstu3.QuestionnaireResponseProcessor(r);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.r4.IQuestionnaireResponseProcessorFactory myR4QuestionnaireResponseProcessorFactory() {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.questionnaireresponse.r4.QuestionnaireResponseProcessor(r);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.r4.IQuestionnaireProcessorFactory myR4QuestionnaireProcessorFactory() {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.questionnaire.r4.QuestionnaireProcessor(r);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.r4.IQuestionnaireProcessorFactory myDstu3QuestionnaireProcessorFactory() {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.questionnaire.r4.QuestionnaireProcessor(r);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.r4.IPlanDefinitionProcessorFactory myR4PlanDefinitionProcessorFactory(EvaluationSettings theEvaluationSettings) {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.plandefinition.r4.PlanDefinitionProcessor(r, theEvaluationSettings);
|
||||
}
|
||||
@Bean
|
||||
ca.uhn.fhir.cr.dstu3.IPlanDefinitionProcessorFactory myDstu3PlanDefinitionProcessorFactory(EvaluationSettings theEvaluationSettings) {
|
||||
return r -> new org.opencds.cqf.cql.evaluator.plandefinition.dstu3.PlanDefinitionProcessor(r, theEvaluationSettings);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "hapi.fhir", name = ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR, havingValue = "true")
|
||||
@@ -240,9 +307,28 @@ public class StarterJpaConfig {
|
||||
return new CorsInterceptor(config);
|
||||
|
||||
}
|
||||
|
||||
@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) {
|
||||
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<ca.uhn.fhir.cr.r4.measure.MeasureOperationsProvider> theR4MeasureOperationProvider, Optional<ca.uhn.fhir.cr.dstu3.measure.MeasureOperationsProvider> theDstu3MeasureOperationProvider,
|
||||
Optional<ca.uhn.fhir.cr.dstu3.activitydefinition.ActivityDefinitionOperationsProvider> theDstu3ActivityDefinitionProvider, Optional<ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider> theR4ActivityDefinitionProvider,
|
||||
Optional<ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider> theR4PlanDefinitionOperationProvider, Optional<ca.uhn.fhir.cr.dstu3.plandefinition.PlanDefinitionOperationsProvider> theDstu3PlanDefinitionOperationProvider,
|
||||
Optional<CareGapsOperationProvider> theR4CareGapsOperationProvider, Optional<SubmitDataProvider> theR4SubmitDataProvider,
|
||||
Optional<ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider> theR4QuestionnaireResponseOperationProvider, Optional<ca.uhn.fhir.cr.dstu3.questionnaireresponse.QuestionnaireResponseOperationsProvider> theDstu3QuestionnaireResponseOperationProvider,
|
||||
Optional<ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider> theR4QuestionnaireOperationsProvider, Optional<ca.uhn.fhir.cr.dstu3.questionnaire.QuestionnaireOperationsProvider> theDstu3QuestionnaireOperationsProvider
|
||||
) {
|
||||
RestfulServer fhirServer = new RestfulServer(fhirSystemDao.getContext());
|
||||
|
||||
List<String> supportedResourceTypes = appProperties.getSupported_resource_types();
|
||||
@@ -260,7 +346,12 @@ public class StarterJpaConfig {
|
||||
fhirSystemDao.getContext().setNarrativeGenerator(new NullNarrativeGenerator());
|
||||
}
|
||||
|
||||
if (appProperties.getMdm_enabled()) mdmProviderProvider.get().loadProvider();
|
||||
if (appProperties.getMdm_enabled()) {
|
||||
mdmProviderProvider.get().loadProvider();
|
||||
//theCrProviderLoader.get().loadProvider();
|
||||
|
||||
}
|
||||
|
||||
|
||||
fhirServer.registerProviders(resourceProviderFactory.createProviders());
|
||||
fhirServer.registerProvider(jpaSystemProvider);
|
||||
@@ -328,7 +419,7 @@ public class StarterJpaConfig {
|
||||
* so it is a potential security vulnerability. Consider using an AuthorizationInterceptor
|
||||
* with this feature.
|
||||
*/
|
||||
if (fhirSystemDao.getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { // <-- ENABLED RIGHT NOW
|
||||
if (fhirSystemDao.getContext().getVersion().getVersion().isEqualOrNewerThan(DSTU3)) { // <-- ENABLED RIGHT NOW
|
||||
fhirServer.registerProvider(terminologyUploaderProvider.get());
|
||||
}
|
||||
|
||||
@@ -375,7 +466,7 @@ public class StarterJpaConfig {
|
||||
|
||||
// GraphQL
|
||||
if (appProperties.getGraphql_enabled()) {
|
||||
if (fhirSystemDao.getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
|
||||
if (fhirSystemDao.getContext().getVersion().getVersion().isEqualOrNewerThan(DSTU3)) {
|
||||
fhirServer.registerProvider(graphQLProvider.get());
|
||||
}
|
||||
}
|
||||
@@ -418,6 +509,32 @@ public class StarterJpaConfig {
|
||||
fhirServer.registerProvider(theIpsOperationProvider.get());
|
||||
}
|
||||
|
||||
//Register the Cr Providers
|
||||
if(appProperties.getCr_enabled()) {
|
||||
switch (fhirSystemDao.getContext().getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
ourLog.info("Registering Dstu3 CR providers");
|
||||
fhirServer.registerProviders(theDstu3MeasureOperationProvider.get()
|
||||
,theDstu3ActivityDefinitionProvider.get()
|
||||
,theDstu3PlanDefinitionOperationProvider.get()
|
||||
,theDstu3QuestionnaireResponseOperationProvider.get()
|
||||
,theDstu3QuestionnaireOperationsProvider.get());
|
||||
break;
|
||||
case R4:
|
||||
ourLog.info("Registering R4 CR providers");
|
||||
fhirServer.registerProviders(theR4MeasureOperationProvider.get()
|
||||
,theR4ActivityDefinitionProvider.get()
|
||||
,theR4PlanDefinitionOperationProvider.get()
|
||||
,theR4CareGapsOperationProvider.get()
|
||||
,theR4SubmitDataProvider.get()
|
||||
,theR4QuestionnaireResponseOperationProvider.get()
|
||||
,theR4QuestionnaireOperationsProvider.get());
|
||||
break;
|
||||
default:
|
||||
throw new ConfigurationException("CR not supported for FHIR version " + fhirSystemDao.getContext().getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
return fhirServer;
|
||||
}
|
||||
|
||||
@@ -465,12 +582,12 @@ public class StarterJpaConfig {
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(fhirServer, fhirSystemDao, jpaStorageSettings);
|
||||
confProvider.setImplementationDescription("HAPI FHIR DSTU2 Server");
|
||||
return confProvider;
|
||||
} else if (fhirVersion == FhirVersionEnum.DSTU3) {
|
||||
} else if (fhirVersion == DSTU3) {
|
||||
|
||||
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry);
|
||||
confProvider.setImplementationDescription("HAPI FHIR DSTU3 Server");
|
||||
return confProvider;
|
||||
} else if (fhirVersion == FhirVersionEnum.R4) {
|
||||
} else if (fhirVersion == R4) {
|
||||
|
||||
JpaCapabilityStatementProvider confProvider = new JpaCapabilityStatementProvider(fhirServer, fhirSystemDao, jpaStorageSettings, searchParamRegistry, theValidationSupport);
|
||||
confProvider.setImplementationDescription("HAPI FHIR R4 Server");
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
package ca.uhn.fhir.jpa.starter.cr;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.cr.dstu3.measure.MeasureOperationsProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* This class represents clinical reasoning provider factory used for loading cql and measure operation dependencies of various fhir models
|
||||
**/
|
||||
@Primary
|
||||
@Service
|
||||
public class CrProviderFactory {
|
||||
@Autowired
|
||||
private FhirContext myFhirContext;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext myApplicationContext;
|
||||
|
||||
public Object getMeasureOperationsProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
return myApplicationContext.getBean(MeasureOperationsProvider.class);
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.measure.MeasureOperationsProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("EvaluateMeasure is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
public Object getActivityDefinitionOperationProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.dstu3.activitydefinition.ActivityDefinitionOperationsProvider.class);
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("ActivityDefinition is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
public Object getPlanDefinitionOperationProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.dstu3.plandefinition.PlanDefinitionOperationsProvider.class);
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("PlanDefinition is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
public Object getCareGapsOperationProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.measure.CareGapsOperationProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("Caregaps is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
public Object getSubmitDataOperationProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.measure.SubmitDataProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("SubmitData is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
public Object getQuestionnaireOperationProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.dstu3.questionnaire.QuestionnaireOperationsProvider.class);
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("Questionnaire is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
public Object getQuestionnaireResponseOperationProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.dstu3.questionnaireresponse.QuestionnaireResponseOperationsProvider.class);
|
||||
case R4:
|
||||
return myApplicationContext.getBean(ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider.class);
|
||||
default:
|
||||
throw new ConfigurationException("Questionnaire Response is not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package ca.uhn.fhir.jpa.starter.cr;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* This class loads and registers CQL provider factory for clinical reasoning into hapi-fhir central provider factory
|
||||
**/
|
||||
@Primary
|
||||
@Service
|
||||
public class CrProviderLoader {
|
||||
private static final Logger myLogger = LoggerFactory.getLogger(CrProviderLoader.class);
|
||||
private final FhirContext myFhirContext;
|
||||
private final ResourceProviderFactory myResourceProviderFactory;
|
||||
private final CrProviderFactory myCrProviderFactory;
|
||||
|
||||
public CrProviderLoader(FhirContext theFhirContext, ResourceProviderFactory theResourceProviderFactory, CrProviderFactory theCrProviderFactory) {
|
||||
myFhirContext = theFhirContext;
|
||||
myResourceProviderFactory = theResourceProviderFactory;
|
||||
myCrProviderFactory = theCrProviderFactory;
|
||||
}
|
||||
|
||||
@EventListener(ContextRefreshedEvent.class)
|
||||
public void loadProvider() {
|
||||
switch (myFhirContext.getVersion().getVersion()) {
|
||||
case DSTU3:
|
||||
myLogger.info("Registering Dstu3 Cr Providers");
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getMeasureOperationsProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getActivityDefinitionOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getPlanDefinitionOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getQuestionnaireOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getQuestionnaireResponseOperationProvider());
|
||||
case R4:
|
||||
myLogger.info("Registering R4 Cr Providers");
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getMeasureOperationsProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getActivityDefinitionOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getPlanDefinitionOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getCareGapsOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getSubmitDataOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getQuestionnaireOperationProvider());
|
||||
myResourceProviderFactory.addSupplier(() -> myCrProviderFactory.getQuestionnaireResponseOperationProvider());
|
||||
break;
|
||||
default:
|
||||
throw new ConfigurationException(Msg.code(1653) + "Cr providers not supported for FHIR version " + myFhirContext.getVersion().getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
package ca.uhn.fhir.jpa.starter.cr;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.cr.config.CrR4Config;
|
||||
import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition;
|
||||
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@Configuration
|
||||
@Conditional({OnR4Condition.class, CrConfigCondition.class})
|
||||
@Import({CrR4Config.class})
|
||||
public class StarterCrR4Config {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ hapi:
|
||||
fhir_version: R4
|
||||
### This flag when enabled to true, will avail evaluate measure operations from CR Module.
|
||||
### Flag is false by default, can be passed as command line argument to override.
|
||||
cr_enabled: "${CR_ENABLED: false}"
|
||||
cr_enabled: true
|
||||
### enable to use the ApacheProxyAddressStrategy which uses X-Forwarded-* headers
|
||||
### to determine the FHIR server address
|
||||
# use_apache_address_strategy: false
|
||||
@@ -125,10 +125,9 @@ hapi:
|
||||
# filter_search_enabled: true
|
||||
# graphql_enabled: true
|
||||
narrative_enabled: false
|
||||
# mdm_enabled: true
|
||||
mdm_enabled: false
|
||||
# local_base_urls:
|
||||
# - https://hapi.fhir.org/baseR4
|
||||
mdm_enabled: false
|
||||
# partitioning:
|
||||
# allow_references_across_partitions: false
|
||||
# partitioning_include_in_search_hashes: false
|
||||
|
||||
@@ -86,21 +86,22 @@ public class ExampleServerDstu3IT implements IServerSupport {
|
||||
|
||||
// Currently fails with:
|
||||
// ca.uhn.fhir.rest.server.exceptions.InternalErrorException: HTTP 500 : Failed to call access method: java.lang.IllegalArgumentException: Could not load library source for libraries referenced in Measure/Measure/measure-EXM104-FHIR3-8.1.000/_history/1.
|
||||
//@Test
|
||||
@Test
|
||||
public void testCQLEvaluateMeasureEXM104() throws IOException {
|
||||
String measureId = "measure-EXM104-FHIR3-8.1.000";
|
||||
|
||||
int numFilesLoaded = loadDataFromDirectory("dstu3/EXM104/EXM104_FHIR3-8.1.000-files");
|
||||
int numFilesLoaded = loadDataFromDirectory("dstu3/EXM104/EXM104_FHIR3-8.1.000-bundle.json");
|
||||
//assertEquals(numFilesLoaded, 3);
|
||||
ourLog.info("{} files imported successfully!", numFilesLoaded);
|
||||
//loadBundle("dstu3/EXM104/EXM104_FHIR3-8.1.000-bundle.json", ourCtx, ourClient);
|
||||
// loadBundle("dstu3/EXM104/EXM104_FHIR3-8.1.000-bundle.json", ourCtx, ourClient);
|
||||
|
||||
// http://localhost:8080/fhir/Measure/measure-EXM104-FHIR3-8.1.000/$evaluate-measure?periodStart=2019-01-01&periodEnd=2019-12-31
|
||||
Parameters inParams = new Parameters();
|
||||
// inParams.addParameter().setName("measure").setValue(new StringType("Measure/measure-EXM104-8.2.000"));
|
||||
// inParams.addParameter().setName("patient").setValue(new StringType("Patient/numer-EXM104-FHIR3"));
|
||||
// inParams.addParameter().setName("periodStart").setValue(new StringType("2019-01-01"));
|
||||
// inParams.addParameter().setName("periodEnd").setValue(new StringType("2019-12-31"));
|
||||
inParams.addParameter().setName("patient").setValue(new StringType("Patient/numer-EXM104-FHIR3"));
|
||||
inParams.addParameter().setName("periodStart").setValue(new StringType("2019-01-01"));
|
||||
inParams.addParameter().setName("periodEnd").setValue(new StringType("2019-12-31"));
|
||||
inParams.addParameter().setName("reportType").setValue(new StringType("individual"));
|
||||
|
||||
Parameters outParams = ourClient
|
||||
.operation()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ca.uhn.fhir.jpa.starter;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
@@ -9,6 +10,9 @@ import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.hl7.fhir.r4.model.MeasureReport;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
@@ -19,16 +23,21 @@ import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static ca.uhn.fhir.util.TestUtil.waitForSize;
|
||||
import static java.lang.Thread.sleep;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {Application.class, JpaStarterWebsocketDispatcherConfig.class}, properties = {
|
||||
"spring.datasource.url=jdbc:h2:mem:dbr4",
|
||||
@@ -36,17 +45,20 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
"hapi.fhir.fhir_version=r4",
|
||||
"hapi.fhir.subscription.websocket_enabled=true",
|
||||
"hapi.fhir.mdm_enabled=true",
|
||||
"hapi.fhir.cr_enabled=true",
|
||||
"hapi.fhir.implementationguides.dk-core.name=hl7.fhir.dk.core",
|
||||
"hapi.fhir.implementationguides.dk-core.version=1.1.0",
|
||||
// Override is currently required when using MDM as the construction of the MDM
|
||||
// beans are ambiguous as they are constructed multiple places. This is evident
|
||||
// when running in a spring boot environment
|
||||
"spring.main.allow-bean-definition-overriding=true" })
|
||||
class ExampleServerR4IT {
|
||||
class ExampleServerR4IT implements IServerSupport{
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerR4IT.class);
|
||||
private IGenericClient ourClient;
|
||||
private FhirContext ourCtx;
|
||||
|
||||
private ApplicationContext ctx;
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@@ -85,7 +97,43 @@ class ExampleServerR4IT {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testCQLEvaluateMeasureEXM130() throws IOException {
|
||||
String measureId = "ColorectalCancerScreeningsFHIR";
|
||||
String measureUrl = "http://ecqi.healthit.gov/ecqms/Measure/ColorectalCancerScreeningsFHIR";
|
||||
|
||||
loadBundle("r4/EXM130/EXM130-7.3.000-bundle.json", ourCtx, ourClient);
|
||||
|
||||
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("periodStart").setValue(new StringType("2019-01-01"));
|
||||
inParams.addParameter().setName("periodEnd").setValue(new StringType("2019-12-31"));
|
||||
inParams.addParameter().setName("reportType").setValue(new StringType("summary"));
|
||||
|
||||
Parameters outParams = ourClient
|
||||
.operation()
|
||||
.onInstance(new IdDt("Measure", measureId))
|
||||
.named("$evaluate-measure")
|
||||
.withParameters(inParams)
|
||||
.cacheControl(new CacheControlDirective().setNoCache(true))
|
||||
.withAdditionalHeader("Content-Type", "application/json")
|
||||
.useHttpGet()
|
||||
.execute();
|
||||
|
||||
List<Parameters.ParametersParameterComponent> response = outParams.getParameter();
|
||||
assertFalse(response.isEmpty());
|
||||
Parameters.ParametersParameterComponent component = response.get(0);
|
||||
assertTrue(component.getResource() instanceof MeasureReport);
|
||||
MeasureReport report = (MeasureReport) component.getResource();
|
||||
assertEquals(measureUrl, report.getMeasure());
|
||||
}
|
||||
|
||||
private org.hl7.fhir.r4.model.Bundle loadBundle(String theLocation, FhirContext theCtx, IGenericClient theClient) throws IOException {
|
||||
String json = stringFromResource(theLocation);
|
||||
org.hl7.fhir.r4.model.Bundle bundle = (org.hl7.fhir.r4.model.Bundle) theCtx.newJsonParser().parseResource(json);
|
||||
org.hl7.fhir.r4.model.Bundle result = theClient.transaction().withBundle(bundle).execute();
|
||||
return result;
|
||||
}
|
||||
@Test
|
||||
public void testBatchPutWithIdenticalTags() {
|
||||
String batchPuts = "{\n" +
|
||||
@@ -208,7 +256,6 @@ class ExampleServerR4IT {
|
||||
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
|
||||
String ourServerBase = "http://localhost:" + port + "/fhir/";
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||
|
||||
await().atMost(2, TimeUnit.MINUTES).until(() -> {
|
||||
sleep(1000); // execute below function every 1 second
|
||||
return activeSubscriptionCount() == 2; // 2 subscription based on mdm-rules.json
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user