@Override
    public void onCompletion(Void result, Exception exception) {
      long processingStartTimeMs = SystemTime.getInstance().milliseconds();
      metrics.getSignedUrlSecurityPostProcessRequestTimeInMs.update(processingStartTimeMs - operationStartTimeMs);
      try {
        if (exception == null) {
          String signedUrl = urlSigningService.getSignedUrl(restRequest);
          LOGGER.debug("Generated {} from {}", signedUrl, restRequest);
          restResponseChannel.setHeader(RestUtils.Headers.DATE, new GregorianCalendar().getTime());
          restResponseChannel.setHeader(RestUtils.Headers.SIGNED_URL, signedUrl);
          restResponseChannel.setHeader(RestUtils.Headers.CONTENT_LENGTH, 0);
          final long processResponseStartTimeMs = SystemTime.getInstance().milliseconds();
          securityService.processResponse(restRequest, restResponseChannel, null,
              (processResponseResult, processResponseException) -> {
                metrics.getSignedUrlSecurityResponseTimeInMs.update(
                    SystemTime.getInstance().milliseconds() - processResponseStartTimeMs);
                callback.onCompletion(null, processResponseException);
              });
        }
      } catch (Exception e) {
        exception = e;
      } finally {
        metrics.getSignedUrlProcessingTimeInMs.update(SystemTime.getInstance().milliseconds() - processingStartTimeMs);
        if (exception != null) {
          callback.onCompletion(null, exception);
        }
      }
    }
Callback for {@link SecurityService#postProcessRequest(RestRequest, Callback)} that handles generating a signed URL
if the security checks succeeded.
ambry-frontend/src/main/java/com/github/ambry/frontend/GetSignedUrlHandler.java