diff --git a/common/src/main/java/org/opencds/cqf/common/config/FhirServerConfig.java b/common/src/main/java/org/opencds/cqf/common/config/FhirServerConfig.java index 74c4c4a1d..6d03856a5 100644 --- a/common/src/main/java/org/opencds/cqf/common/config/FhirServerConfig.java +++ b/common/src/main/java/org/opencds/cqf/common/config/FhirServerConfig.java @@ -4,11 +4,15 @@ import java.sql.Driver; import org.apache.commons.dbcp2.BasicDataSource; +import org.opencds.cqf.cds.providers.ProviderConfiguration; +import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; +import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; @@ -17,6 +21,7 @@ @Configuration @EnableTransactionManagement +@ComponentScan(basePackages = "org.opencds.cqf.common") public class FhirServerConfig { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirServerConfig.class); @@ -123,5 +128,19 @@ public ResponseHighlighterInterceptor responseHighlighterInterceptor() { @Bean public PartitionSettings partitionSettings() { return new PartitionSettings(); - } + } + + @Bean() + public ProviderConfiguration providerConfiguration() { + return new ProviderConfiguration( + HapiProperties.getCdsHooksFhirServerExpandValueSets(), + HapiProperties.getCdsHooksFhirServerMaxCodesPerQuery(), + HapiProperties.getCdsHooksFhirServerSearchStyleEnum(), + HapiProperties.getCdsHooksPreFetchMaxUriLength()); + } + + @Bean() + public SearchParameterResolver searchParameterResolver(FhirContext fhirContext) { + return new SearchParameterResolver(fhirContext); + } } diff --git a/common/src/main/java/org/opencds/cqf/common/retrieve/JpaFhirRetrieveProvider.java b/common/src/main/java/org/opencds/cqf/common/retrieve/JpaFhirRetrieveProvider.java index 2719bf68f..4c082ecb1 100644 --- a/common/src/main/java/org/opencds/cqf/common/retrieve/JpaFhirRetrieveProvider.java +++ b/common/src/main/java/org/opencds/cqf/common/retrieve/JpaFhirRetrieveProvider.java @@ -9,24 +9,29 @@ import java.util.Map; import java.util.stream.Collectors; +import javax.inject.Inject; + import org.hl7.fhir.instance.model.api.IBaseResource; import org.opencds.cqf.cql.engine.fhir.retrieve.SearchParamFhirRetrieveProvider; import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterMap; import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.IBundleProvider; +@Component public class JpaFhirRetrieveProvider extends SearchParamFhirRetrieveProvider { private static final Logger logger = LoggerFactory.getLogger(JpaFhirRetrieveProvider.class); DaoRegistry registry; + @Inject public JpaFhirRetrieveProvider(DaoRegistry registry, SearchParameterResolver searchParameterResolver) { super(searchParameterResolver); this.registry = registry; diff --git a/dstu3/pom.xml b/dstu3/pom.xml index 88aaed16c..c489dab2f 100644 --- a/dstu3/pom.xml +++ b/dstu3/pom.xml @@ -18,5 +18,11 @@ common ${project.version} + + + javax + javaee-api + 8.0.1 + diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/config/FhirServerConfigDstu3.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/config/FhirServerConfigDstu3.java index a19151e6f..8ac0b35d4 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/config/FhirServerConfigDstu3.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/config/FhirServerConfigDstu3.java @@ -1,11 +1,26 @@ package org.opencds.cqf.dstu3.config; +import java.util.ArrayList; +import java.util.List; + import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.opencds.cqf.common.config.HapiProperties; +import org.opencds.cqf.dstu3.providers.ActivityDefinitionApplyProvider; +import org.opencds.cqf.dstu3.providers.ApplyCqlOperationProvider; +import org.opencds.cqf.dstu3.providers.CacheValueSetsProvider; +import org.opencds.cqf.dstu3.providers.CodeSystemUpdateProvider; +import org.opencds.cqf.dstu3.providers.CqlExecutionProvider; +import org.opencds.cqf.dstu3.providers.LibraryOperationsProvider; +import org.opencds.cqf.dstu3.providers.MeasureOperationsProvider; +import org.opencds.cqf.dstu3.providers.ObservationProvider; +import org.opencds.cqf.dstu3.providers.PlanDefinitionApplyProvider; +import org.opencds.cqf.dstu3.providers.QuestionnaireProvider; +import org.opencds.cqf.tooling.library.stu3.NarrativeProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -17,6 +32,7 @@ import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; @Configuration +@ComponentScan(basePackages = "org.opencds.cqf.dstu3") public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 { protected final DataSource myDataSource; @@ -71,4 +87,37 @@ public JpaTransactionManager transactionManager(EntityManagerFactory entityManag retVal.setEntityManagerFactory(entityManagerFactory); return retVal; } + + @Bean(name= "myOperationProvidersDstu3") + public List> operationProviders() { + // TODO: Make this registry dynamic + // Scan an interface, create a plugin-api, etc. + // Basically, anything that's not included in base HAPI and implements an operation. + List> classes = new ArrayList<>(); + classes.add(ActivityDefinitionApplyProvider.class); + classes.add(ApplyCqlOperationProvider.class); + classes.add(CacheValueSetsProvider.class); + classes.add(CodeSystemUpdateProvider.class); + classes.add(CqlExecutionProvider.class); + classes.add(LibraryOperationsProvider.class); + classes.add(MeasureOperationsProvider.class); + classes.add(PlanDefinitionApplyProvider.class); + + // The plugin API will need to a way to determine whether a particular + // service should be registered + if(HapiProperties.getQuestionnaireResponseExtractEnabled()) { + classes.add(QuestionnaireProvider.class); + }; + + if (HapiProperties.getObservationTransformEnabled()) { + classes.add(ObservationProvider.class); + } + + return classes; + } + + @Bean() + public NarrativeProvider narrativeProvider() { + return new NarrativeProvider(); + } } diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/evaluation/ProviderFactory.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/evaluation/ProviderFactory.java index 67afaa133..5d5387b32 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/evaluation/ProviderFactory.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/evaluation/ProviderFactory.java @@ -1,5 +1,7 @@ package org.opencds.cqf.dstu3.evaluation; +import javax.inject.Inject; + import org.opencds.cqf.common.evaluation.EvaluationProviderFactory; import org.opencds.cqf.common.helpers.ClientHelper; import org.opencds.cqf.common.providers.Dstu3ApelonFhirTerminologyProvider; @@ -10,6 +12,7 @@ import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver; import org.opencds.cqf.cql.engine.fhir.terminology.Dstu3FhirTerminologyProvider; import org.opencds.cqf.cql.engine.terminology.TerminologyProvider; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; @@ -18,6 +21,7 @@ // This class is a relatively dumb factory for data providers. It supports only // creating JPA providers for FHIR and only basic auth for terminology +@Component public class ProviderFactory implements EvaluationProviderFactory { DaoRegistry registry; @@ -25,6 +29,7 @@ public class ProviderFactory implements EvaluationProviderFactory { FhirContext fhirContext; ISearchParamRegistry searchParamRegistry; + @Inject public ProviderFactory(FhirContext fhirContext, DaoRegistry registry, TerminologyProvider defaultTerminologyProvider) { this.defaultTerminologyProvider = defaultTerminologyProvider; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ActivityDefinitionApplyProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ActivityDefinitionApplyProvider.java index a015d2e8c..2aab800e4 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ActivityDefinitionApplyProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ActivityDefinitionApplyProvider.java @@ -4,6 +4,8 @@ import java.util.Collections; import java.util.List; +import javax.inject.Inject; + import org.hl7.fhir.dstu3.model.ActivityDefinition; import org.hl7.fhir.dstu3.model.Attachment; import org.hl7.fhir.dstu3.model.BooleanType; @@ -24,6 +26,7 @@ import org.opencds.cqf.cql.engine.fhir.model.Dstu3FhirModelResolver; import org.opencds.cqf.cql.engine.model.ModelResolver; import org.opencds.cqf.dstu3.helpers.Helper; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -35,12 +38,14 @@ /** * Created by Bryn on 1/16/2017. */ +@Component public class ActivityDefinitionApplyProvider { private CqlExecutionProvider executionProvider; private ModelResolver modelResolver; private IFhirResourceDao activityDefinitionDao; + @Inject public ActivityDefinitionApplyProvider(FhirContext fhirContext, CqlExecutionProvider executionProvider, IFhirResourceDao activityDefinitionDao) { this.modelResolver = new Dstu3FhirModelResolver(); diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ApplyCqlOperationProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ApplyCqlOperationProvider.java index d82bba842..e0520cd6e 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ApplyCqlOperationProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ApplyCqlOperationProvider.java @@ -5,6 +5,8 @@ import java.util.Date; import java.util.List; +import javax.inject.Inject; + import org.cqframework.cql.cql2elm.LibraryManager; import org.cqframework.cql.cql2elm.ModelManager; import org.cqframework.cql.elm.execution.Library; @@ -26,6 +28,7 @@ import org.opencds.cqf.common.helpers.TranslatorHelper; import org.opencds.cqf.cql.engine.execution.Context; import org.opencds.cqf.cql.engine.runtime.DateTime; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -33,12 +36,14 @@ import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; +@Component public class ApplyCqlOperationProvider { private EvaluationProviderFactory providerFactory; private IFhirResourceDao bundleDao; FhirContext context; + @Inject public ApplyCqlOperationProvider(EvaluationProviderFactory providerFactory, IFhirResourceDao bundleDao, FhirContext context) { this.providerFactory = providerFactory; this.bundleDao = bundleDao; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CacheValueSetsProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CacheValueSetsProvider.java index 563e327dc..e9d822cf5 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CacheValueSetsProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CacheValueSetsProvider.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; +import javax.inject.Inject; + import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Endpoint; import org.hl7.fhir.dstu3.model.IdType; @@ -11,6 +13,7 @@ import org.hl7.fhir.dstu3.model.Resource; import org.hl7.fhir.dstu3.model.ValueSet; import org.opencds.cqf.dstu3.helpers.Helper; +import org.springframework.stereotype.Component; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; @@ -24,11 +27,13 @@ import ca.uhn.fhir.rest.param.StringOrListParam; import ca.uhn.fhir.rest.param.StringParam; +@Component public class CacheValueSetsProvider { private IFhirSystemDao systemDao; private IFhirResourceDao endpointDao; + @Inject public CacheValueSetsProvider(IFhirSystemDao systemDao, IFhirResourceDao endpointDao) { this.systemDao = systemDao; this.endpointDao = endpointDao; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CodeSystemUpdateProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CodeSystemUpdateProvider.java index e67461477..299fa1eaa 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CodeSystemUpdateProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CodeSystemUpdateProvider.java @@ -9,6 +9,8 @@ import java.util.Set; import java.util.stream.Collectors; +import javax.inject.Inject; + import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.Enumerations; import org.hl7.fhir.dstu3.model.IdType; @@ -16,6 +18,7 @@ import org.hl7.fhir.dstu3.model.ValueSet; import org.opencds.cqf.dstu3.builders.OperationOutcomeBuilder; import org.opencds.cqf.dstu3.builders.RandomIdBuilder; +import org.springframework.stereotype.Component; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; @@ -24,10 +27,12 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.UriParam; +@Component public class CodeSystemUpdateProvider { private IFhirResourceDao valueSetDao; private IFhirResourceDao codeSystemDao; + @Inject public CodeSystemUpdateProvider(IFhirResourceDao valueSetDao, IFhirResourceDao codeSystemDao) { this.valueSetDao = valueSetDao; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqfRulerJpaConformanceProviderDstu3.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqfRulerJpaConformanceProviderDstu3.java index f1bc80505..0a9d9e22b 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqfRulerJpaConformanceProviderDstu3.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqfRulerJpaConformanceProviderDstu3.java @@ -1,23 +1,18 @@ package org.opencds.cqf.dstu3.providers; -import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; +import javax.servlet.http.HttpServletRequest; + +import org.hl7.fhir.dstu3.model.CapabilityStatement; +import org.hl7.fhir.dstu3.model.Extension; +import org.hl7.fhir.dstu3.model.StringType; +import org.opencds.cqf.dstu3.servlet.BaseServlet; + import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.rest.annotation.Metadata; import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.RestfulServer; -import org.hl7.fhir.dstu3.model.*; -import org.opencds.cqf.dstu3.servlet.BaseServlet; - -import javax.servlet.http.HttpServletRequest; public class CqfRulerJpaConformanceProviderDstu3 extends JpaConformanceProviderDstu3 { - public CqfRulerJpaConformanceProviderDstu3(RestfulServer theRestfulServer, IFhirSystemDao theSystemDao, DaoConfig theDaoConfig, ISearchParamRegistry theSearchParamRegistry) { - super(theRestfulServer, theSystemDao, theDaoConfig, theSearchParamRegistry); - } - @Metadata @Override public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) { diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqlExecutionProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqlExecutionProvider.java index c5a1f1c70..d73e18415 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqlExecutionProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/CqlExecutionProvider.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Map; +import javax.inject.Inject; + import org.apache.commons.lang3.tuple.Triple; import org.cqframework.cql.cql2elm.CqlTranslator; import org.cqframework.cql.cql2elm.CqlTranslatorException; @@ -37,6 +39,7 @@ import org.opencds.cqf.cql.engine.terminology.TerminologyProvider; import org.opencds.cqf.dstu3.helpers.FhirMeasureBundler; import org.opencds.cqf.dstu3.helpers.LibraryHelper; +import org.springframework.stereotype.Component; import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; @@ -44,10 +47,12 @@ /** * Created by Bryn on 1/16/2017. */ +@Component public class CqlExecutionProvider { private EvaluationProviderFactory providerFactory; private LibraryResolutionProvider libraryResolutionProvider; + @Inject public CqlExecutionProvider(LibraryResolutionProvider libraryResolutionProvider, EvaluationProviderFactory providerFactory) { this.providerFactory = providerFactory; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/DataRequirementsProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/DataRequirementsProvider.java index 017050d28..4853a5176 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/DataRequirementsProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/DataRequirementsProvider.java @@ -67,8 +67,10 @@ import org.opencds.cqf.tooling.measure.stu3.CqfMeasure; import org.opencds.cqf.tooling.measure.stu3.TerminologyRef; import org.opencds.cqf.tooling.measure.stu3.TerminologyRef.TerminologyRefType; +import org.springframework.stereotype.Component; import org.opencds.cqf.tooling.measure.stu3.VersionedTerminologyRef; +@Component public class DataRequirementsProvider { // For creating the CQF measure we need to: diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/HQMFProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/HQMFProvider.java index 56b4eb8e4..948955d04 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/HQMFProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/HQMFProvider.java @@ -47,11 +47,13 @@ import org.opencds.cqf.tooling.measure.stu3.CqfMeasure; import org.opencds.cqf.tooling.measure.stu3.TerminologyRef; import org.opencds.cqf.tooling.measure.stu3.TerminologyRef.TerminologyRefType; +import org.springframework.stereotype.Component; import org.w3c.dom.Document; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.parser.IParser; +@Component public class HQMFProvider { private static Map measureTypeValueSetMap = new HashMap() { diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/JpaTerminologyProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/JpaTerminologyProvider.java index 237c07c07..40f833043 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/JpaTerminologyProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/JpaTerminologyProvider.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionContainsComponent; @@ -11,6 +13,7 @@ import org.opencds.cqf.cql.engine.terminology.CodeSystemInfo; import org.opencds.cqf.cql.engine.terminology.TerminologyProvider; import org.opencds.cqf.cql.engine.terminology.ValueSetInfo; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.support.ValueSetExpansionOptions; @@ -26,11 +29,13 @@ /** * Created by Christopher Schuler on 7/17/2017. */ +@Component public class JpaTerminologyProvider implements TerminologyProvider { private ITermReadSvcDstu3 terminologySvcDstu3; private ValueSetResourceProvider valueSetResourceProvider; + @Inject public JpaTerminologyProvider(ITermReadSvcDstu3 terminologySvcDstu3, FhirContext context, ValueSetResourceProvider valueSetResourceProvider) { this.terminologySvcDstu3 = terminologySvcDstu3; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/LibraryOperationsProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/LibraryOperationsProvider.java index 41ed8dcb2..ca303c83f 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/LibraryOperationsProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/LibraryOperationsProvider.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Objects; +import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import org.cqframework.cql.cql2elm.CqlTranslator; @@ -19,6 +20,7 @@ import org.opencds.cqf.common.providers.LibraryResolutionProvider; import org.opencds.cqf.common.providers.LibrarySourceProvider; import org.opencds.cqf.tooling.library.stu3.NarrativeProvider; +import org.springframework.stereotype.Component; import ca.uhn.fhir.jpa.rp.dstu3.LibraryResourceProvider; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; @@ -32,12 +34,14 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.UriParam; +@Component public class LibraryOperationsProvider implements org.opencds.cqf.common.providers.LibraryResolutionProvider { private NarrativeProvider narrativeProvider; private DataRequirementsProvider dataRequirementsProvider; private LibraryResourceProvider libraryResourceProvider; + @Inject public LibraryOperationsProvider(LibraryResourceProvider libraryResourceProvider, NarrativeProvider narrativeProvider) { this.narrativeProvider = narrativeProvider; diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/MeasureOperationsProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/MeasureOperationsProvider.java index 33f1cf6d4..e25a54f93 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/MeasureOperationsProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/MeasureOperationsProvider.java @@ -8,6 +8,7 @@ import java.util.UUID; import java.util.stream.Collectors; +import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; @@ -48,6 +49,7 @@ import org.opencds.cqf.tooling.measure.stu3.CqfMeasure; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.BaseRuntimeChildDefinition; @@ -62,6 +64,7 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +@Component public class MeasureOperationsProvider { private NarrativeProvider narrativeProvider; @@ -75,6 +78,7 @@ public class MeasureOperationsProvider { private static final Logger logger = LoggerFactory.getLogger(MeasureOperationsProvider.class); + @Inject public MeasureOperationsProvider(DaoRegistry registry, EvaluationProviderFactory factory, NarrativeProvider narrativeProvider, HQMFProvider hqmfProvider, LibraryResolutionProvider libraryResolutionProvider, diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/OAuthProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/OAuthProvider.java index d2c1438cc..2bb5073db 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/OAuthProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/OAuthProvider.java @@ -1,23 +1,25 @@ package org.opencds.cqf.dstu3.providers; -import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; -import ca.uhn.fhir.rest.annotation.Metadata; -import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.RestfulServer; -import org.hl7.fhir.dstu3.model.*; +import javax.servlet.http.HttpServletRequest; + +import org.hl7.fhir.dstu3.model.CapabilityStatement; +import org.hl7.fhir.dstu3.model.CodeableConcept; +import org.hl7.fhir.dstu3.model.Coding; +import org.hl7.fhir.dstu3.model.Extension; +import org.hl7.fhir.dstu3.model.UriType; import org.opencds.cqf.common.config.HapiProperties; -import org.opencds.cqf.dstu3.servlet.BaseServlet; +import org.springframework.stereotype.Component; -import javax.servlet.http.HttpServletRequest; +import ca.uhn.fhir.rest.annotation.Metadata; +import ca.uhn.fhir.rest.api.server.RequestDetails; +/** + * This class is NOT designed to be a real OAuth provider. + * It is designed to provide a capability statement and to pass thru the path to the real oauth verification server. + * It should only get instantiated if hapi.properties has oauth.enabled set to true. + */ +@Component public class OAuthProvider extends CqfRulerJpaConformanceProviderDstu3 { - public OAuthProvider(RestfulServer theRestfulServer, IFhirSystemDao theSystemDao, DaoConfig theDaoConfig, ISearchParamRegistry theSearchParamRegistry) { - super(theRestfulServer, theSystemDao, theDaoConfig, theSearchParamRegistry); - } - @Metadata @Override public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) { diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ObservationProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ObservationProvider.java index 395ef38b0..6b2794717 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ObservationProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/ObservationProvider.java @@ -10,17 +10,22 @@ import org.hl7.fhir.dstu3.model.ConceptMap; import org.hl7.fhir.dstu3.model.Observation; import org.opencds.cqf.common.config.HapiProperties; +import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; +import javax.inject.Inject; + import static org.opencds.cqf.common.helpers.ClientHelper.getClient; +@Component public class ObservationProvider { private FhirContext fhirContext; + @Inject public ObservationProvider(FhirContext fhirContext){ this.fhirContext = fhirContext; } diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/PlanDefinitionApplyProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/PlanDefinitionApplyProvider.java index 6712aeced..9a659ae31 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/PlanDefinitionApplyProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/PlanDefinitionApplyProvider.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.UUID; +import javax.inject.Inject; import javax.xml.bind.JAXBException; import org.hl7.fhir.dstu3.model.ActivityDefinition; @@ -38,6 +39,7 @@ import org.opencds.cqf.dstu3.builders.RequestGroupBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -46,6 +48,7 @@ import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; +@Component public class PlanDefinitionApplyProvider { private CqlExecutionProvider executionProvider; @@ -59,6 +62,7 @@ public class PlanDefinitionApplyProvider { private static final Logger logger = LoggerFactory.getLogger(PlanDefinitionApplyProvider.class); + @Inject public PlanDefinitionApplyProvider(FhirContext fhirContext, ActivityDefinitionApplyProvider activityDefinitionApplyProvider, IFhirResourceDao planDefinitionDao, diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/QuestionnaireProvider.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/QuestionnaireProvider.java index a135d4b77..41e64db2a 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/QuestionnaireProvider.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/providers/QuestionnaireProvider.java @@ -6,15 +6,21 @@ import ca.uhn.fhir.rest.client.api.IGenericClient; import org.hl7.fhir.dstu3.model.*; import org.opencds.cqf.common.config.HapiProperties; +import org.springframework.stereotype.Component; import java.util.Collections; import java.util.Date; +import javax.inject.Inject; + import static org.opencds.cqf.common.helpers.ClientHelper.getClient; +@Component public class QuestionnaireProvider { private FhirContext fhirContext; + + @Inject public QuestionnaireProvider(FhirContext fhirContext){ this.fhirContext = fhirContext; } diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/BaseServlet.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/BaseServlet.java index d71173c17..0545e5b01 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/BaseServlet.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/BaseServlet.java @@ -1,26 +1,15 @@ package org.opencds.cqf.dstu3.servlet; import java.util.Arrays; +import java.util.List; import javax.servlet.ServletException; -import org.hl7.fhir.dstu3.model.ActivityDefinition; import org.hl7.fhir.dstu3.model.Bundle; -import org.hl7.fhir.dstu3.model.CodeSystem; -import org.hl7.fhir.dstu3.model.Endpoint; -import org.hl7.fhir.dstu3.model.Library; -import org.hl7.fhir.dstu3.model.Measure; import org.hl7.fhir.dstu3.model.Meta; -import org.hl7.fhir.dstu3.model.PlanDefinition; -import org.hl7.fhir.dstu3.model.ValueSet; -import org.hl7.fhir.instance.model.api.IBaseResource; import org.opencds.cqf.common.config.HapiProperties; -import org.opencds.cqf.common.evaluation.EvaluationProviderFactory; -import org.opencds.cqf.common.retrieve.JpaFhirRetrieveProvider; -import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver; -import org.opencds.cqf.dstu3.evaluation.ProviderFactory; -import org.opencds.cqf.dstu3.providers.*; -import org.opencds.cqf.tooling.library.stu3.NarrativeProvider; +import org.opencds.cqf.dstu3.providers.CqfRulerJpaConformanceProviderDstu3; +import org.opencds.cqf.dstu3.providers.OAuthProvider; import org.opencds.cqf.tooling.measure.stu3.CodeTerminologyRef; import org.opencds.cqf.tooling.measure.stu3.CqfMeasure; import org.opencds.cqf.tooling.measure.stu3.PopulationCriteriaMap; @@ -31,19 +20,13 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; +import ca.uhn.fhir.jpa.api.rp.ResourceProviderFactory; import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider; import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3; -import ca.uhn.fhir.jpa.rp.dstu3.LibraryResourceProvider; -import ca.uhn.fhir.jpa.rp.dstu3.MeasureResourceProvider; -import ca.uhn.fhir.jpa.rp.dstu3.ValueSetResourceProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; -import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3; -import ca.uhn.fhir.jpa.api.rp.ResourceProviderFactory; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy; @@ -79,6 +62,10 @@ protected void initialize() throws ServletException { IFhirSystemDao systemDao = appCtx.getBean("mySystemDaoDstu3", IFhirSystemDao.class); this.registry = appCtx.getBean(DaoRegistry.class); + DaoConfig daoConfig = appCtx.getBean(DaoConfig.class); + + ISearchParamRegistry searchParamRegistry = appCtx.getBean(ISearchParamRegistry.class); + // System and Resource Providers Object systemProvider = appCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class); registerProvider(systemProvider); @@ -87,27 +74,26 @@ protected void initialize() throws ServletException { ResourceProviderFactory.class); registerProviders(resourceProviders.createProviders()); - if(HapiProperties.getOAuthEnabled()) { - OAuthProvider oauthProvider = new OAuthProvider(this, systemDao, - appCtx.getBean(DaoConfig.class), appCtx.getBean(ISearchParamRegistry.class)); - this.registerProvider(oauthProvider); - this.setServerConformanceProvider(oauthProvider); - }else { + List> operationsProviders = appCtx.getBean("myOperationProvidersDstu3", List.class); + operationsProviders.forEach(x -> registerProvider(appCtx.getBean(x))); - JpaConformanceProviderDstu3 confProvider = new CqfRulerJpaConformanceProviderDstu3(this, systemDao, - appCtx.getBean(DaoConfig.class), appCtx.getBean(ISearchParamRegistry.class)); - confProvider.setImplementationDescription("CQF Ruler FHIR DSTU3 Server"); - setServerConformanceProvider(confProvider); + if(HapiProperties.getOAuthEnabled()) { + OAuthProvider oauthProvider = new OAuthProvider(); + oauthProvider.setDaoConfig(daoConfig); + oauthProvider.setSystemDao(systemDao); + oauthProvider.setSearchParamRegistry(searchParamRegistry); + oauthProvider.setImplementationDescription("CQF Ruler FHIR DSTU3 Server"); + this.setServerConformanceProvider(oauthProvider); + }else { + + JpaConformanceProviderDstu3 confProvider = new CqfRulerJpaConformanceProviderDstu3(); + confProvider.setDaoConfig(daoConfig); + confProvider.setSystemDao(systemDao); + confProvider.setSearchParamRegistry(searchParamRegistry); + confProvider.setImplementationDescription("CQF Ruler FHIR DSTU3 Server"); + this.setServerConformanceProvider(confProvider); } - JpaTerminologyProvider localSystemTerminologyProvider = new JpaTerminologyProvider( - appCtx.getBean("terminologyService", ITermReadSvcDstu3.class), getFhirContext(), - (ValueSetResourceProvider) this.getResourceProvider(ValueSet.class)); - EvaluationProviderFactory providerFactory = new ProviderFactory(this.fhirContext, this.registry, - localSystemTerminologyProvider); - - resolveProviders(providerFactory, localSystemTerminologyProvider, this.registry); - /* * ETag Support */ @@ -180,87 +166,4 @@ protected void initialize() throws ServletException { registerInterceptor(interceptor); } } - - protected NarrativeProvider getNarrativeProvider() { - return new NarrativeProvider(); - } - - // Since resource provider resolution not lazy, the providers here must be - // resolved in the correct - // order of dependencies. - @SuppressWarnings("unchecked") - private void resolveProviders(EvaluationProviderFactory providerFactory, - JpaTerminologyProvider localSystemTerminologyProvider, DaoRegistry registry) throws ServletException { - NarrativeProvider narrativeProvider = this.getNarrativeProvider(); - HQMFProvider hqmfProvider = new HQMFProvider(); - - // Code System Update - CodeSystemUpdateProvider csUpdate = new CodeSystemUpdateProvider(this.getDao(ValueSet.class), - this.getDao(CodeSystem.class)); - this.registerProvider(csUpdate); - - // Cache Value Sets - CacheValueSetsProvider cvs = new CacheValueSetsProvider(this.registry.getSystemDao(), - this.getDao(Endpoint.class)); - this.registerProvider(cvs); - - // Library processing - LibraryOperationsProvider libraryProvider = new LibraryOperationsProvider( - (LibraryResourceProvider) this.getResourceProvider(Library.class), narrativeProvider); - this.registerProvider(libraryProvider); - - // CQL Execution - CqlExecutionProvider cql = new CqlExecutionProvider(libraryProvider, providerFactory); - this.registerProvider(cql); - - // Bundle processing - ApplyCqlOperationProvider bundleProvider = new ApplyCqlOperationProvider(providerFactory, - this.getDao(Bundle.class), this.fhirContext); - this.registerProvider(bundleProvider); - - // Measure processing - MeasureOperationsProvider measureProvider = new MeasureOperationsProvider(this.registry, providerFactory, - narrativeProvider, hqmfProvider, libraryProvider, - (MeasureResourceProvider) this.getResourceProvider(Measure.class)); - this.registerProvider(measureProvider); - - // // ActivityDefinition processing - ActivityDefinitionApplyProvider actDefProvider = new ActivityDefinitionApplyProvider(this.fhirContext, cql, - this.getDao(ActivityDefinition.class)); - this.registerProvider(actDefProvider); - - JpaFhirRetrieveProvider localSystemRetrieveProvider = new JpaFhirRetrieveProvider(registry, - new SearchParameterResolver(this.fhirContext)); - - // PlanDefinition processing - PlanDefinitionApplyProvider planDefProvider = new PlanDefinitionApplyProvider(this.fhirContext, actDefProvider, - this.getDao(PlanDefinition.class), this.getDao(ActivityDefinition.class), cql); - this.registerProvider(planDefProvider); - - CdsHooksServlet.setPlanDefinitionProvider(planDefProvider); - CdsHooksServlet.setLibraryResolutionProvider(libraryProvider); - CdsHooksServlet.setSystemTerminologyProvider(localSystemTerminologyProvider); - CdsHooksServlet.setSystemRetrieveProvider(localSystemRetrieveProvider); - - // QuestionnaireResponse processing - if(HapiProperties.getQuestionnaireResponseExtractEnabled()) { - QuestionnaireProvider questionnaireProvider = new QuestionnaireProvider(this.fhirContext); - this.registerProvider(questionnaireProvider); - } - // Observation processing - if(HapiProperties.getObservationTransformEnabled()) { - ObservationProvider observationProvider = new ObservationProvider(this.fhirContext); - this.registerProvider(observationProvider); - } - } - - protected IFhirResourceDao getDao(Class clazz) { - return this.registry.getResourceDao(clazz); - } - - @SuppressWarnings("unchecked") - protected BaseJpaResourceProvider getResourceProvider(Class clazz) { - return (BaseJpaResourceProvider) this.getResourceProviders().stream() - .filter(x -> x.getResourceType().getSimpleName().equals(clazz.getSimpleName())).findFirst().get(); - } } diff --git a/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/CdsHooksServlet.java b/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/CdsHooksServlet.java index 8b21c4476..3b93d6dd3 100644 --- a/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/CdsHooksServlet.java +++ b/dstu3/src/main/java/org/opencds/cqf/dstu3/servlet/CdsHooksServlet.java @@ -50,6 +50,7 @@ import org.opencds.cqf.dstu3.providers.PlanDefinitionApplyProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; @@ -61,44 +62,32 @@ public class CdsHooksServlet extends HttpServlet { private FhirVersionEnum version = FhirVersionEnum.DSTU3; private static final Logger logger = LoggerFactory.getLogger(CdsHooksServlet.class); - private static PlanDefinitionApplyProvider planDefinitionProvider; + private org.opencds.cqf.dstu3.providers.PlanDefinitionApplyProvider planDefinitionProvider; - private static LibraryResolutionProvider libraryResolutionProvider; + private LibraryResolutionProvider libraryResolutionProvider; - private static JpaFhirRetrieveProvider fhirRetrieveProvider; + private JpaFhirRetrieveProvider fhirRetrieveProvider; - private static JpaTerminologyProvider jpaTerminologyProvider; + private org.opencds.cqf.dstu3.providers.JpaTerminologyProvider jpaTerminologyProvider; private ProviderConfiguration providerConfiguration; - public ProviderConfiguration getProviderConfiguration() { - if (providerConfiguration == null) { - providerConfiguration = new ProviderConfiguration( - HapiProperties.getCdsHooksFhirServerExpandValueSets(), - HapiProperties.getCdsHooksFhirServerMaxCodesPerQuery(), - HapiProperties.getCdsHooksFhirServerSearchStyleEnum(), - HapiProperties.getCdsHooksPreFetchMaxUriLength()); - } - - return providerConfiguration; - } - - // TODO: There's probably a way to wire this all up using Spring - public static void setPlanDefinitionProvider(PlanDefinitionApplyProvider planDefinitionProvider) { - CdsHooksServlet.planDefinitionProvider = planDefinitionProvider; - } - - public static void setLibraryResolutionProvider( - LibraryResolutionProvider libraryResolutionProvider) { - CdsHooksServlet.libraryResolutionProvider = libraryResolutionProvider; - } - - public static void setSystemRetrieveProvider(JpaFhirRetrieveProvider fhirRetrieveProvider) { - CdsHooksServlet.fhirRetrieveProvider = fhirRetrieveProvider; + @SuppressWarnings("unchecked") + @Override + public void init() { + // System level providers + ApplicationContext appCtx = (ApplicationContext) getServletContext() + .getAttribute("org.springframework.web.context.WebApplicationContext.ROOT"); + + this.providerConfiguration = appCtx.getBean(ProviderConfiguration.class); + this.planDefinitionProvider = appCtx.getBean(PlanDefinitionApplyProvider.class); + this.libraryResolutionProvider = (LibraryResolutionProvider)appCtx.getBean(LibraryResolutionProvider.class); + this.fhirRetrieveProvider = appCtx.getBean(JpaFhirRetrieveProvider.class); + this.jpaTerminologyProvider = appCtx.getBean(JpaTerminologyProvider.class); } - public static void setSystemTerminologyProvider(JpaTerminologyProvider jpaTerminologyProvider) { - CdsHooksServlet.jpaTerminologyProvider = jpaTerminologyProvider; + protected ProviderConfiguration getProviderConfiguration() { + return this.providerConfiguration; } // CORS Pre-flight diff --git a/pom.xml b/pom.xml index 101ab0e47..5ab9b4b4e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 @@ -94,63 +94,63 @@ - - org.opencds.cqf.cql - evaluator.execution - ${cql-evaluator.version} - - - org.opencds.cqf - tooling - ${cqf-tooling.version} - - - org.slf4j - slf4j-log4j12 - - - - - - org.opencds.cqf.cql - engine - ${cql-engine.version} - - - org.slf4j - slf4j-log4j12 - - - - - - org.opencds.cqf.cql - engine.fhir - ${cql-engine.version} - - - org.slf4j - slf4j-log4j12 - - - - - - info.cqframework - cql-to-elm - ${cqframework.version} - - - - info.cqframework - cql-formatter - ${cqframework.version} - - - org.opencds.cqf - cds - ${cds-hooks.version} - + + org.opencds.cqf.cql + evaluator.execution + ${cql-evaluator.version} + + + org.opencds.cqf + tooling + ${cqf-tooling.version} + + + org.slf4j + slf4j-log4j12 + + + + + + org.opencds.cqf.cql + engine + ${cql-engine.version} + + + org.slf4j + slf4j-log4j12 + + + + + + org.opencds.cqf.cql + engine.fhir + ${cql-engine.version} + + + org.slf4j + slf4j-log4j12 + + + + + + info.cqframework + cql-to-elm + ${cqframework.version} + + + + info.cqframework + cql-formatter + ${cqframework.version} + + + org.opencds.cqf + cds + ${cds-hooks.version} + @@ -162,6 +162,13 @@ org.opencds.cqf.cql evaluator.execution + + + javax + javaee-api + 8.0.1 + + org.opencds.cqf tooling @@ -278,9 +285,9 @@ - org.slf4j - jcl-over-slf4j - ${slf4j.version} + org.slf4j + jcl-over-slf4j + ${slf4j.version} @@ -409,12 +416,34 @@ 1.8 1.8 + true + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + true + true + + org.apache.maven.plugins maven-war-plugin 3.2.3 + + + + true + true + + + org.apache.maven.plugins diff --git a/r4/src/main/java/org/opencds/cqf/r4/config/FhirServerConfigR4.java b/r4/src/main/java/org/opencds/cqf/r4/config/FhirServerConfigR4.java index 7e8b3e8ac..bb79e4ded 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/config/FhirServerConfigR4.java +++ b/r4/src/main/java/org/opencds/cqf/r4/config/FhirServerConfigR4.java @@ -1,11 +1,26 @@ package org.opencds.cqf.r4.config; +import java.util.ArrayList; +import java.util.List; + import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.opencds.cqf.common.config.HapiProperties; +import org.opencds.cqf.r4.providers.ActivityDefinitionApplyProvider; +import org.opencds.cqf.r4.providers.ApplyCqlOperationProvider; +import org.opencds.cqf.r4.providers.CacheValueSetsProvider; +import org.opencds.cqf.r4.providers.CodeSystemUpdateProvider; +import org.opencds.cqf.r4.providers.CqlExecutionProvider; +import org.opencds.cqf.r4.providers.LibraryOperationsProvider; +import org.opencds.cqf.r4.providers.MeasureOperationsProvider; +import org.opencds.cqf.r4.providers.ObservationProvider; +import org.opencds.cqf.r4.providers.PlanDefinitionApplyProvider; +import org.opencds.cqf.r4.providers.QuestionnaireProvider; +import org.opencds.cqf.tooling.library.r4.NarrativeProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -17,6 +32,7 @@ import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; @Configuration +@ComponentScan(basePackages = "org.opencds.cqf.r4") public class FhirServerConfigR4 extends BaseJavaConfigR4 { protected final DataSource myDataSource; @@ -71,4 +87,37 @@ public JpaTransactionManager transactionManager(EntityManagerFactory entityManag retVal.setEntityManagerFactory(entityManagerFactory); return retVal; } + + @Bean(name= "myOperationProvidersR4") + public List> operationProviders() { + // TODO: Make this registry dynamic + // Scan an interface, create a plugin-api, etc. + // Basically, anything that's not included in base HAPI and implements an operation. + List> classes = new ArrayList<>(); + classes.add(ActivityDefinitionApplyProvider.class); + classes.add(ApplyCqlOperationProvider.class); + classes.add(CacheValueSetsProvider.class); + classes.add(CodeSystemUpdateProvider.class); + classes.add(CqlExecutionProvider.class); + classes.add(LibraryOperationsProvider.class); + classes.add(MeasureOperationsProvider.class); + classes.add(PlanDefinitionApplyProvider.class); + + // The plugin API will need to a way to determine whether a particular + // service should be registered + if(HapiProperties.getQuestionnaireResponseExtractEnabled()) { + classes.add(QuestionnaireProvider.class); + }; + + if (HapiProperties.getObservationTransformEnabled()) { + classes.add(ObservationProvider.class); + } + + return classes; + } + + @Bean() + public NarrativeProvider narrativeProvider() { + return new NarrativeProvider(); + } } diff --git a/r4/src/main/java/org/opencds/cqf/r4/evaluation/MeasureEvaluation.java b/r4/src/main/java/org/opencds/cqf/r4/evaluation/MeasureEvaluation.java index 3e1a2dcd6..d795b626f 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/evaluation/MeasureEvaluation.java +++ b/r4/src/main/java/org/opencds/cqf/r4/evaluation/MeasureEvaluation.java @@ -113,6 +113,7 @@ public MeasureReport evaluatePopulationMeasure(Measure measure, Context context) return evaluate(measure, context, getAllPatients(), MeasureReport.MeasureReportType.SUMMARY, isSingle); } + @SuppressWarnings("unchecked") private void clearExpressionCache(Context context) { // Hack to clear expression cache // See cqf-ruler github issue #153 diff --git a/r4/src/main/java/org/opencds/cqf/r4/evaluation/ProviderFactory.java b/r4/src/main/java/org/opencds/cqf/r4/evaluation/ProviderFactory.java index b60a6c509..ed0631c0a 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/evaluation/ProviderFactory.java +++ b/r4/src/main/java/org/opencds/cqf/r4/evaluation/ProviderFactory.java @@ -1,5 +1,7 @@ package org.opencds.cqf.r4.evaluation; +import javax.inject.Inject; + import org.opencds.cqf.common.evaluation.EvaluationProviderFactory; import org.opencds.cqf.common.helpers.ClientHelper; import org.opencds.cqf.common.providers.R4ApelonFhirTerminologyProvider; @@ -10,6 +12,7 @@ import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver; import org.opencds.cqf.cql.engine.fhir.terminology.R4FhirTerminologyProvider; import org.opencds.cqf.cql.engine.terminology.TerminologyProvider; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; @@ -17,12 +20,14 @@ // This class is a relatively dumb factory for data providers. It supports only // creating JPA providers for FHIR, and only basic auth for terminology +@Component public class ProviderFactory implements EvaluationProviderFactory { DaoRegistry registry; TerminologyProvider defaultTerminologyProvider; FhirContext fhirContext; + @Inject public ProviderFactory(FhirContext fhirContext, DaoRegistry registry, TerminologyProvider defaultTerminologyProvider) { this.defaultTerminologyProvider = defaultTerminologyProvider; diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/ActivityDefinitionApplyProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/ActivityDefinitionApplyProvider.java index 672b65de1..41a7fca12 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/ActivityDefinitionApplyProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/ActivityDefinitionApplyProvider.java @@ -4,6 +4,8 @@ import java.util.Collections; import java.util.List; +import javax.inject.Inject; + import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r4.model.ActivityDefinition; import org.hl7.fhir.r4.model.Attachment; @@ -24,6 +26,7 @@ import org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver; import org.opencds.cqf.cql.engine.model.ModelResolver; import org.opencds.cqf.r4.helpers.Helper; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -35,12 +38,14 @@ /** * Created by Bryn on 1/16/2017. */ +@Component public class ActivityDefinitionApplyProvider { private CqlExecutionProvider executionProvider; private ModelResolver modelResolver; private IFhirResourceDao activityDefinitionDao; + @Inject public ActivityDefinitionApplyProvider(FhirContext fhirContext, CqlExecutionProvider executionProvider, IFhirResourceDao activityDefinitionDao) { this.modelResolver = new R4FhirModelResolver(); diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/ApplyCqlOperationProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/ApplyCqlOperationProvider.java index ec0215e11..3dc33f364 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/ApplyCqlOperationProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/ApplyCqlOperationProvider.java @@ -4,6 +4,8 @@ import java.util.AbstractMap; import java.util.Date; +import javax.inject.Inject; + import org.cqframework.cql.cql2elm.LibraryManager; import org.cqframework.cql.cql2elm.ModelManager; import org.cqframework.cql.elm.execution.Library; @@ -26,6 +28,7 @@ import org.opencds.cqf.common.helpers.TranslatorHelper; import org.opencds.cqf.cql.engine.execution.Context; import org.opencds.cqf.cql.engine.runtime.DateTime; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -33,12 +36,14 @@ import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; +@Component public class ApplyCqlOperationProvider { private EvaluationProviderFactory providerFactory; private IFhirResourceDao bundleDao; private FhirContext context; + @Inject public ApplyCqlOperationProvider(EvaluationProviderFactory providerFactory, IFhirResourceDao bundleDao, FhirContext context) { this.providerFactory = providerFactory; this.bundleDao = bundleDao; diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/CacheValueSetsProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/CacheValueSetsProvider.java index addf35302..a39c7ea19 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/CacheValueSetsProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/CacheValueSetsProvider.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; +import javax.inject.Inject; + import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Endpoint; import org.hl7.fhir.r4.model.IdType; @@ -11,6 +13,7 @@ import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.ValueSet; import org.opencds.cqf.r4.helpers.Helper; +import org.springframework.stereotype.Component; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; @@ -24,11 +27,13 @@ import ca.uhn.fhir.rest.param.StringOrListParam; import ca.uhn.fhir.rest.param.StringParam; +@Component public class CacheValueSetsProvider { private IFhirSystemDao systemDao; private IFhirResourceDao endpointDao; + @Inject public CacheValueSetsProvider(IFhirSystemDao systemDao, IFhirResourceDao endpointDao) { this.systemDao = systemDao; this.endpointDao = endpointDao; diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/CodeSystemUpdateProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/CodeSystemUpdateProvider.java index c0ddbf56d..9451ae9c6 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/CodeSystemUpdateProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/CodeSystemUpdateProvider.java @@ -9,6 +9,8 @@ import java.util.Set; import java.util.stream.Collectors; +import javax.inject.Inject; + import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.IdType; @@ -16,6 +18,7 @@ import org.hl7.fhir.r4.model.ValueSet; import org.opencds.cqf.r4.builders.OperationOutcomeBuilder; import org.opencds.cqf.r4.builders.RandomIdBuilder; +import org.springframework.stereotype.Component; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; @@ -24,10 +27,12 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.UriParam; +@Component public class CodeSystemUpdateProvider { private IFhirResourceDao valueSetDao; private IFhirResourceDao codeSystemDao; + @Inject public CodeSystemUpdateProvider(IFhirResourceDao valueSetDao, IFhirResourceDao codeSystemDao) { this.valueSetDao = valueSetDao; diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/CqfRulerJpaConformanceProviderR4.java b/r4/src/main/java/org/opencds/cqf/r4/providers/CqfRulerJpaConformanceProviderR4.java index 4c679520d..80859885c 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/CqfRulerJpaConformanceProviderR4.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/CqfRulerJpaConformanceProviderR4.java @@ -1,28 +1,17 @@ package org.opencds.cqf.r4.providers; -import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; -import ca.uhn.fhir.rest.annotation.Metadata; -import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.RestfulServer; +import javax.servlet.http.HttpServletRequest; + +import org.hl7.fhir.r4.model.CapabilityStatement; import org.hl7.fhir.r4.model.Extension; import org.hl7.fhir.r4.model.StringType; -import org.hl7.fhir.r4.model.Bundle; -import org.hl7.fhir.r4.model.CapabilityStatement; -import org.hl7.fhir.r4.model.Meta; import org.opencds.cqf.r4.servlet.BaseServlet; - -import javax.servlet.http.HttpServletRequest; +import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4; +import ca.uhn.fhir.rest.annotation.Metadata; +import ca.uhn.fhir.rest.api.server.RequestDetails; public class CqfRulerJpaConformanceProviderR4 extends JpaConformanceProviderR4 { - - public CqfRulerJpaConformanceProviderR4(RestfulServer theRestfulServer, IFhirSystemDao theSystemDao, DaoConfig theDaoConfig, ISearchParamRegistry theSearchParamRegistry) { - super(theRestfulServer, theSystemDao, theDaoConfig, theSearchParamRegistry); - } - @Metadata @Override public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) { diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/CqlExecutionProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/CqlExecutionProvider.java index ac855087d..31ef27cb0 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/CqlExecutionProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/CqlExecutionProvider.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Map; +import javax.inject.Inject; + import org.apache.commons.lang3.tuple.Triple; import org.cqframework.cql.cql2elm.CqlTranslator; import org.cqframework.cql.cql2elm.CqlTranslatorException; @@ -37,6 +39,7 @@ import org.opencds.cqf.r4.helpers.CanonicalHelper; import org.opencds.cqf.r4.helpers.FhirMeasureBundler; import org.opencds.cqf.r4.helpers.LibraryHelper; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.annotation.Operation; @@ -45,11 +48,13 @@ /** * Created by Bryn on 1/16/2017. */ +@Component public class CqlExecutionProvider { private EvaluationProviderFactory providerFactory; private LibraryResolutionProvider libraryResourceProvider; private FhirContext context; + @Inject public CqlExecutionProvider(LibraryResolutionProvider libraryResourceProvider, EvaluationProviderFactory providerFactory, FhirContext context) { this.providerFactory = providerFactory; diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/DataRequirementsProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/DataRequirementsProvider.java index 03557ad5f..8605d7292 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/DataRequirementsProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/DataRequirementsProvider.java @@ -61,10 +61,12 @@ import org.opencds.cqf.tooling.measure.r4.CqfMeasure; import org.opencds.cqf.tooling.measure.r4.TerminologyRef; import org.opencds.cqf.tooling.measure.r4.TerminologyRef.TerminologyRefType; +import org.springframework.stereotype.Component; import org.opencds.cqf.tooling.measure.r4.VersionedTerminologyRef; import org.opencds.cqf.r4.helpers.CanonicalHelper; import org.opencds.cqf.r4.helpers.LibraryHelper; +@Component public class DataRequirementsProvider { // For creating the CQF measure we need to: diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/HQMFProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/HQMFProvider.java index 4672a1544..f5fe84798 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/HQMFProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/HQMFProvider.java @@ -46,11 +46,13 @@ import org.opencds.cqf.tooling.measure.r4.CqfMeasure; import org.opencds.cqf.tooling.measure.r4.TerminologyRef; import org.opencds.cqf.tooling.measure.r4.TerminologyRef.TerminologyRefType; +import org.springframework.stereotype.Component; import org.w3c.dom.Document; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.parser.IParser; +@Component public class HQMFProvider { private static Map measureTypeValueSetMap = new HashMap() { diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/JpaTerminologyProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/JpaTerminologyProvider.java index bcfd7b0a2..8b83fbd48 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/JpaTerminologyProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/JpaTerminologyProvider.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.ValueSet; @@ -11,6 +13,7 @@ import org.opencds.cqf.cql.engine.terminology.CodeSystemInfo; import org.opencds.cqf.cql.engine.terminology.TerminologyProvider; import org.opencds.cqf.cql.engine.terminology.ValueSetInfo; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.support.ValueSetExpansionOptions; @@ -23,11 +26,13 @@ import ca.uhn.fhir.rest.param.UriParam; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +@Component public class JpaTerminologyProvider implements TerminologyProvider { private ITermReadSvcR4 terminologySvcR4; private ValueSetResourceProvider valueSetResourceProvider; + @Inject public JpaTerminologyProvider(ITermReadSvcR4 terminologySvcR4, FhirContext context, ValueSetResourceProvider valueSetResourceProvider) { this.terminologySvcR4 = terminologySvcR4; diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/LibraryOperationsProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/LibraryOperationsProvider.java index 547bffefc..ed26d31bf 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/LibraryOperationsProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/LibraryOperationsProvider.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Objects; +import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.tuple.Pair; @@ -49,6 +50,7 @@ import org.opencds.cqf.cql.engine.terminology.TerminologyProvider; import org.opencds.cqf.cql.evaluator.execution.provider.BundleRetrieveProvider; import org.opencds.cqf.tooling.library.r4.NarrativeProvider; +import org.springframework.stereotype.Component; import org.opencds.cqf.r4.helpers.FhirMeasureBundler; import org.opencds.cqf.r4.helpers.LibraryHelper; @@ -66,6 +68,7 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.UriParam; +@Component public class LibraryOperationsProvider implements LibraryResolutionProvider { private NarrativeProvider narrativeProvider; @@ -74,6 +77,7 @@ public class LibraryOperationsProvider implements LibraryResolutionProvider libraryResolutionProvider, diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/OAuthProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/OAuthProvider.java index 2a124c70f..baf5d9d8a 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/OAuthProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/OAuthProvider.java @@ -2,35 +2,24 @@ import javax.servlet.http.HttpServletRequest; -import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.CapabilityStatement; import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Extension; -import org.hl7.fhir.r4.model.Meta; import org.hl7.fhir.r4.model.UriType; import org.opencds.cqf.common.config.HapiProperties; +import org.springframework.stereotype.Component; -import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.rest.annotation.Metadata; import ca.uhn.fhir.rest.api.server.RequestDetails; -import ca.uhn.fhir.rest.server.RestfulServer; -import org.opencds.cqf.r4.servlet.BaseServlet; +/** + * This class is NOT designed to be a real OAuth provider. + * It is designed to provide a capability statement and to pass thru the path to the real oauth verification server. + * It should only get instantiated if hapi.properties has oauth.enabled set to true. + */ +@Component public class OAuthProvider extends CqfRulerJpaConformanceProviderR4 { - /** - * This class is NOT designed to be a real OAuth provider. - * It is designed to provide a capability statement and to pass thru the path to the real oauth verification server. - * It should only get instantiated if hapi.properties has oauth.enabled set to true. - */ - - public OAuthProvider(RestfulServer theRestfulServer, IFhirSystemDao theSystemDao, DaoConfig theDaoConfig, ISearchParamRegistry theSearchParamRegistry) { - super(theRestfulServer, theSystemDao, theDaoConfig, theSearchParamRegistry); - } - @Metadata @Override public CapabilityStatement getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) { diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/ObservationProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/ObservationProvider.java index c636cec94..83a2d6ba5 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/ObservationProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/ObservationProvider.java @@ -10,17 +10,22 @@ import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.Observation; import org.opencds.cqf.common.config.HapiProperties; +import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; +import javax.inject.Inject; + import static org.opencds.cqf.common.helpers.ClientHelper.getClient; +@Component public class ObservationProvider { private FhirContext fhirContext; + @Inject public ObservationProvider(FhirContext fhirContext){ this.fhirContext = fhirContext; } diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/PlanDefinitionApplyProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/PlanDefinitionApplyProvider.java index 6513c67fa..3c5197217 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/PlanDefinitionApplyProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/PlanDefinitionApplyProvider.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.UUID; +import javax.inject.Inject; import javax.xml.bind.JAXBException; import org.hl7.fhir.exceptions.FHIRException; @@ -39,6 +40,7 @@ import org.opencds.cqf.r4.helpers.CanonicalHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -47,6 +49,7 @@ import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; +@Component public class PlanDefinitionApplyProvider { private CqlExecutionProvider executionProvider; @@ -60,6 +63,7 @@ public class PlanDefinitionApplyProvider { private static final Logger logger = LoggerFactory.getLogger(PlanDefinitionApplyProvider.class); + @Inject public PlanDefinitionApplyProvider(FhirContext fhirContext, ActivityDefinitionApplyProvider activityDefinitionApplyProvider, IFhirResourceDao planDefinitionDao, diff --git a/r4/src/main/java/org/opencds/cqf/r4/providers/QuestionnaireProvider.java b/r4/src/main/java/org/opencds/cqf/r4/providers/QuestionnaireProvider.java index e12a5c651..0bdbcc2b3 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/providers/QuestionnaireProvider.java +++ b/r4/src/main/java/org/opencds/cqf/r4/providers/QuestionnaireProvider.java @@ -6,15 +6,21 @@ import ca.uhn.fhir.rest.client.api.IGenericClient; import org.hl7.fhir.r4.model.*; import org.opencds.cqf.common.config.HapiProperties; +import org.springframework.stereotype.Component; import java.util.Collections; import java.util.Date; +import javax.inject.Inject; + import static org.opencds.cqf.common.helpers.ClientHelper.getClient; +@Component public class QuestionnaireProvider { private FhirContext fhirContext; + + @Inject public QuestionnaireProvider(FhirContext fhirContext){ this.fhirContext = fhirContext; } diff --git a/r4/src/main/java/org/opencds/cqf/r4/servlet/BaseServlet.java b/r4/src/main/java/org/opencds/cqf/r4/servlet/BaseServlet.java index 8a3ba1ca0..d1e7e8024 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/servlet/BaseServlet.java +++ b/r4/src/main/java/org/opencds/cqf/r4/servlet/BaseServlet.java @@ -1,55 +1,37 @@ package org.opencds.cqf.r4.servlet; import java.util.Arrays; +import java.util.List; import javax.servlet.ServletException; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.r4.model.ActivityDefinition; import org.hl7.fhir.r4.model.Bundle; -import org.hl7.fhir.r4.model.CodeSystem; -import org.hl7.fhir.r4.model.Endpoint; -import org.hl7.fhir.r4.model.Library; -import org.hl7.fhir.r4.model.Measure; import org.hl7.fhir.r4.model.Meta; -import org.hl7.fhir.r4.model.PlanDefinition; -import org.hl7.fhir.r4.model.ValueSet; import org.opencds.cqf.common.config.HapiProperties; -import org.opencds.cqf.common.evaluation.EvaluationProviderFactory; -import org.opencds.cqf.common.retrieve.JpaFhirRetrieveProvider; -import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver; -import org.opencds.cqf.tooling.library.r4.NarrativeProvider; +import org.opencds.cqf.r4.providers.CqfRulerJpaConformanceProviderR4; +import org.opencds.cqf.r4.providers.OAuthProvider; import org.opencds.cqf.tooling.measure.r4.CodeTerminologyRef; import org.opencds.cqf.tooling.measure.r4.CqfMeasure; import org.opencds.cqf.tooling.measure.r4.PopulationCriteriaMap; import org.opencds.cqf.tooling.measure.r4.VersionedTerminologyRef; -import org.opencds.cqf.r4.evaluation.ProviderFactory; -import org.opencds.cqf.r4.providers.*; import org.springframework.context.ApplicationContext; import org.springframework.web.cors.CorsConfiguration; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; -import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; -import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; +import ca.uhn.fhir.jpa.api.rp.ResourceProviderFactory; import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider; -import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4; import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4; -import ca.uhn.fhir.jpa.rp.r4.LibraryResourceProvider; -import ca.uhn.fhir.jpa.rp.r4.MeasureResourceProvider; -import ca.uhn.fhir.jpa.rp.r4.ValueSetResourceProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; -import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4; -import ca.uhn.fhir.jpa.api.rp.ResourceProviderFactory; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; -import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.interceptor.CorsInterceptor; +import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; public class BaseServlet extends RestfulServer { @@ -80,6 +62,9 @@ protected void initialize() throws ServletException { IFhirSystemDao systemDao = appCtx.getBean("mySystemDaoR4", IFhirSystemDao.class); this.registry = appCtx.getBean(DaoRegistry.class); + DaoConfig daoConfig = appCtx.getBean(DaoConfig.class); + ISearchParamRegistry searchParamRegistry = appCtx.getBean(ISearchParamRegistry.class); + // System and Resource Providers Object systemProvider = appCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class); registerProvider(systemProvider); @@ -88,27 +73,26 @@ protected void initialize() throws ServletException { ResourceProviderFactory resourceProviders = appCtx.getBean("myResourceProvidersR4", ResourceProviderFactory.class); registerProviders(resourceProviders.createProviders()); + List> operationsProviders = appCtx.getBean("myOperationProvidersR4", List.class); + operationsProviders.forEach(x -> registerProvider(appCtx.getBean(x))); + if(HapiProperties.getOAuthEnabled()) { - OAuthProvider oauthProvider = new OAuthProvider(this, systemDao, - appCtx.getBean(DaoConfig.class), appCtx.getBean(ISearchParamRegistry.class)); - this.registerProvider(oauthProvider); - this.setServerConformanceProvider(oauthProvider); - }else { - JpaConformanceProviderR4 confProvider = new CqfRulerJpaConformanceProviderR4(this, systemDao, - appCtx.getBean(DaoConfig.class), appCtx.getBean(ISearchParamRegistry.class)); - confProvider.setImplementationDescription("CQF Ruler FHIR R4 Server"); - setServerConformanceProvider(confProvider); + OAuthProvider oauthProvider = new OAuthProvider(); + oauthProvider.setDaoConfig(daoConfig); + oauthProvider.setSystemDao(systemDao); + oauthProvider.setSearchParamRegistry(searchParamRegistry); + oauthProvider.setImplementationDescription("CQF Ruler FHIR R4 Server"); + this.setServerConformanceProvider(oauthProvider); + }else { + + CqfRulerJpaConformanceProviderR4 confProvider = new CqfRulerJpaConformanceProviderR4(); + confProvider.setDaoConfig(daoConfig); + confProvider.setSystemDao(systemDao); + confProvider.setSearchParamRegistry(searchParamRegistry); + confProvider.setImplementationDescription("CQF Ruler FHIR R4 Server"); + this.setServerConformanceProvider(confProvider); } - JpaTerminologyProvider localSystemTerminologyProvider = new JpaTerminologyProvider( - appCtx.getBean("terminologyService", ITermReadSvcR4.class), getFhirContext(), - (ValueSetResourceProvider) this.getResourceProvider(ValueSet.class)); - EvaluationProviderFactory providerFactory = new ProviderFactory(this.fhirContext, this.registry, localSystemTerminologyProvider); - - resolveProviders(providerFactory, localSystemTerminologyProvider, this.registry); - - // CdsHooksServlet.provider = provider; - /* * ETag Support */ @@ -184,85 +168,4 @@ protected void initialize() throws ServletException { registerInterceptor(interceptor); } } - - protected NarrativeProvider getNarrativeProvider() { - return new NarrativeProvider(); - } - - // Since resource provider resolution not lazy, the providers here must be - // resolved in the correct - // order of dependencies. - @SuppressWarnings("unchecked") - private void resolveProviders(EvaluationProviderFactory providerFactory, - JpaTerminologyProvider localSystemTerminologyProvider, DaoRegistry registry) throws ServletException { - NarrativeProvider narrativeProvider = this.getNarrativeProvider(); - HQMFProvider hqmfProvider = new HQMFProvider(); - - // Code System Update - CodeSystemUpdateProvider csUpdate = new CodeSystemUpdateProvider(this.getDao(ValueSet.class), this.getDao(CodeSystem.class)); - this.registerProvider(csUpdate); - - // Cache Value Sets - CacheValueSetsProvider cvs = new CacheValueSetsProvider(this.registry.getSystemDao(), this.getDao(Endpoint.class)); - this.registerProvider(cvs); - - // Library processing - LibraryOperationsProvider libraryProvider = new LibraryOperationsProvider( - (LibraryResourceProvider) this.getResourceProvider(Library.class), narrativeProvider, registry, localSystemTerminologyProvider); - this.registerProvider(libraryProvider); - - // CQL Execution - CqlExecutionProvider cql = new CqlExecutionProvider(libraryProvider, providerFactory, this.fhirContext); - this.registerProvider(cql); - - // Bundle processing - ApplyCqlOperationProvider bundleProvider = new ApplyCqlOperationProvider(providerFactory, - this.getDao(Bundle.class), this.fhirContext); - this.registerProvider(bundleProvider); - - // Measure processing - MeasureOperationsProvider measureProvider = new MeasureOperationsProvider(this.registry, providerFactory, - narrativeProvider, hqmfProvider, libraryProvider, - (MeasureResourceProvider) this.getResourceProvider(Measure.class)); - this.registerProvider(measureProvider); - - // // ActivityDefinition processing - ActivityDefinitionApplyProvider actDefProvider = new ActivityDefinitionApplyProvider(this.fhirContext, cql, - this.getDao(ActivityDefinition.class)); - this.registerProvider(actDefProvider); - - JpaFhirRetrieveProvider localSystemRetrieveProvider = new JpaFhirRetrieveProvider(registry, - new SearchParameterResolver(this.fhirContext)); - - // PlanDefinition processing - PlanDefinitionApplyProvider planDefProvider = new PlanDefinitionApplyProvider(this.fhirContext, actDefProvider, - this.getDao(PlanDefinition.class), this.getDao(ActivityDefinition.class), cql); - this.registerProvider(planDefProvider); - - CdsHooksServlet.setPlanDefinitionProvider(planDefProvider); - CdsHooksServlet.setLibraryResolutionProvider(libraryProvider); - CdsHooksServlet.setSystemTerminologyProvider(localSystemTerminologyProvider); - CdsHooksServlet.setSystemRetrieveProvider(localSystemRetrieveProvider); - - // QuestionnaireResponse processing - if(HapiProperties.getQuestionnaireResponseExtractEnabled()) { - QuestionnaireProvider questionnaireProvider = new QuestionnaireProvider(this.fhirContext); - this.registerProvider(questionnaireProvider); - } - // Observation processing - if(HapiProperties.getObservationTransformEnabled()) { - ObservationProvider observationProvider = new ObservationProvider(this.fhirContext); - this.registerProvider(observationProvider); - } - } - - protected IFhirResourceDao getDao(Class clazz) { - return this.registry.getResourceDao(clazz); - } - - @SuppressWarnings("unchecked") - protected BaseJpaResourceProvider getResourceProvider(Class clazz) { - return (BaseJpaResourceProvider) this.getResourceProviders().stream() - .filter(x -> x.getResourceType().getSimpleName().equals(clazz.getSimpleName())).findFirst().get(); - } } diff --git a/r4/src/main/java/org/opencds/cqf/r4/servlet/CdsHooksServlet.java b/r4/src/main/java/org/opencds/cqf/r4/servlet/CdsHooksServlet.java index 37489cac2..2658ef37c 100644 --- a/r4/src/main/java/org/opencds/cqf/r4/servlet/CdsHooksServlet.java +++ b/r4/src/main/java/org/opencds/cqf/r4/servlet/CdsHooksServlet.java @@ -50,6 +50,7 @@ import org.opencds.cqf.r4.providers.PlanDefinitionApplyProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; @@ -61,44 +62,32 @@ public class CdsHooksServlet extends HttpServlet { private FhirVersionEnum version = FhirVersionEnum.R4; private static final Logger logger = LoggerFactory.getLogger(CdsHooksServlet.class); - private static PlanDefinitionApplyProvider planDefinitionProvider; + private org.opencds.cqf.r4.providers.PlanDefinitionApplyProvider planDefinitionProvider; - private static LibraryResolutionProvider libraryResolutionProvider; + private LibraryResolutionProvider libraryResolutionProvider; - private static JpaFhirRetrieveProvider fhirRetrieveProvider; + private JpaFhirRetrieveProvider fhirRetrieveProvider; - private static JpaTerminologyProvider jpaTerminologyProvider; + private org.opencds.cqf.r4.providers.JpaTerminologyProvider jpaTerminologyProvider; private ProviderConfiguration providerConfiguration; - public ProviderConfiguration getProviderConfiguration() { - if (providerConfiguration == null) { - providerConfiguration = new ProviderConfiguration( - HapiProperties.getCdsHooksFhirServerExpandValueSets() , - HapiProperties.getCdsHooksFhirServerMaxCodesPerQuery(), - HapiProperties.getCdsHooksFhirServerSearchStyleEnum(), - HapiProperties.getCdsHooksPreFetchMaxUriLength()); - } - - return providerConfiguration; - } - - // TODO: There's probably a way to wire this all up using Spring - public static void setPlanDefinitionProvider(PlanDefinitionApplyProvider planDefinitionProvider) { - CdsHooksServlet.planDefinitionProvider = planDefinitionProvider; - } - - public static void setLibraryResolutionProvider( - LibraryResolutionProvider libraryResolutionProvider) { - CdsHooksServlet.libraryResolutionProvider = libraryResolutionProvider; - } - - public static void setSystemRetrieveProvider(JpaFhirRetrieveProvider fhirRetrieveProvider) { - CdsHooksServlet.fhirRetrieveProvider = fhirRetrieveProvider; + @SuppressWarnings("unchecked") + @Override + public void init() { + // System level providers + ApplicationContext appCtx = (ApplicationContext) getServletContext() + .getAttribute("org.springframework.web.context.WebApplicationContext.ROOT"); + + this.providerConfiguration = appCtx.getBean(ProviderConfiguration.class); + this.planDefinitionProvider = appCtx.getBean(PlanDefinitionApplyProvider.class); + this.libraryResolutionProvider = (LibraryResolutionProvider)appCtx.getBean(LibraryResolutionProvider.class); + this.fhirRetrieveProvider = appCtx.getBean(JpaFhirRetrieveProvider.class); + this.jpaTerminologyProvider = appCtx.getBean(JpaTerminologyProvider.class); } - public static void setSystemTerminologyProvider(JpaTerminologyProvider jpaTerminologyProvider) { - CdsHooksServlet.jpaTerminologyProvider = jpaTerminologyProvider; + protected ProviderConfiguration getProviderConfiguration() { + return this.providerConfiguration; } // CORS Pre-flight