diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java
index b36bc90a43f..1463d5f1369 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/interceptor/api/Pointcut.java
@@ -1511,6 +1511,46 @@ public enum Pointcut implements IPointcut {
"ca.uhn.fhir.rest.api.server.storage.TransactionDetails"
),
+ /**
+ * Storage Hook:
+ * Invoked before a resource will be deleted
+ *
+ * Hooks will have access to the contents of the resource being deleted
+ * but should not make any changes as storage has already occurred
+ *
+ * Hooks may accept the following parameters:
+ *
+ * - org.hl7.fhir.instance.model.api.IBaseResource - The resource being deleted
+ * -
+ * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the
+ * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
+ * pulled out of the servlet request. Note that the bean
+ * properties are not all guaranteed to be populated, depending on how early during processing the
+ * exception occurred.
+ *
+ * -
+ * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the
+ * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
+ * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will
+ * only be populated when operating in a RestfulServer implementation. It is provided as a convenience.
+ *
+ * -
+ * ca.uhn.fhir.rest.api.server.storage.TransactionDetails - The outer transaction details object (since 5.0.0)
+ *
+ *
+ *
+ * Hooks should return void
.
+ *
+ */
+ STORAGE_TRANSACTION_PROCESSED(void.class,
+ "org.hl7.fhir.instance.model.api.IBaseResource",
+ "ca.uhn.fhir.rest.api.server.storage.DeferredInterceptorBroadcasts",
+ "ca.uhn.fhir.rest.api.server.RequestDetails",
+ "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails",
+ "ca.uhn.fhir.rest.api.server.storage.TransactionDetails"
+ ),
+
+
/**
* Storage Hook:
* Invoked when a resource delete operation is about to fail due to referential integrity checks. Intended for use with {@literal ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor}.
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java
index 379664a141a..1e25f7bb007 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseTransactionProcessor.java
@@ -995,25 +995,16 @@ public abstract class BaseTransactionProcessor {
flushSession(theIdToPersistedOutcome);
theTransactionStopWatch.endCurrentTask();
- if (conditionalRequestUrls.size() > 0) {
- theTransactionStopWatch.startTask("Check for conflicts in conditional resources");
- }
+
+
/*
* Double check we didn't allow any duplicates we shouldn't have
*/
- for (Map.Entry> nextEntry : conditionalRequestUrls.entrySet()) {
- String matchUrl = nextEntry.getKey();
- Class extends IBaseResource> resType = nextEntry.getValue();
- if (isNotBlank(matchUrl)) {
- Set val = myMatchResourceUrlService.processMatchUrl(matchUrl, resType, theRequest);
- if (val.size() > 1) {
- throw new InvalidRequestException(
- "Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
- }
- }
+ if (conditionalRequestUrls.size() > 0) {
+ theTransactionStopWatch.startTask("Check for conflicts in conditional resources");
}
-
+ validateNoDuplicates(theRequest, theActionName, conditionalRequestUrls);
theTransactionStopWatch.endCurrentTask();
for (IIdType next : theAllIds) {
@@ -1034,6 +1025,13 @@ public abstract class BaseTransactionProcessor {
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, nextPointcut, nextParams);
}
+
+ theTransactionDetails.deferredBroadcastProcessingFinished();
+
+
+
+ //finishedCallingDeferredInterceptorBroadcasts
+
return entriesToProcess;
} finally {
@@ -1043,6 +1041,20 @@ public abstract class BaseTransactionProcessor {
}
}
+ private void validateNoDuplicates(RequestDetails theRequest, String theActionName, Map> conditionalRequestUrls) {
+ for (Map.Entry> nextEntry : conditionalRequestUrls.entrySet()) {
+ String matchUrl = nextEntry.getKey();
+ Class extends IBaseResource> resType = nextEntry.getValue();
+ if (isNotBlank(matchUrl)) {
+ Set val = myMatchResourceUrlService.processMatchUrl(matchUrl, resType, theRequest);
+ if (val.size() > 1) {
+ throw new InvalidRequestException(
+ "Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
+ }
+ }
+ }
+ }
+
protected abstract void flushSession(Map theIdToPersistedOutcome);
private void validateResourcePresent(IBaseResource theResource, Integer theOrder, String theVerb) {
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/DeferredInterceptorBroadcasts.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/DeferredInterceptorBroadcasts.java
new file mode 100644
index 00000000000..f13e6e41407
--- /dev/null
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/DeferredInterceptorBroadcasts.java
@@ -0,0 +1,8 @@
+package ca.uhn.fhir.rest.api.server.storage;
+
+import com.google.common.collect.ListMultimap;
+
+public class DeferredInterceptorBroadcasts {
+
+ public DeferredInterceptorBroadcasts(ListMultimap)
+}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/TransactionDetails.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/TransactionDetails.java
index 57520bc2570..76a28163313 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/TransactionDetails.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/storage/TransactionDetails.java
@@ -53,6 +53,7 @@ public class TransactionDetails {
private Map myUserData;
private ListMultimap myDeferredInterceptorBroadcasts;
private EnumSet myDeferredInterceptorBroadcastPointcuts;
+ private boolean myIsPointcutDeferred;
/**
* Constructor
@@ -189,7 +190,16 @@ public class TransactionDetails {
*/
public void addDeferredInterceptorBroadcast(Pointcut thePointcut, HookParams theHookParams) {
Validate.isTrue(isAcceptingDeferredInterceptorBroadcasts(thePointcut));
+ myIsPointcutDeferred = true;
myDeferredInterceptorBroadcasts.put(thePointcut, theHookParams);
}
+
+ public boolean isPointcutDeferred() {
+ return myIsPointcutDeferred;
+ }
+
+ public void deferredBroadcastProcessingFinished() {
+ myIsPointcutDeferred = false;
+ }
}