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 01d2e5637e4..2de3cf3cb54 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 @@ -448,6 +448,45 @@ public enum Pointcut { "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" ), + /** + * Server Hook: + * This method is called after all processing is completed for a request, regardless of whether + * the request completed successfully or not. It is called after {@link #SERVER_PROCESSING_COMPLETED_NORMALLY} + * in the case of successful operations. + *

+ * Hooks may accept the following parameters: + *

+ *

+ *

+ * This method must return void + *

+ *

+ * This method should not throw any exceptions. Any exception that is thrown by this + * method will be logged, but otherwise not acted upon (i.e. even if a hook method + * throws an exception, processing will continue and other interceptors will be + * called). Therefore it is considered a bug to throw an exception from hook methods using this + * pointcut. + *

+ */ + SERVER_PROCESSING_COMPLETED( + void.class, + new ExceptionHandlingSpec() + .addLogAndSwallow(Throwable.class), + "ca.uhn.fhir.rest.api.server.RequestDetails", + "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" + ), + /** * Invoked whenever a persisted resource has been modified and is being submitted to the * subscription processing pipeline. This method is called before the resource is placed @@ -1442,7 +1481,9 @@ public enum Pointcut { * This pointcut is used only for unit tests. Do not use in production code as it may be changed or * removed at any time. */ - TEST_RO(BaseServerResponseException.class, String.class.getName(), String.class.getName()); + TEST_RO(BaseServerResponseException.class, String.class.getName(), String.class.getName()) + + ; private final List myParameterTypes; private final Class myReturnType; diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java index f351bc37d36..ef2b7e43e2f 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java @@ -58,6 +58,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.UnavailableException; import javax.servlet.http.HttpServlet; @@ -1085,6 +1086,13 @@ public class RestfulServer extends HttpServlet implements IRestfulServer theUserData, String theMethod) { @@ -256,6 +256,12 @@ public class InterceptorUserDataMapDstu2Test { updateMapUsing(theServletRequestDetails.getUserData(), "processingCompletedNormally"); } + @Hook(Pointcut.SERVER_PROCESSING_COMPLETED) + public void processingCompleted(RequestDetails theRequestDetails, ServletRequestDetails theServletRequestDetails) { + updateMapUsing(theRequestDetails.getUserData(), "processingCompleted"); + updateMapUsing(theServletRequestDetails.getUserData(), "processingCompleted"); + } + @Hook(Pointcut.SERVER_PRE_PROCESS_OUTGOING_EXCEPTION) public void preProcessOutgoingException(RequestDetails theRequestDetails, ServletRequestDetails theServletRequestDetails) { updateMapUsing(theRequestDetails.getUserData(), "preProcessOutgoingException"); diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 268844917a8..24ebecacdde 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -262,6 +262,10 @@ socket timeout settings to client requests. Thanks to Petro Mykhailyshyn for the pull request! + + A new server interceptor hook called PROCESSING_COMPLETED has been added. This + hook is called by the server at the end of processing every request (success and failure). +