public static RequestPath parse(RestRequest restRequest, List<String> prefixesToRemove, String clusterName)
      throws RestServiceException {
    String blobIdHeader = RestUtils.getHeader(restRequest.getArgs(), Headers.BLOB_ID, false);
    if (blobIdHeader != null) {
      // If blob id is specified in the rest request header and it has cluster name prefix, we remove its prefix, subResource
      // and use this id (pure blob id with no prefix or subResource) to update "x-ambry-blob-id" header. The purpose is
      // to ensure IdConverter and IdSigningService can receive a valid blob id and correctly identify it.
      String blobIdStr =
          parse(blobIdHeader, Collections.emptyMap(), prefixesToRemove, clusterName).getOperationOrBlobId(false);
      // BlobId is url encoded in order to pass blob names with special characters
      try {
        blobIdStr = URLDecoder.decode(blobIdStr, StandardCharsets.UTF_8.name());
      } catch (UnsupportedEncodingException exception) {
        throw new RestServiceException("Invalid blob id " + blobIdStr, exception, RestServiceErrorCode.BadRequest);
      }
      restRequest.setArg(Headers.BLOB_ID, blobIdStr);
    }
    String path;
    try {
      path = restRequest.getPath();
    } catch (IllegalArgumentException e) {
      throw new RestServiceException("Invalid URI path", e, RestServiceErrorCode.BadRequest);
    }

    if (path.startsWith(S3_PATH) || path.startsWith(Operations.S3)) {
      // Convert to named blob request internally
      path = convertToNamedBlobPath(path);
      restRequest.setArg(S3_REQUEST, "true");
    }

    return parse(path, restRequest.getArgs(), prefixesToRemove, clusterName);
  }
Parse the request path (and additional headers in some cases). The path will match the following regex-like
description:
<pre>
{@code {prefixToRemove}?{clusterNameSegment}?({operationOrBlobId}|{operationOrBlobId}/{subResource})}
</pre>
For example, something like {@code /prefixOne/clusterA/parts/of/blobId/BlobInfo}, {@code /clusterA/operation},
or {@code /blobId}, among others.
@param restRequest {@link RestRequest} containing metadata about the request.
@param prefixesToRemove the list of prefixes that could precede the other parts of the URL. Removal of
                        prefixes earlier in the list will be preferred to removal of the ones later in the list.
@param clusterName the cluster name to recognize and handle when parsing the URL. Case is ignored when matching
                   this path segment.
@return a {@link RequestPath} object.
ambry-api/src/main/java/com/github/ambry/rest/RequestPath.java