add valueset cache and cache invalidation listeners

This commit is contained in:
Justin McKelvy
2023-10-11 15:16:17 -06:00
parent 3a0b42b265
commit 6d10c0bade
5 changed files with 136 additions and 68 deletions

View File

@@ -14,7 +14,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>6.9.9-SNAPSHOT</version>
<version>6.9.10-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-jpaserver-starter</artifactId>

View File

@@ -0,0 +1,85 @@
package ca.uhn.fhir.jpa.starter.cr;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.cr.common.CodeCacheResourceChangeListener;
import ca.uhn.fhir.cr.common.ElmCacheResourceChangeListener;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCacheRefresher;
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry;
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerCacheFactory;
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerCacheRefresherImpl;
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryImpl;
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryInterceptor;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
import org.cqframework.cql.cql2elm.model.Model;
import org.hl7.cql.model.ModelIdentifier;
import org.hl7.elm.r1.VersionedIdentifier;
import org.opencds.cqf.cql.engine.runtime.Code;
import org.opencds.cqf.fhir.cql.EvaluationSettings;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Configuration
public class BaseCrConfig {
@Bean
public Map<VersionedIdentifier, CompiledLibrary> globalLibraryCache() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<ModelIdentifier, Model> globalModelCache() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<String, List<Code>> globalValueSetCache() {
return new ConcurrentHashMap<>();
}
@Bean
public ElmCacheResourceChangeListener elmCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry,
DaoRegistry theDaoRegistry,
EvaluationSettings theEvaluationSettings) {
ElmCacheResourceChangeListener listener =
new ElmCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getLibraryCache());
theResourceChangeListenerRegistry.registerResourceResourceChangeListener(
"Library", SearchParameterMap.newSynchronous(), listener, 1000);
return listener;
}
@Bean
public CodeCacheResourceChangeListener codeCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry,
EvaluationSettings theEvaluationSettings,
DaoRegistry theDaoRegistry) {
CodeCacheResourceChangeListener listener = new CodeCacheResourceChangeListener(theDaoRegistry, theEvaluationSettings.getValueSetCache());
//registry
theResourceChangeListenerRegistry.registerResourceResourceChangeListener(
"ValueSet", SearchParameterMap.newSynchronous(), listener,1000);
return listener;
}
@Bean
public IResourceChangeListenerRegistry resourceChangeListenerRegistry(InMemoryResourceMatcher theInMemoryResourceMatcher, FhirContext theFhirContext, ResourceChangeListenerCacheFactory theResourceChangeListenerCacheFactory) {
return new ResourceChangeListenerRegistryImpl(theFhirContext, theResourceChangeListenerCacheFactory, theInMemoryResourceMatcher);
}
@Bean
IResourceChangeListenerCacheRefresher resourceChangeListenerCacheRefresher() {
return new ResourceChangeListenerCacheRefresherImpl();
}
@Bean
public ResourceChangeListenerRegistryInterceptor resourceChangeListenerRegistryInterceptor() {
return new ResourceChangeListenerRegistryInterceptor();
}
}

View File

