diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java index bcb9c81..b11da46 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java @@ -5,6 +5,8 @@ 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.CrProviderConfig; +import ca.uhn.fhir.jpa.starter.cr.StarterCrDstu3Config; 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; @@ -37,7 +39,10 @@ import org.springframework.web.servlet.DispatcherServlet; WebsocketDispatcherConfig.class, MdmConfig.class, JpaBatch2Config.class, - Batch2JobsConfig.class + Batch2JobsConfig.class, + StarterCrR4Config.class, + StarterCrDstu3Config.class, + CrProviderConfig.class }) public class Application extends SpringBootServletInitializer { diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java index 9751ba7..ba78ccc 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java @@ -9,7 +9,6 @@ import ca.uhn.fhir.jpa.model.config.PartitionSettings.CrossPartitionReferenceMod import ca.uhn.fhir.jpa.model.entity.StorageSettings; import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.jpa.starter.util.JpaHibernatePropertiesProvider; -import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory; import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl; import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender; import ca.uhn.fhir.rest.server.mail.IMailSvc; diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java index 58873c3..d74a654 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java @@ -9,9 +9,6 @@ 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.config.CrProperties; -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; @@ -45,6 +42,7 @@ 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.CrOperationLoader; import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper; import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.jpa.util.ResourceCountCache; @@ -64,10 +62,7 @@ import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.ResultSeverityEnum; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; -import org.cqframework.cql.cql2elm.model.Model; -import org.hl7.cql.model.ModelIdentifier; import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; -import org.opencds.cqf.cql.evaluator.CqlOptions; import org.opencds.cqf.cql.evaluator.library.EvaluationSettings; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; @@ -80,8 +75,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.web.cors.CorsConfiguration; -import ca.uhn.fhir.cr.common.IRepositoryFactory; -import ca.uhn.fhir.cr.repo.HapiFhirRepository; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; @@ -175,6 +168,12 @@ public class StarterJpaConfig { return new HSearchSortHelperImpl(mySearchParamRegistry); } + @Bean + @ConditionalOnProperty(prefix = "hapi.fhir", name = ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR, havingValue = "true") + public RepositoryValidatingInterceptor repositoryValidatingInterceptor( + IRepositoryValidationInterceptorFactory factory) { + return factory.buildUsingStoredStructureDefinitions(); + } @Bean public ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider myR4QuestionnaireOperationsProvider() { return new ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider(); @@ -217,16 +216,16 @@ public class StarterJpaConfig { @Bean ca.uhn.fhir.cr.dstu3.IActivityDefinitionProcessorFactory myDstu3ActivityDefinitionProcessorFactory( - EvaluationSettings theEvaluationSettings) { + EvaluationSettings theEvaluationSettings) { return r -> new org.opencds.cqf.cql.evaluator.activitydefinition.dstu3.ActivityDefinitionProcessor(r, - theEvaluationSettings); + theEvaluationSettings); } @Bean ca.uhn.fhir.cr.r4.IActivityDefinitionProcessorFactory myR4ActivityDefinitionProcessorFactory( - EvaluationSettings theEvaluationSettings) { + EvaluationSettings theEvaluationSettings) { return r -> new org.opencds.cqf.cql.evaluator.activitydefinition.r4.ActivityDefinitionProcessor(r, - theEvaluationSettings); + theEvaluationSettings); } @Bean @@ -251,50 +250,16 @@ public class StarterJpaConfig { @Bean ca.uhn.fhir.cr.r4.IPlanDefinitionProcessorFactory myR4PlanDefinitionProcessorFactory( - EvaluationSettings theEvaluationSettings) { + 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) { + EvaluationSettings theEvaluationSettings) { return r -> new org.opencds.cqf.cql.evaluator.plandefinition.dstu3.PlanDefinitionProcessor(r, - theEvaluationSettings); + theEvaluationSettings); } - - @Bean - @ConditionalOnProperty(prefix = "hapi.fhir", name = ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR, havingValue = "true") - public RepositoryValidatingInterceptor repositoryValidatingInterceptor( - IRepositoryValidationInterceptorFactory factory) { - return factory.buildUsingStoredStructureDefinitions(); - } - - @Bean - IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry) { - return rd -> new HapiFhirRepository(theDaoRegistry, rd, (RestfulServer) rd.getServer()); - } - - @Bean - EvaluationSettings evaluationSettings(CqlOptions theCqlOptions, Map theGlobalModelCache, - Map theGlobalLibraryCache) { - var evaluationSettings = new EvaluationSettings(); - evaluationSettings.setCqlOptions(theCqlOptions); - evaluationSettings.setModelCache(theGlobalModelCache); - evaluationSettings.setLibraryCache(theGlobalLibraryCache); - - return evaluationSettings; - } - - @Bean - public CqlOptions cqlOptions(CrProperties theCrProperties) { - return theCrProperties.getCqlProperties().getCqlOptions(); - } - - @Bean - public CrProperties crProperties() { - return new CrProperties(); - } - @Bean public LoggingInterceptor loggingInterceptor(AppProperties appProperties) { @@ -387,18 +352,7 @@ public class StarterJpaConfig { IPackageInstallerSvc packageInstallerSvc, ThreadSafeResourceDeleterSvc theThreadSafeResourceDeleterSvc, ApplicationContext appContext, Optional theIpsOperationProvider, - Optional theR4MeasureOperationProvider, - Optional theDstu3MeasureOperationProvider, - Optional theDstu3ActivityDefinitionProvider, - Optional theR4ActivityDefinitionProvider, - Optional theR4PlanDefinitionOperationProvider, - Optional theDstu3PlanDefinitionOperationProvider, - Optional theR4CareGapsOperationProvider, - Optional theR4SubmitDataProvider, - Optional theR4QuestionnaireResponseOperationProvider, - Optional theDstu3QuestionnaireResponseOperationProvider, - Optional theR4QuestionnaireOperationsProvider, - Optional theDstu3QuestionnaireOperationsProvider) { + Optional theCrProviderLoader){ RestfulServer fhirServer = new RestfulServer(fhirSystemDao.getContext()); List supportedResourceTypes = appProperties.getSupported_resource_types(); @@ -418,8 +372,9 @@ public class StarterJpaConfig { if (appProperties.getMdm_enabled()) { mdmProviderProvider.get().loadProvider(); - // theCrProviderLoader.get().loadProvider(); - + } + if (appProperties.getCr_enabled()){ + theCrProviderLoader.get().loadProvider(); } fhirServer.registerProviders(resourceProviderFactory.createProviders()); @@ -584,6 +539,7 @@ public class StarterJpaConfig { fhirServer.registerProvider(theIpsOperationProvider.get()); } + return fhirServer; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrOperationFactory.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrOperationFactory.java new file mode 100644 index 0000000..caa9548 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrOperationFactory.java @@ -0,0 +1,103 @@ +package ca.uhn.fhir.jpa.starter.cr; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +import ca.uhn.fhir.context.ConfigurationException; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.cr.r4.measure.CareGapsOperationProvider; +import ca.uhn.fhir.cr.r4.measure.SubmitDataProvider; +import ca.uhn.fhir.cr.dstu3.activitydefinition.ActivityDefinitionOperationsProvider; +import ca.uhn.fhir.cr.dstu3.measure.MeasureOperationsProvider; +import ca.uhn.fhir.cr.dstu3.plandefinition.PlanDefinitionOperationsProvider; +import ca.uhn.fhir.cr.dstu3.questionnaire.QuestionnaireOperationsProvider; +import ca.uhn.fhir.cr.dstu3.questionnaireresponse.QuestionnaireResponseOperationsProvider; + +public class CrOperationFactory { + @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("Measure operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } + + public Object getActivityDefinitionProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case DSTU3: + return myApplicationContext.getBean(ActivityDefinitionOperationsProvider.class); + case R4: + return myApplicationContext + .getBean(ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider.class); + default: + throw new ConfigurationException("ActivityDefinition operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } + + public Object getPlanDefinitionProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case DSTU3: + return myApplicationContext.getBean(PlanDefinitionOperationsProvider.class); + case R4: + return myApplicationContext + .getBean(ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider.class); + default: + throw new ConfigurationException("PlanDefinition operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } + + public Object getCareGapsProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case R4: + return myApplicationContext.getBean(CareGapsOperationProvider.class); + default: + throw new ConfigurationException("PlanDefinition operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } + public Object getSubmitDataProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case R4: + return myApplicationContext.getBean(SubmitDataProvider.class); + default: + throw new ConfigurationException("PlanDefinition operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } + public Object getQuestionnaireResponseOperationProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case DSTU3: + return myApplicationContext.getBean(QuestionnaireResponseOperationsProvider.class); + case R4: + return myApplicationContext + .getBean(ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider.class); + default: + throw new ConfigurationException("PlanDefinition operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } + public Object getQuestionnaireOperationProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case DSTU3: + return myApplicationContext.getBean(QuestionnaireOperationsProvider.class); + case R4: + return myApplicationContext + .getBean(ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider.class); + default: + throw new ConfigurationException("PlanDefinition operations are not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } +} \ No newline at end of file diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrOperationLoader.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrOperationLoader.java new file mode 100644 index 0000000..21067e0 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrOperationLoader.java @@ -0,0 +1,52 @@ +package ca.uhn.fhir.jpa.starter.cr; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; + +import ca.uhn.fhir.context.ConfigurationException; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; + +public class CrOperationLoader { + private static final Logger myLogger = LoggerFactory.getLogger(CrOperationLoader.class); + private final FhirContext myFhirContext; + private final ResourceProviderFactory myResourceProviderFactory; + private final CrOperationFactory myCrProviderFactory; + + public CrOperationLoader(FhirContext theFhirContext, ResourceProviderFactory theResourceProviderFactory, + CrOperationFactory theCrProviderFactory) { + myFhirContext = theFhirContext; + myResourceProviderFactory = theResourceProviderFactory; + myCrProviderFactory = theCrProviderFactory; + } + + @EventListener(ContextRefreshedEvent.class) + public void loadProvider() { + switch (myFhirContext.getVersion().getVersion()) { + case DSTU3: + myLogger.info("Registering DSTU3 Clinical Reasoning Providers"); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getMeasureOperationsProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getActivityDefinitionProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getPlanDefinitionProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getQuestionnaireResponseOperationProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getQuestionnaireOperationProvider); + break; + case R4: + myLogger.info("Registering R4 Clinical Reasoning Providers"); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getMeasureOperationsProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getActivityDefinitionProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getPlanDefinitionProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getCareGapsProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getSubmitDataProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getQuestionnaireResponseOperationProvider); + myResourceProviderFactory.addSupplier(myCrProviderFactory::getQuestionnaireOperationProvider); + break; + default: + throw new ConfigurationException("Clinical Reasoning not supported for FHIR version " + + myFhirContext.getVersion().getVersion()); + } + } +} + diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProviderConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProviderConfig.java new file mode 100644 index 0000000..8801678 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProviderConfig.java @@ -0,0 +1,26 @@ +package ca.uhn.fhir.jpa.starter.cr; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; + +@Configuration +@Conditional(CrConfigCondition.class) +public class CrProviderConfig { + + @Bean + CrOperationFactory crOperationFactory() { + return new CrOperationFactory(); + } + + @Bean + CrOperationLoader crOperationLoader(FhirContext theFhirContext, ResourceProviderFactory theResourceProviderFactory, + CrOperationFactory theCrlProviderFactory) { + return new CrOperationLoader(theFhirContext, theResourceProviderFactory, theCrlProviderFactory); + } + +} + diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java index 9efc086..65c0a9a 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java @@ -1,7 +1,10 @@ package ca.uhn.fhir.jpa.starter.cr; +import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.cr.config.CrDstu3Config; import ca.uhn.fhir.jpa.starter.annotations.OnDSTU3Condition; +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; @@ -10,4 +13,14 @@ import org.springframework.context.annotation.Import; @Conditional({OnDSTU3Condition.class, CrConfigCondition.class}) @Import({CrDstu3Config.class}) public class StarterCrDstu3Config { + @Bean + CrOperationFactory crOperationFactory() { + return new CrOperationFactory(); + } + + @Bean + CrOperationLoader crOperationLoader(FhirContext theFhirContext, ResourceProviderFactory theResourceProviderFactory, + CrOperationFactory theCrlProviderFactory) { + return new CrOperationLoader(theFhirContext, theResourceProviderFactory, theCrlProviderFactory); + } } diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java index a9ea3d3..2f0e71c 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java index 3d1eb15..c239dba 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java @@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.core.io.ClassPathResource; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.File;