Add a bit of logging for search parameters when they can't be found

This commit is contained in:
James Agnew 2019-04-10 20:32:36 -04:00
parent bb98ded1fa
commit 380644d19d
4 changed files with 47 additions and 6 deletions

View File

@ -73,14 +73,17 @@ public abstract class BaseConfig implements SchedulingConfigurer {
@Autowired @Autowired
protected Environment myEnv; protected Environment myEnv;
@Autowired
protected DaoRegistry myDaoRegistry;
@Override @Override
public void configureTasks(@Nonnull ScheduledTaskRegistrar theTaskRegistrar) { public void configureTasks(@Nonnull ScheduledTaskRegistrar theTaskRegistrar) {
theTaskRegistrar.setTaskScheduler(taskScheduler()); theTaskRegistrar.setTaskScheduler(taskScheduler());
} }
@Bean("myDaoRegistry")
public DaoRegistry daoRegistry() {
return new DaoRegistry();
}
@Bean(autowire = Autowire.BY_TYPE) @Bean(autowire = Autowire.BY_TYPE)
public DatabaseBackedPagingProvider databaseBackedPagingProvider() { public DatabaseBackedPagingProvider databaseBackedPagingProvider() {
return new DatabaseBackedPagingProvider(); return new DatabaseBackedPagingProvider();
@ -182,7 +185,7 @@ public abstract class BaseConfig implements SchedulingConfigurer {
* Subclasses may override * Subclasses may override
*/ */
protected boolean isSupported(String theResourceType) { protected boolean isSupported(String theResourceType) {
return myDaoRegistry.getResourceDao(theResourceType) != null; return daoRegistry().getResourceDao(theResourceType) != null;
} }
public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) { public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) {

View File

@ -35,13 +35,20 @@ import org.springframework.stereotype.Component;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component("myDaoRegistry")
public class DaoRegistry implements ApplicationContextAware { public class DaoRegistry implements ApplicationContextAware {
private ApplicationContext myAppCtx; private ApplicationContext myAppCtx;
@Autowired @Autowired
private FhirContext myContext; private FhirContext myContext;
/**
* Constructor
*/
public DaoRegistry() {
super();
}
private volatile Map<String, IFhirResourceDao<?>> myResourceNameToResourceDao; private volatile Map<String, IFhirResourceDao<?>> myResourceNameToResourceDao;
private volatile IFhirSystemDao<?, ?> mySystemDao; private volatile IFhirSystemDao<?, ?> mySystemDao;
private Set<String> mySupportedResourceTypes; private Set<String> mySupportedResourceTypes;

View File

@ -1027,6 +1027,7 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test {
} }
@Test @Test
public void testUniqueValuesAreIndexed_DateAndToken() { public void testUniqueValuesAreIndexed_DateAndToken() {
createUniqueBirthdateAndGenderSps(); createUniqueBirthdateAndGenderSps();

View File

@ -24,6 +24,9 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.model.search.PerformanceMessage;
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.retry.Retrier; import ca.uhn.fhir.jpa.searchparam.retry.Retrier;
@ -41,6 +44,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
@ -63,6 +67,9 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
private volatile Map<String, Map<String, RuntimeSearchParam>> myActiveSearchParams; private volatile Map<String, Map<String, RuntimeSearchParam>> myActiveSearchParams;
private volatile long myLastRefresh; private volatile long myLastRefresh;
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster;
@Override @Override
public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) {
@ -121,6 +128,7 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
} }
private void populateActiveSearchParams(Map<String, Map<String, RuntimeSearchParam>> theActiveSearchParams) { private void populateActiveSearchParams(Map<String, Map<String, RuntimeSearchParam>> theActiveSearchParams) {
Map<String, List<JpaRuntimeSearchParam>> activeUniqueSearchParams = new HashMap<>(); Map<String, List<JpaRuntimeSearchParam>> activeUniqueSearchParams = new HashMap<>();
Map<String, Map<Set<String>, List<JpaRuntimeSearchParam>>> activeParamNamesToUniqueSearchParams = new HashMap<>(); Map<String, Map<Set<String>, List<JpaRuntimeSearchParam>>> activeParamNamesToUniqueSearchParams = new HashMap<>();
@ -133,8 +141,13 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
for (Map.Entry<String, Map<String, RuntimeSearchParam>> nextResourceNameToEntries : theActiveSearchParams.entrySet()) { for (Map.Entry<String, Map<String, RuntimeSearchParam>> nextResourceNameToEntries : theActiveSearchParams.entrySet()) {
List<JpaRuntimeSearchParam> uniqueSearchParams = activeUniqueSearchParams.computeIfAbsent(nextResourceNameToEntries.getKey(), k -> new ArrayList<>()); List<JpaRuntimeSearchParam> uniqueSearchParams = activeUniqueSearchParams.computeIfAbsent(nextResourceNameToEntries.getKey(), k -> new ArrayList<>());
Collection<RuntimeSearchParam> nextSearchParamsForResourceName = nextResourceNameToEntries.getValue().values(); Collection<RuntimeSearchParam> nextSearchParamsForResourceName = nextResourceNameToEntries.getValue().values();
ourLog.trace("Resource {} has {} params", nextResourceNameToEntries.getKey(), nextResourceNameToEntries.getValue().size());
for (RuntimeSearchParam nextCandidate : nextSearchParamsForResourceName) { for (RuntimeSearchParam nextCandidate : nextSearchParamsForResourceName) {
ourLog.trace("Resource {} has parameter {} with ID {}", nextResourceNameToEntries.getKey(), nextCandidate.getName(), nextCandidate.getId());
if (nextCandidate.getId() != null) { if (nextCandidate.getId() != null) {
idToRuntimeSearchParam.put(nextCandidate.getId().toUnqualifiedVersionless().getValue(), nextCandidate); idToRuntimeSearchParam.put(nextCandidate.getId().toUnqualifiedVersionless().getValue(), nextCandidate);
} }
@ -150,6 +163,8 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
} }
ourLog.trace("Have {} search params loaded", idToRuntimeSearchParam.size());
Set<String> haveSeen = new HashSet<>(); Set<String> haveSeen = new HashSet<>();
for (JpaRuntimeSearchParam next : jpaSearchParams) { for (JpaRuntimeSearchParam next : jpaSearchParams) {
if (!haveSeen.add(next.getId().toUnqualifiedVersionless().getValue())) { if (!haveSeen.add(next.getId().toUnqualifiedVersionless().getValue())) {
@ -164,7 +179,14 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
next.getCompositeOf().add(componentTarget); next.getCompositeOf().add(componentTarget);
paramNames.add(componentTarget.getName()); paramNames.add(componentTarget.getName());
} else { } else {
ourLog.warn("Search parameter {} refers to unknown component {}", next.getId().toUnqualifiedVersionless().getValue(), nextRef); String existingParams = idToRuntimeSearchParam
.keySet()
.stream()
.sorted()
.collect(Collectors.joining(", "));
String message = "Search parameter " + next.getId().toUnqualifiedVersionless().getValue() + " refers to unknown component " + nextRef + ", ignoring this parameter (valid values: " + existingParams + ")";
ourLog.warn(message);
myInterceptorBroadcaster.callHooks(Pointcut.PERFTRACE_MESSAGE, new PerformanceMessage().setMessage(message));
} }
} }
@ -182,6 +204,8 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
} }
} }
ourLog.trace("Have {} unique search params", activeParamNamesToUniqueSearchParams.size());
myActiveUniqueSearchParams = activeUniqueSearchParams; myActiveUniqueSearchParams = activeUniqueSearchParams;
myActiveParamNamesToUniqueSearchParams = activeParamNamesToUniqueSearchParams; myActiveParamNamesToUniqueSearchParams = activeParamNamesToUniqueSearchParams;
} }
@ -225,12 +249,15 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
IBundleProvider allSearchParamsBp = mySearchParamProvider.search(params); IBundleProvider allSearchParamsBp = mySearchParamProvider.search(params);
int size = allSearchParamsBp.size(); int size = allSearchParamsBp.size();
ourLog.trace("Loaded {} search params from the DB", size);
// Just in case.. // Just in case..
if (size >= MAX_MANAGED_PARAM_COUNT) { if (size >= MAX_MANAGED_PARAM_COUNT) {
ourLog.warn("Unable to support >" + MAX_MANAGED_PARAM_COUNT + " search params!"); ourLog.warn("Unable to support >" + MAX_MANAGED_PARAM_COUNT + " search params!");
size = MAX_MANAGED_PARAM_COUNT; size = MAX_MANAGED_PARAM_COUNT;
} }
int overriddenCount = 0;
List<IBaseResource> allSearchParams = allSearchParamsBp.getResources(0, size); List<IBaseResource> allSearchParams = allSearchParamsBp.getResources(0, size);
for (IBaseResource nextResource : allSearchParams) { for (IBaseResource nextResource : allSearchParams) {
SP nextSp = (SP) nextResource; SP nextSp = (SP) nextResource;
@ -252,11 +279,14 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
String name = runtimeSp.getName(); String name = runtimeSp.getName();
if (myModelConfig.isDefaultSearchParamsCanBeOverridden() || !searchParamMap.containsKey(name)) { if (myModelConfig.isDefaultSearchParamsCanBeOverridden() || !searchParamMap.containsKey(name)) {
searchParamMap.put(name, runtimeSp); searchParamMap.put(name, runtimeSp);
overriddenCount++;
} }
} }
} }
ourLog.trace("Have overridden {} built-in search parameters", overriddenCount);
Map<String, Map<String, RuntimeSearchParam>> activeSearchParams = new HashMap<>(); Map<String, Map<String, RuntimeSearchParam>> activeSearchParams = new HashMap<>();
for (Map.Entry<String, Map<String, RuntimeSearchParam>> nextEntry : searchParams.entrySet()) { for (Map.Entry<String, Map<String, RuntimeSearchParam>> nextEntry : searchParams.entrySet()) {
for (RuntimeSearchParam nextSp : nextEntry.getValue().values()) { for (RuntimeSearchParam nextSp : nextEntry.getValue().values()) {
@ -323,7 +353,7 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
int refreshCacheWithRetry() { int refreshCacheWithRetry() {
Retrier<Integer> refreshCacheRetrier = new Retrier(() -> { Retrier<Integer> refreshCacheRetrier = new Retrier(() -> {
synchronized(BaseSearchParamRegistry.this) { synchronized (BaseSearchParamRegistry.this) {
return mySearchParamProvider.refreshCache(this, REFRESH_INTERVAL); return mySearchParamProvider.refreshCache(this, REFRESH_INTERVAL);
} }
}, MAX_RETRIES); }, MAX_RETRIES);