@@ -17,7 +17,6 @@ import ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionApplyProvider;
import ca.uhn.fhir.cr.r4.cqlexecution.CqlExecutionOperationProvider;
import ca.uhn.fhir.cr.r4.measure.CareGapsOperationProvider;
import ca.uhn.fhir.cr.r4.measure.MeasureOperationsProvider;
import ca.uhn.fhir.cr.r4.measure.MeasureService;
import ca.uhn.fhir.cr.r4.measure.SubmitDataProvider;
import ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionApplyProvider;
import ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionPackageProvider;
@@ -31,6 +30,7 @@ import org.opencds.cqf.fhir.cr.cql.r4.R4CqlExecutionService;
import org.opencds.cqf.fhir.cr.measure.CareGapsProperties;
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions;
import org.opencds.cqf.fhir.cr.measure.r4.R4CareGapsService;
import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureService;
import org.opencds.cqf.fhir.cr.measure.r4.R4SubmitDataService;
import org.opencds.cqf.fhir.cr.plandefinition.r4.PlanDefinitionProcessor;
import org.opencds.cqf.fhir.cr.questionnaire.r4.QuestionnaireProcessor;
@@ -50,7 +50,7 @@ public class CrR4Config {
@Bean
IMeasureServiceFactory r4MeasureServiceFactory(
IRepositoryFactory theRepositoryFactory, MeasureEvaluationOptions theEvaluationOptions) {
return rd -> new MeasureService(theRepositoryFactory.create(rd), theEvaluationOptions);
return rd -> new R4MeasureService(theRepositoryFactory.create(rd), theEvaluationOptions);
}
@Bean

View File

@@ -15,6 +15,7 @@ import org.cqframework.cql.cql2elm.model.Model;
import org.hl7.cql.model.ModelIdentifier;
import org.hl7.elm.r1.VersionedIdentifier;
import org.opencds.cqf.cql.engine.execution.CqlEngine;
import org.opencds.cqf.cql.engine.runtime.Code;
import org.opencds.cqf.fhir.cql.EvaluationSettings;
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions;
import org.opencds.cqf.fhir.utility.ValidationProfile;
@@ -23,6 +24,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.*;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -33,7 +35,7 @@ import java.util.concurrent.ConcurrentHashMap;
ApplyOperationConfig.class,
ExtractOperationConfig.class,
PackageOperationConfig.class,
PopulateOperationConfig.class})
PopulateOperationConfig.class, BaseCrConfig.class})
public class StarterCrDstu3Config {
private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrDstu3Config.class);
@@ -52,7 +54,8 @@ public class StarterCrDstu3Config {
public EvaluationSettings evaluationSettings(
AppProperties theAppProperties,
Map<VersionedIdentifier, CompiledLibrary> theGlobalLibraryCache,
Map<ModelIdentifier, Model> theGlobalModelCache) {
Map<ModelIdentifier, Model> theGlobalModelCache,
Map<String, List<Code>> theGlobalValueSetCache) {
var evaluationSettings = EvaluationSettings.getDefault();
var cqlOptions = evaluationSettings.getCqlOptions();
@@ -120,19 +123,10 @@ public class StarterCrDstu3Config {
cqlOptions.setCqlCompilerOptions(cqlCompilerOptions);
evaluationSettings.setLibraryCache(theGlobalLibraryCache);
evaluationSettings.setModelCache(theGlobalModelCache);
evaluationSettings.setValueSetCache(theGlobalValueSetCache);
return evaluationSettings;
}
@Bean
public Map<VersionedIdentifier, CompiledLibrary> globalLibraryCache() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<ModelIdentifier, Model> globalModelCache() {
return new ConcurrentHashMap<>();
}
@Bean
public PostInitProviderRegisterer postInitProviderRegisterer(RestfulServer theRestfulServer,
ResourceProviderFactory theResourceProviderFactory) {

View File

@@ -1,13 +1,9 @@
package ca.uhn.fhir.jpa.starter.cr;
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.cr.common.CqlThreadFactory;
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.starter.AppProperties;
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
@@ -15,6 +11,7 @@ import org.cqframework.cql.cql2elm.model.Model;
import org.hl7.cql.model.ModelIdentifier;
import org.hl7.elm.r1.VersionedIdentifier;
import org.opencds.cqf.cql.engine.execution.CqlEngine;
import org.opencds.cqf.cql.engine.runtime.Code;
import org.opencds.cqf.fhir.cql.EvaluationSettings;
import org.opencds.cqf.fhir.cr.measure.CareGapsProperties;
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions;
@@ -25,15 +22,15 @@ import org.springframework.context.annotation.*;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Configuration
@Conditional({ OnR4Condition.class, CrConfigCondition.class })
@Import(CrR4Config.class)
@Import({BaseCrConfig.class, CrR4Config.class})
public class StarterCrR4Config {
private static final Logger ourLogger = LoggerFactory.getLogger(StarterCrR4Config.class);
@@ -72,7 +69,8 @@ public class StarterCrR4Config {
public EvaluationSettings evaluationSettings(
AppProperties theAppProperties,
Map<VersionedIdentifier, CompiledLibrary> theGlobalLibraryCache,
Map<ModelIdentifier, Model> theGlobalModelCache) {
Map<ModelIdentifier, Model> theGlobalModelCache,
Map<String, List<Code>> theGlobalValueSetCache) {
var evaluationSettings = EvaluationSettings.getDefault();
var cqlOptions = evaluationSettings.getCqlOptions();
@@ -140,19 +138,10 @@ public class StarterCrR4Config {
cqlOptions.setCqlCompilerOptions(cqlCompilerOptions);
evaluationSettings.setLibraryCache(theGlobalLibraryCache);
evaluationSettings.setModelCache(theGlobalModelCache);
evaluationSettings.setValueSetCache(theGlobalValueSetCache);
return evaluationSettings;
}
@Bean
public Map<VersionedIdentifier, CompiledLibrary> globalLibraryCache() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<ModelIdentifier, Model> globalModelCache() {
return new ConcurrentHashMap<>();
}
@Bean
public PostInitProviderRegisterer postInitProviderRegisterer(RestfulServer theRestfulServer,
ResourceProviderFactory theResourceProviderFactory) {