@Override
  public void postProcessRequest(RestRequest restRequest, Callback<Void> callback) {
    if (restRequest == null || callback == null) {
      throw new IllegalArgumentException("RestRequest or Callback is null");
    }
    Exception exception = null;
    frontendMetrics.securityServicePostProcessRequestRate.mark();
    long startTimeMs = System.currentTimeMillis();
    try {
      if (!isOpen) {
        exception = new RestServiceException("SecurityService is closed", RestServiceErrorCode.ServiceUnavailable);
      } else if (hostLevelThrottler.shouldThrottle(restRequest)) {
        exception = new RestServiceException("Too many requests", RestServiceErrorCode.TooManyRequests);
      } else {
        if (QuotaUtils.isRequestResourceQuotaManaged(restRequest) && quotaManager != null) {
          ThrottlingRecommendation throttlingRecommendation = quotaManager.recommend(restRequest);
          if (throttlingRecommendation != null && throttlingRecommendation.shouldThrottle()
              && quotaManager.getQuotaMode() == QuotaMode.THROTTLING) {
            Map<String, String> quotaHeaderMap = RestUtils.buildUserQuotaHeadersMap(throttlingRecommendation);
            throw new RestServiceException("User Quota Exceeded", RestServiceErrorCode.TooManyRequests, true, true,
                quotaHeaderMap);
          }
        }
        if (restRequest.getRestMethod() == RestMethod.DELETE || restRequest.getRestMethod() == RestMethod.PUT) {
          accountAndContainerNamePreconditionCheck(restRequest);
        } else if (restRequest.getRestMethod() == RestMethod.GET) {
          RequestPath requestPath = getRequestPath(restRequest);
          String operationOrBlobId = requestPath.getOperationOrBlobId(true);
          // ensure that secure path validation is only performed when getting blobs rather than other operations.
          if (!operationOrBlobId.isEmpty() && !OPERATIONS.contains(operationOrBlobId)) {
            validateSecurePathIfRequired(restRequest, requestPath.getPrefix(), frontendConfig.securePathPrefix);
          }
        }
      }
    } catch (Exception e) {
      exception = e;
    } finally {
      frontendMetrics.securityServicePostProcessRequestTimeInMs.update(System.currentTimeMillis() - startTimeMs);
      callback.onCompletion(null, exception);
    }
  }
Default implementation of {@link SecurityService} for Ambry that doesn't do any validations, but just
sets the respective headers on response.
ambry-frontend/src/main/java/com/github/ambry/frontend/AmbrySecurityService.java