public static BlobProperties buildBlobProperties(Map<String, Object> args) throws RestServiceException {
    Account account = getAccountFromArgs(args);
    Container container = getContainerFromArgs(args);
    String serviceId = getHeader(args, Headers.SERVICE_ID, true);
    String contentType = getHeader(args, Headers.AMBRY_CONTENT_TYPE, true);
    String ownerId = getHeader(args, Headers.OWNER_ID, false);
    String externalAssetTag = getHeader(args, Headers.EXTERNAL_ASSET_TAG, false);
    String contentEncoding = getHeader(args, Headers.AMBRY_CONTENT_ENCODING, false);
    String filename = getHeader(args, Headers.AMBRY_FILENAME, false);
    String reservedMetadataBlobid = getReservedMetadataBlobId(args);

    long ttl = getTtlFromRequestHeader(args);

    // This field should not matter on newly created blobs, because all privacy/cacheability decisions should be made
    // based on the container properties and ACLs. For now, BlobProperties still includes this field, though.
    boolean isPrivate = !container.isCacheable();
    return new BlobProperties(-1, serviceId, ownerId, contentType, isPrivate, ttl, account.getId(), container.getId(),
        container.isEncrypted(), externalAssetTag, contentEncoding, filename, reservedMetadataBlobid);
  }
Builds {@link BlobProperties} given the arguments associated with a request.
@param args the arguments associated with the request. Cannot be {@code null}.
@return the {@link BlobProperties} extracted from the arguments.
@throws RestServiceException if required arguments aren't present or if they aren't in the format or number
                                   expected.
ambry-api/src/main/java/com/github/ambry/rest/RestUtils.java