private Callback<Void> routerTtlUpdateCallback(BlobInfo blobInfo, String blobId) {
      return buildCallback(frontendMetrics.updateBlobTtlRouterMetrics, convertedBlobId -> {
        // Set the named blob state to be 'READY' after the Ttl update succeed
        if (!restRequest.getArgs().containsKey(NAMED_BLOB_VERSION)) {
          throw new RestServiceException(
              "Internal key " + NAMED_BLOB_VERSION + " is required in Named Blob TTL update callback!",
              RestServiceErrorCode.InternalServerError);
        }
        long namedBlobVersion = (long) restRequest.getArgs().get(NAMED_BLOB_VERSION);
        String blobIdClean = stripSlashAndExtensionFromId(blobId);
        NamedBlobPath namedBlobPath = NamedBlobPath.parse(getRequestPath(restRequest), restRequest.getArgs());
        NamedBlobRecord record = new NamedBlobRecord(namedBlobPath.getAccountName(), namedBlobPath.getContainerName(),
            namedBlobPath.getBlobName(), blobIdClean, Utils.Infinite_Time, namedBlobVersion);
        namedBlobDb.updateBlobTtlAndStateToReady(record).get();
        securityService.processResponse(restRequest, restResponseChannel, blobInfo, securityProcessResponseCallback());
      }, uri, LOGGER, finalCallback);
    }
After TTL update finishes, call {@link SecurityService#postProcessRequest} to perform
request time security checks that rely on the request being fully parsed and any additional arguments set.
@param blobInfo the {@link BlobInfo} to use for security checks.
@param blobId the {@link String} to use for blob id.
@return a {@link Callback} to be used with {@link Router#updateBlobTtl(String, String, long)}.
ambry-frontend/src/main/java/com/github/ambry/frontend/s3/S3MultipartCompleteUploadHandler.java