diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
index 9161e8419d2..4af1b5ee0f8 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
@@ -10,6 +10,7 @@ import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.interceptor.api.HookParams;
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.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java
index 447f45fffa0..739122096fe 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/IdHelperService.java
@@ -23,7 +23,9 @@ package ca.uhn.fhir.jpa.dao.index;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.model.entity.ForcedId;
-import ca.uhn.fhir.model.dstu2.resource.Specimen;
+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.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import com.google.common.collect.ListMultimap;
@@ -43,6 +45,8 @@ public class IdHelperService {
protected IForcedIdDao myForcedIdDao;
@Autowired(required = true)
private DaoConfig myDaoConfig;
+ @Autowired
+ private IInterceptorBroadcaster myInterceptorBroadcaster;
public void delete(ForcedId forcedId) {
myForcedIdDao.delete(forcedId);
@@ -51,7 +55,7 @@ public class IdHelperService {
public Long translateForcedIdToPid(String theResourceName, String theResourceId) throws ResourceNotFoundException {
// We only pass 1 input in so only 0..1 will come back
IdDt id = new IdDt(theResourceName, theResourceId);
- List matches = translateForcedIdToPids(myDaoConfig, myForcedIdDao, Collections.singletonList(id));
+ List matches = translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, myForcedIdDao, Collections.singletonList(id));
assert matches.size() <= 1;
if (matches.isEmpty()) {
throw new ResourceNotFoundException(id);
@@ -60,10 +64,10 @@ public class IdHelperService {
}
public List translateForcedIdToPids(Collection theId) {
- return IdHelperService.translateForcedIdToPids(myDaoConfig, myForcedIdDao, theId);
+ return IdHelperService.translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, myForcedIdDao, theId);
}
- static List translateForcedIdToPids(DaoConfig theDaoConfig, IForcedIdDao theForcedIdDao, Collection theId) {
+ static List translateForcedIdToPids(DaoConfig theDaoConfig, IInterceptorBroadcaster theInterceptorBroadcaster, IForcedIdDao theForcedIdDao, Collection theId) {
theId.forEach(id -> Validate.isTrue(id.hasIdPart()));
if (theId.isEmpty()) {
@@ -89,7 +93,13 @@ public class IdHelperService {
String nextResourceType = nextEntry.getKey();
Collection nextIds = nextEntry.getValue();
if (isBlank(nextResourceType)) {
+
+ PerformanceMessage msg = new PerformanceMessage()
+ .setMessage("This search uses unqualified resource IDs (an ID without a resource type). This is less efficient than using a qualified type.");
+ theInterceptorBroadcaster.callHooks(Pointcut.PERFTRACE_MESSAGE, msg);
+
retVal.addAll(theForcedIdDao.findByForcedId(nextIds));
+
} else {
retVal.addAll(theForcedIdDao.findByTypeAndForcedId(nextResourceType, nextIds));
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java
index a9b0408baa2..0c85f1d44e4 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java
@@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.entity;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.param.DateRangeParam;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/PerformanceTracingLoggingInterceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/PerformanceTracingLoggingInterceptor.java
index 3711a2c5a36..f75162f690f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/PerformanceTracingLoggingInterceptor.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/PerformanceTracingLoggingInterceptor.java
@@ -7,24 +7,25 @@ import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.util.LogUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.event.Level;
@Interceptor(manualRegistration = true)
public class PerformanceTracingLoggingInterceptor {
private static final Logger ourLog = LoggerFactory.getLogger(PerformanceTracingLoggingInterceptor.class);
private final Logger myLog;
- private final LogUtil.Level myLevel;
+ private final Level myLevel;
/**
* Constructor that logs to this class with a level of INFO
*/
public PerformanceTracingLoggingInterceptor() {
- this(ourLog, LogUtil.Level.INFO);
+ this(ourLog, Level.INFO);
}
/**
* Constructor that logs to a custom logger and level
*/
- public PerformanceTracingLoggingInterceptor(Logger theLog, LogUtil.Level theLevel) {
+ public PerformanceTracingLoggingInterceptor(Logger theLog, Level theLevel) {
myLog = theLog;
myLevel = theLevel;
}
@@ -39,6 +40,21 @@ public class PerformanceTracingLoggingInterceptor {
log("Query found {} matches in {} for query {}", theOutcome.getFoundMatchesCount(), theOutcome.getQueryStopwatch(), theOutcome.getSearchUuid());
}
+ @Hook(value = Pointcut.PERFTRACE_SEARCH_COMPLETE)
+ public void searchComplete(SearchRuntimeDetails theOutcome) {
+ log("Query {} is complete in {} - Found {} matches", theOutcome.getSearchUuid(), theOutcome.getQueryStopwatch(), theOutcome.getFoundMatchesCount());
+ }
+
+ @Hook(value = Pointcut.PERFTRACE_SEARCH_PASS_COMPLETE)
+ public void searchPassComplete(SearchRuntimeDetails theOutcome) {
+ log("Query {} pass complete and set to status {} in {} - Found {} matches", theOutcome.getSearchUuid(), theOutcome.getSearchStatus(), theOutcome.getQueryStopwatch(), theOutcome.getFoundMatchesCount());
+ }
+
+ @Hook(value = Pointcut.PERFTRACE_SEARCH_FAILED)
+ public void searchFailed(SearchRuntimeDetails theOutcome) {
+ log("Query {} failed in {} - Found {} matches", theOutcome.getSearchUuid(), theOutcome.getQueryStopwatch(), theOutcome.getFoundMatchesCount());
+ }
+
private void log(String theMessage, Object... theArgs) {
LogUtil.log(myLog, myLevel, theMessage, theArgs);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaSearchFirstPageBundleProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaSearchFirstPageBundleProvider.java
index 0afd31f2b16..a8d7a668f9b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaSearchFirstPageBundleProvider.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaSearchFirstPageBundleProvider.java
@@ -26,16 +26,13 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.entity.Search;
-import ca.uhn.fhir.jpa.entity.SearchStatusEnum;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl.SearchTask;
-import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class PersistedJpaSearchFirstPageBundleProvider extends PersistedJpaBundleProvider {
private static final Logger ourLog = LoggerFactory.getLogger(PersistedJpaSearchFirstPageBundleProvider.class);
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java
index 6dbf994f7e0..68f375582d2 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java
@@ -26,6 +26,9 @@ import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.dao.data.ISearchIncludeDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.*;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
+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.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.Include;
@@ -70,6 +73,7 @@ import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import java.util.*;
+import java.util.List;
import java.util.concurrent.*;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
@@ -97,6 +101,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
@Autowired
private ISearchResultDao mySearchResultDao;
@Autowired
+ private IInterceptorBroadcaster myInterceptorBroadcaster;
+ @Autowired
private PlatformTransactionManager myManagedTxManager;
@Autowired
private DaoRegistry myDaoRegistry;
@@ -704,7 +710,13 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
}
});
-// FIXME: JA interceptor
+ mySearchRuntimeDetails.setSearchStatus(mySearch.getStatus());
+ if (mySearch.getStatus() == SearchStatusEnum.FINISHED) {
+ myInterceptorBroadcaster.callHooks(Pointcut.PERFTRACE_SEARCH_COMPLETE, mySearchRuntimeDetails);
+ } else {
+ myInterceptorBroadcaster.callHooks(Pointcut.PERFTRACE_SEARCH_PASS_COMPLETE, mySearchRuntimeDetails);
+ }
+
ourLog.info("Have completed search for [{}{}] and found {} resources in {}ms - Status is {}", mySearch.getResourceType(), mySearch.getSearchQueryString(), mySyncedPids.size(), sw.getMillis(), mySearch.getStatus());
} catch (Throwable t) {
@@ -742,6 +754,9 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
mySearch.setFailureCode(failureCode);
mySearch.setStatus(SearchStatusEnum.FAILED);
+ mySearchRuntimeDetails.setSearchStatus(mySearch.getStatus());
+ myInterceptorBroadcaster.callHooks(Pointcut.PERFTRACE_SEARCH_FAILED, mySearchRuntimeDetails);
+
saveSearch();
} finally {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionInterceptorLoader.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionInterceptorLoader.java
index 5af1faf0591..86bb3be4d14 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionInterceptorLoader.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionInterceptorLoader.java
@@ -57,12 +57,12 @@ public class SubscriptionInterceptorLoader {
if (!supportedSubscriptionTypes.isEmpty()) {
loadSubscriptions();
ourLog.info("Registering subscription activating interceptor");
- myInterceptorRegistry.registerInterceptor(mySubscriptionActivatingInterceptor);
+ myInterceptorRegistry.registerAnonymousInterceptor(mySubscriptionActivatingInterceptor);
}
if (myDaoConfig.isSubscriptionMatchingEnabled()) {
mySubscriptionMatcherInterceptor.start();
ourLog.info("Registering subscription matcher interceptor");
- myInterceptorRegistry.registerInterceptor(mySubscriptionMatcherInterceptor);
+ myInterceptorRegistry.registerAnonymousInterceptor(mySubscriptionMatcherInterceptor);
}
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
index 89e2d1998bf..cb81f0d3af5 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
@@ -142,7 +142,7 @@ public abstract class BaseJpaTest {
protected CountDownLatch registerLatchHookInterceptor(int theCount, Pointcut theLatchPointcut) {
CountDownLatch deliveryLatch = new CountDownLatch(theCount);
- myInterceptorRegistry.registerAnonymousHookForUnitTest(theLatchPointcut, Integer.MAX_VALUE, t -> deliveryLatch.countDown());
+ myInterceptorRegistry.registerAnonymousInterceptor(theLatchPointcut, Integer.MAX_VALUE, (thePointcut, t) -> deliveryLatch.countDown());
return deliveryLatch;
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
index f6bf6eced40..ea055cc50db 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
@@ -323,7 +323,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
myDaoConfig.setInterceptors(myInterceptor);
myPerformanceTracingLoggingInterceptor = new PerformanceTracingLoggingInterceptor();
- myInterceptorRegistry.registerInterceptor(myPerformanceTracingLoggingInterceptor);
+ myInterceptorRegistry.registerAnonymousInterceptor(myPerformanceTracingLoggingInterceptor);
}
@Before
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java
index 0b497388698..119c07a00bd 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchOptimizedTest.java
@@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.entity.Search;
-import ca.uhn.fhir.jpa.entity.SearchStatusEnum;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java
index 1dd6c8a479d..17b3bf93c4a 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java
@@ -4,7 +4,7 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.entity.Search;
-import ca.uhn.fhir.jpa.entity.SearchStatusEnum;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl;
import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.util.StopWatch;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java
index 47c1164da76..68c3e70202c 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4Test.java
@@ -5,7 +5,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.entity.Search;
-import ca.uhn.fhir.jpa.entity.SearchStatusEnum;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CompositionDocumentR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CompositionDocumentR4Test.java
index 0efacbe93a6..a2bbbc981c0 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CompositionDocumentR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/CompositionDocumentR4Test.java
@@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.interceptor.api.HookParams;
-import ca.uhn.fhir.jpa.model.interceptor.api.IAnonymousLambdaHook;
+import ca.uhn.fhir.jpa.model.interceptor.api.IAnonymousInterceptor;
import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.rest.api.EncodingEnum;
@@ -32,6 +32,7 @@ import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -137,13 +138,13 @@ public class CompositionDocumentR4Test extends BaseResourceProviderR4Test {
@Test
public void testInterceptorHookIsCalledForAllContents_RESOURCE_MAY_BE_RETURNED() throws IOException {
- IAnonymousLambdaHook pointcut = mock(IAnonymousLambdaHook.class);
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.RESOURCE_MAY_BE_RETURNED, pointcut);
+ IAnonymousInterceptor pointcut = mock(IAnonymousInterceptor.class);
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.RESOURCE_MAY_BE_RETURNED, pointcut);
String theUrl = ourServerBase + "/" + compId + "/$document?_format=json";
fetchBundle(theUrl, EncodingEnum.JSON);
- Mockito.verify(pointcut, times(10)).invoke(myHookParamsCaptor.capture());
+ Mockito.verify(pointcut, times(10)).invoke(eq(Pointcut.RESOURCE_MAY_BE_RETURNED), myHookParamsCaptor.capture());
List returnedClasses = myHookParamsCaptor
.getAllValues()
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java
index 74c9f355e40..67db89bd729 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/HookInterceptorR4Test.java
@@ -17,7 +17,7 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
@Test
public void testOP_PRESTORAGE_RESOURCE_CREATED_ModifyResource() {
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.OP_PRESTORAGE_RESOURCE_CREATED, t->{
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.OP_PRESTORAGE_RESOURCE_CREATED, (thePointcut, t)->{
Patient contents = (Patient) t.get(IBaseResource.class, 0);
contents.getNameFirstRep().setFamily("NEWFAMILY");
});
@@ -36,7 +36,7 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
@Test
public void testOP_PRECOMMIT_RESOURCE_CREATED_ModifyResource() {
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.OP_PRECOMMIT_RESOURCE_CREATED, t->{
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.OP_PRECOMMIT_RESOURCE_CREATED, (thePointcut, t)->{
Patient contents = (Patient) t.get(IBaseResource.class, 0);
contents.getNameFirstRep().setFamily("NEWFAMILY");
});
@@ -59,7 +59,7 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
p.setActive(true);
IIdType id = ourClient.create().resource(p).execute().getId();
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.OP_PRESTORAGE_RESOURCE_UPDATED, t->{
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.OP_PRESTORAGE_RESOURCE_UPDATED, (thePointcut, t)->{
Patient contents = (Patient) t.get(IBaseResource.class, 1);
contents.getNameFirstRep().setFamily("NEWFAMILY");
});
@@ -83,7 +83,7 @@ public class HookInterceptorR4Test extends BaseResourceProviderR4Test {
p.setActive(true);
IIdType id = ourClient.create().resource(p).execute().getId();
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.OP_PRECOMMIT_RESOURCE_UPDATED, t->{
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.OP_PRECOMMIT_RESOURCE_UPDATED, (thePointcut, t)->{
Patient contents = (Patient) t.get(IBaseResource.class, 1);
contents.getNameFirstRep().setFamily("NEWFAMILY");
});
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderInterceptorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderInterceptorR4Test.java
index 138a175e572..3fe539a7f89 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderInterceptorR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderInterceptorR4Test.java
@@ -1,5 +1,11 @@
package ca.uhn.fhir.jpa.provider.r4;
+import ca.uhn.fhir.jpa.dao.DaoConfig;
+import ca.uhn.fhir.jpa.model.interceptor.api.HookParams;
+import ca.uhn.fhir.jpa.model.interceptor.api.IAnonymousInterceptor;
+import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut;
+import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
+import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
@@ -13,6 +19,7 @@ import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
import ca.uhn.fhir.rest.server.interceptor.ServerOperationInterceptorAdapter;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.TestUtil;
+import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
@@ -29,14 +36,19 @@ import org.junit.After;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
import java.util.stream.Collectors;
+import static org.hamcrest.Matchers.in;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
@@ -48,6 +60,7 @@ public class ResourceProviderInterceptorR4Test extends BaseResourceProviderR4Tes
private IServerOperationInterceptor myDaoInterceptor;
private IServerOperationInterceptor myServerInterceptor;
+ private List
*/
- PERFTRACE_SEARCH_SELECT_COMPLETE(SearchRuntimeDetails.class.getName());
+ PERFTRACE_SEARCH_SELECT_COMPLETE(SearchRuntimeDetails.class.getName()),
+ /**
+ * Note that this is a performance tracing hook. Use with caution in production
+ * systems, since calling it may (or may not) carry a cost.
+ *
+ * This hook is invoked when a search has failed for any reason. When this pointcut
+ * is invoked, the search has completed unsuccessfully and will not be continued.
+ *
+ * Hooks may accept the following parameters:
+ *
+ *
+ * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being
+ * performed. Hooks should not modify this object.
+ *
+ *
+ *
+ * Hooks should return void.
+ *
+ */
+ PERFTRACE_SEARCH_FAILED(SearchRuntimeDetails.class.getName()),
+
+ /**
+ * Note that this is a performance tracing hook. Use with caution in production
+ * systems, since calling it may (or may not) carry a cost.
+ *
+ * This hook is invoked when a search has failed for any reason. When this pointcut
+ * is invoked, a pass in the Search Coordinator has completed successfully, but
+ * not all possible resources have been loaded yet so a future paging request
+ * may trigger a new task that will load further resources.
+ *
+ * Hooks may accept the following parameters:
+ *
+ *
+ * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being
+ * performed. Hooks should not modify this object.
+ *
+ *
+ *
+ * Hooks should return void.
+ *
+ */
+ PERFTRACE_SEARCH_PASS_COMPLETE(SearchRuntimeDetails.class.getName()),
+
+ /**
+ * Note that this is a performance tracing hook. Use with caution in production
+ * systems, since calling it may (or may not) carry a cost.
+ *
+ * This hook is invoked when a search has failed for any reason. When this pointcut
+ * is invoked, a pass in the Search Coordinator has completed successfully, and all
+ * possible results have been fetched and loaded into the query cache.
+ *
+ * Hooks may accept the following parameters:
+ *
+ *
+ * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being
+ * performed. Hooks should not modify this object.
+ *
+ *
+ *
+ * Hooks should return void.
+ *
+ */
+ PERFTRACE_SEARCH_COMPLETE(SearchRuntimeDetails.class.getName()),
+
+
+ /**
+ * Note that this is a performance tracing hook. Use with caution in production
+ * systems, since calling it may (or may not) carry a cost.
+ *
+ * This hook is invoked when any informational or warning messages generated by the
+ * SearchCoordinator are created. It is typically used to provide logging
+ * or capture details related to a specific request.
+ *
+ * Hooks may accept the following parameters:
+ *
+ *
+ * {@link PerformanceMessage} - Contains the message
+ *
+ *
+ *
+ * Hooks should return void.
+ *
+ */
+ PERFTRACE_MESSAGE(PerformanceMessage.class.getName())
+
+ ;
private final List myParameterTypes;
Pointcut(String... theParameterTypes) {
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorService.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorService.java
index 7fbb7753bac..b5524fc5eb5 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorService.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorService.java
@@ -32,6 +32,7 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
@@ -43,22 +44,37 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
private final ListMultimap myGlobalInvokers = ArrayListMultimap.create();
private final ListMultimap myAnonymousInvokers = ArrayListMultimap.create();
private final Object myRegistryMutex = new Object();
- private String myName;
private final ThreadLocal> myThreadlocalInvokers = new ThreadLocal<>();
- private boolean myThreadlocalInvokersEnabled;
+ private String myName;
+ private boolean myThreadlocalInvokersEnabled = true;
+
+ /**
+ * Constructor which uses a default name of "default"
+ */
+ public InterceptorService() {
+ this("default");
+ }
/**
* Constructor
+ *
+ * @param theName The name for this registry (useful for troubleshooting)
*/
public InterceptorService(String theName) {
super();
myName = theName;
}
+ /**
+ * Are threadlocal interceptors enabled on this registry (defaults to true)
+ */
public boolean isThreadlocalInvokersEnabled() {
return myThreadlocalInvokersEnabled;
}
+ /**
+ * Are threadlocal interceptors enabled on this registry (defaults to true)
+ */
public void setThreadlocalInvokersEnabled(boolean theThreadlocalInvokersEnabled) {
myThreadlocalInvokersEnabled = theThreadlocalInvokersEnabled;
}
@@ -71,8 +87,8 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
@Override
@VisibleForTesting
- public void registerAnonymousHookForUnitTest(Pointcut thePointcut, IAnonymousLambdaHook theHook) {
- registerAnonymousHookForUnitTest(thePointcut, DEFAULT_ORDER, theHook);
+ public void registerAnonymousInterceptor(Pointcut thePointcut, IAnonymousInterceptor theInterceptor) {
+ registerAnonymousInterceptor(thePointcut, DEFAULT_ORDER, theInterceptor);
}
public void setName(String theName) {
@@ -80,17 +96,27 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
}
@Override
- public void registerAnonymousHookForUnitTest(Pointcut thePointcut, int theOrder, IAnonymousLambdaHook theHook) {
+ public void registerAnonymousInterceptor(Pointcut thePointcut, int theOrder, IAnonymousInterceptor theInterceptor) {
Validate.notNull(thePointcut);
- Validate.notNull(theHook);
-
- myAnonymousInvokers.put(thePointcut, new AnonymousLambdaInvoker(theHook, theOrder));
+ Validate.notNull(theInterceptor);
+ synchronized (myRegistryMutex) {
+ myAnonymousInvokers.put(thePointcut, new AnonymousLambdaInvoker(thePointcut, theInterceptor, theOrder));
+ }
}
@Override
@VisibleForTesting
public void clearAnonymousHookForUnitTest() {
- myAnonymousInvokers.clear();
+ synchronized (myRegistryMutex) {
+ myAnonymousInvokers.clear();
+ }
+ }
+
+ @Override
+ public void unregisterInterceptors(@Nullable Collection> theInterceptors) {
+ if (theInterceptors != null) {
+ theInterceptors.forEach(t -> unregisterInterceptor(t));
+ }
}
@Override
@@ -125,7 +151,7 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
}
@Override
- public boolean registerInterceptor(Object theInterceptor) {
+ public boolean registerAnonymousInterceptor(Object theInterceptor) {
synchronized (myRegistryMutex) {
if (isInterceptorAlreadyRegistered(theInterceptor)) {
@@ -159,12 +185,13 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
synchronized (myRegistryMutex) {
myInterceptors.removeIf(t -> t == theInterceptor);
myGlobalInvokers.entries().removeIf(t -> t.getValue().getInterceptor() == theInterceptor);
+ myAnonymousInvokers.entries().removeIf(t -> t.getValue().getInterceptor() == theInterceptor);
}
}
@Override
public boolean registerGlobalInterceptor(Object theInterceptor) {
- return registerInterceptor(theInterceptor);
+ return registerAnonymousInterceptor(theInterceptor);
}
@Override
@@ -281,8 +308,8 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
retVal = Arrays
.stream(theInvokersLists)
- .filter(t->t!= null)
- .flatMap(t->t.stream())
+ .filter(t -> t != null)
+ .flatMap(t -> t.stream())
.sorted()
.collect(Collectors.toList());
@@ -312,16 +339,18 @@ public class InterceptorService implements IInterceptorRegistry, IInterceptorBro
}
private class AnonymousLambdaInvoker extends BaseInvoker {
- private final IAnonymousLambdaHook myHook;
+ private final IAnonymousInterceptor myHook;
+ private final Pointcut myPointcut;
- public AnonymousLambdaInvoker(IAnonymousLambdaHook theHook, int theOrder) {
+ public AnonymousLambdaInvoker(Pointcut thePointcut, IAnonymousInterceptor theHook, int theOrder) {
super(theHook, theOrder);
myHook = theHook;
+ myPointcut = thePointcut;
}
@Override
boolean invoke(HookParams theParams) {
- myHook.invoke(theParams);
+ myHook.invoke(myPointcut, theParams);
return true;
}
}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/PerformanceMessage.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/PerformanceMessage.java
new file mode 100644
index 00000000000..90c4d180349
--- /dev/null
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/PerformanceMessage.java
@@ -0,0 +1,16 @@
+package ca.uhn.fhir.jpa.model.search;
+
+public class PerformanceMessage {
+
+ private String myMessage;
+
+ public String getMessage() {
+ return myMessage;
+ }
+
+ public PerformanceMessage setMessage(String theMessage) {
+ myMessage = theMessage;
+ return this;
+ }
+
+}
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchRuntimeDetails.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchRuntimeDetails.java
index 95a888b60a8..90a5a842277 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchRuntimeDetails.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchRuntimeDetails.java
@@ -12,6 +12,7 @@ public class SearchRuntimeDetails {
private int myFoundMatchesCount;
private boolean myLoadSynchronous;
private String myQueryString;
+ private SearchStatusEnum mySearchStatus;
public SearchRuntimeDetails(String theSearchUuid) {
mySearchUuid = theSearchUuid;
@@ -52,4 +53,12 @@ public class SearchRuntimeDetails {
public String getQueryString() {
return myQueryString;
}
+
+ public SearchStatusEnum getSearchStatus() {
+ return mySearchStatus;
+ }
+
+ public void setSearchStatus(SearchStatusEnum theSearchStatus) {
+ mySearchStatus = theSearchStatus;
+ }
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchStatusEnum.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchStatusEnum.java
similarity index 96%
rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchStatusEnum.java
rename to hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchStatusEnum.java
index fa6f8e16774..52de69710e7 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchStatusEnum.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/search/SearchStatusEnum.java
@@ -1,4 +1,4 @@
-package ca.uhn.fhir.jpa.entity;
+package ca.uhn.fhir.jpa.model.search;
/*-
* #%L
diff --git a/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorServiceTest.java b/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorServiceTest.java
index cbd279d4f9c..e9a554dba52 100644
--- a/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorServiceTest.java
+++ b/hapi-fhir-jpaserver-model/src/test/java/ca/uhn/fhir/jpa/model/interceptor/executor/InterceptorServiceTest.java
@@ -1,6 +1,9 @@
package ca.uhn.fhir.jpa.model.interceptor.executor;
-import ca.uhn.fhir.jpa.model.interceptor.api.*;
+import ca.uhn.fhir.jpa.model.interceptor.api.Hook;
+import ca.uhn.fhir.jpa.model.interceptor.api.HookParams;
+import ca.uhn.fhir.jpa.model.interceptor.api.Interceptor;
+import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.StopWatch;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -14,7 +17,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.core.annotation.Order;
import org.springframework.test.context.ContextConfiguration;
@@ -50,7 +52,7 @@ public class InterceptorServiceTest {
int initialSize = myInterceptorRegistry.getGlobalInterceptorsForUnitTest().size();
try {
- myInterceptorRegistry.registerInterceptor(new InterceptorThatFailsOnRegister());
+ myInterceptorRegistry.registerAnonymousInterceptor(new InterceptorThatFailsOnRegister());
fail();
} catch (InternalErrorException e) {
// good
@@ -72,7 +74,7 @@ public class InterceptorServiceTest {
public void testManuallyRegisterGlobalInterceptor() {
// Register the manual interceptor (has @Order right in the middle)
- myInterceptorRegistry.registerInterceptor(myInterceptorManual);
+ myInterceptorRegistry.registerAnonymousInterceptor(myInterceptorManual);
List globalInterceptors = myInterceptorRegistry.getGlobalInterceptorsForUnitTest();
assertEquals(3, globalInterceptors.size());
assertTrue(globalInterceptors.get(0).getClass().toString(), globalInterceptors.get(0) instanceof MyTestInterceptorOne);
@@ -80,7 +82,7 @@ public class InterceptorServiceTest {
assertTrue(globalInterceptors.get(2).getClass().toString(), globalInterceptors.get(2) instanceof MyTestInterceptorTwo);
// Try to register again (should have no effect
- myInterceptorRegistry.registerInterceptor(myInterceptorManual);
+ myInterceptorRegistry.registerAnonymousInterceptor(myInterceptorManual);
globalInterceptors = myInterceptorRegistry.getGlobalInterceptorsForUnitTest();
assertEquals(3, globalInterceptors.size());
assertTrue(globalInterceptors.get(0).getClass().toString(), globalInterceptors.get(0) instanceof MyTestInterceptorOne);
@@ -263,7 +265,7 @@ public class InterceptorServiceTest {
*
*/
@Test
- @Ignore
+ @Ignore("Performance test - Not needed normally")
public void testThreadLocalHookInterceptorMicroBenchmark() {
threadLocalMicroBenchmark(true, 500000);
threadLocalMicroBenchmark(false, 500000);
@@ -328,7 +330,6 @@ public class InterceptorServiceTest {
}
@Configuration
- @ComponentScan(basePackages = "ca.uhn.fhir.jpa.model")
static class InterceptorRegistryTestCtxConfig {
@Bean
@@ -343,7 +344,7 @@ public class InterceptorServiceTest {
@Bean
public MyTestInterceptorTwo interceptor1() {
MyTestInterceptorTwo retVal = new MyTestInterceptorTwo();
- interceptorService().registerInterceptor(retVal);
+ interceptorService().registerAnonymousInterceptor(retVal);
return retVal;
}
@@ -354,7 +355,7 @@ public class InterceptorServiceTest {
@Bean
public MyTestInterceptorOne interceptor2() {
MyTestInterceptorOne retVal = new MyTestInterceptorOne();
- interceptorService().registerInterceptor(retVal);
+ interceptorService().registerAnonymousInterceptor(retVal);
return retVal;
}
diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java
index 0bcd02c33b2..1493b926270 100644
--- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java
+++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/PointcutLatch.java
@@ -1,7 +1,7 @@
package ca.uhn.fhir.jpa.subscription.module;
import ca.uhn.fhir.jpa.model.interceptor.api.HookParams;
-import ca.uhn.fhir.jpa.model.interceptor.api.IAnonymousLambdaHook;
+import ca.uhn.fhir.jpa.model.interceptor.api.IAnonymousInterceptor;
import ca.uhn.fhir.jpa.model.interceptor.api.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -15,7 +15,7 @@ import java.util.stream.Collectors;
import static org.junit.Assert.*;
-public class PointcutLatch implements IAnonymousLambdaHook {
+public class PointcutLatch implements IAnonymousInterceptor {
private static final Logger ourLog = LoggerFactory.getLogger(PointcutLatch.class);
private static final int DEFAULT_TIMEOUT_SECONDS = 10;
private static final FhirObjectPrinter ourFhirObjectToStringMapper = new FhirObjectPrinter();
@@ -25,9 +25,11 @@ public class PointcutLatch implements IAnonymousLambdaHook {
private CountDownLatch myCountdownLatch;
private AtomicReference myFailure;
private AtomicReference> myCalledWith;
+ private Pointcut myPointcut;
public PointcutLatch(Pointcut thePointcut) {
this.name = thePointcut.name();
+ myPointcut = thePointcut;
}
public PointcutLatch(String theName) {
@@ -105,7 +107,7 @@ public class PointcutLatch implements IAnonymousLambdaHook {
@Override
- public void invoke(HookParams theArgs) {
+ public void invoke(Pointcut thePointcut, HookParams theArgs) {
if (myCountdownLatch == null) {
throw new PointcutLatchException("invoke() called before setExpectedCount() called.", theArgs);
} else if (myCountdownLatch.getCount() <= 0) {
@@ -121,7 +123,7 @@ public class PointcutLatch implements IAnonymousLambdaHook {
}
public void call(Object arg) {
- this.invoke(new HookParams(arg));
+ this.invoke(myPointcut, new HookParams(arg));
}
private class PointcutLatchException extends IllegalStateException {
diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java
index 6ec7ee0895e..ed8faffc058 100644
--- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java
+++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/standalone/BaseBlockingQueueSubscribableChannelDstu3Test.java
@@ -78,8 +78,8 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base
ourSubscribableChannel = mySubscriptionChannelFactory.newDeliveryChannel("test", Subscription.SubscriptionChannelType.RESTHOOK.toCode().toLowerCase());
ourSubscribableChannel.subscribe(myStandaloneSubscriptionMessageHandler);
}
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED, mySubscriptionMatchingPost);
- myInterceptorRegistry.registerAnonymousHookForUnitTest(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED, mySubscriptionActivatedPost);
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED, mySubscriptionMatchingPost);
+ myInterceptorRegistry.registerAnonymousInterceptor(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED, mySubscriptionActivatedPost);
}
@After
@@ -171,7 +171,7 @@ public abstract class BaseBlockingQueueSubscribableChannelDstu3Test extends Base
public MethodOutcome update(@ResourceParam Observation theObservation, HttpServletRequest theRequest) {
ourContentTypes.add(theRequest.getHeader(Constants.HEADER_CONTENT_TYPE).replaceAll(";.*", ""));
ourUpdatedObservations.add(theObservation);
- updateLatch.invoke(new HookParams().add(Observation.class, theObservation));
+ updateLatch.invoke(null, new HookParams().add(Observation.class, theObservation));
ourLog.info("Received Listener Update (now have {} updates)", ourUpdatedObservations.size());
return new MethodOutcome(new IdType("Observation/1"), false);
}