From 2083b7ca748c11d63d4bfa9562ef73d83a9ede40 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Tue, 28 Feb 2023 13:42:08 -0500 Subject: [PATCH] Flush SP cache after SP change (#4566) * Flush SP cache after SP change * Add changelog * Test fix --- .../4566-flush-sp-cache-after-sp-change.yaml | 6 ++++++ .../jpa/dao/JpaResourceDaoSearchParameter.java | 17 +++++++++++++++++ ...esourceDaoR4SearchCustomSearchParamTest.java | 6 ++++-- ...ResourceProviderCustomSearchParamR4Test.java | 4 ---- 4 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4566-flush-sp-cache-after-sp-change.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4566-flush-sp-cache-after-sp-change.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4566-flush-sp-cache-after-sp-change.yaml new file mode 100644 index 00000000000..82c981df95f --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4566-flush-sp-cache-after-sp-change.yaml @@ -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." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaResourceDaoSearchParameter.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaResourceDaoSearchParameter.java index 56e6b42e609..4ff2e684dd2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaResourceDaoSearchParameter.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaResourceDaoSearchParameter.java @@ -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 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; diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java index c6a8c78b1c2..406b1fc398d 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java @@ -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 paramsCaptor = ArgumentCaptor.forClass(HookParams.class); verify(interceptor, times(1)).invoke(any(), paramsCaptor.capture()); diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java index 261c04a8a69..22f2e3e19df 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java @@ -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();