Flush SP cache after SP change (#4566)

* Flush SP cache after SP change

* Add changelog

* Test fix
This commit is contained in:
James Agnew 2023-02-28 13:42:08 -05:00 committed by GitHub
parent ec13b751fe
commit 2083b7ca74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 6 deletions

View File

@ -0,0 +1,6 @@
---
type: add
issue: 4566
title: "When creating or modifying a SearchParameter in the JPA server, the local SearchParameter cache
is now immediately flushed. This should help with situations such as tests where a SearchParameter
is created and then used before the scheduled cache refresh typically occurs."

View File

@ -9,6 +9,8 @@ import com.google.common.annotations.VisibleForTesting;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.CodeType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.List;
import java.util.stream.Collectors;
@ -42,6 +44,21 @@ public class JpaResourceDaoSearchParameter<T extends IBaseResource> extends Base
private SearchParameterDaoValidator mySearchParameterDaoValidator;
protected void reindexAffectedResources(T theResource, RequestDetails theRequestDetails) {
/*
* After we commit, flush the search parameter cache. This only helps on the
* local server (ie in a cluster the other servers won't be flushed) but
* the cache is short anyhow, and flushing locally is better than nothing.
* Many use cases where you would create a search parameter and immediately
* try to use it tend to be on single-server setups anyhow, e.g. unit tests
*/
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
mySearchParamRegistry.forceRefresh();
}
});
// N.B. Don't do this on the canonicalized version
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;

View File

@ -1744,6 +1744,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
@Test
public void testCompositeWithInvalidTarget() {
// Setup
SearchParameter sp = new SearchParameter();
sp.addBase("Patient");
sp.setCode("myDoctor");
@ -1752,14 +1753,15 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
sp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE);
sp.addComponent()
.setDefinition("http://foo");
mySearchParameterDao.create(sp);
IAnonymousInterceptor interceptor = mock(IAnonymousInterceptor.class);
myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.JPA_PERFTRACE_WARNING, interceptor);
try {
mySearchParamRegistry.forceRefresh();
// Test
mySearchParameterDao.create(sp);
// Verify
ArgumentCaptor<HookParams> paramsCaptor = ArgumentCaptor.forClass(HookParams.class);
verify(interceptor, times(1)).invoke(any(), paramsCaptor.capture());

View File

@ -401,10 +401,6 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
fooSp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE);
mySearchParameterDao.create(fooSp, mySrd);
myCaptureQueriesListener.clear();
mySearchParamRegistry.forceRefresh();
myCaptureQueriesListener.logAllQueriesForCurrentThread();
Patient pat = new Patient();
pat.setGender(AdministrativeGender.MALE);
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();