public static Map<String, String> buildUserMetadata(byte[] userMetadata) {
    if (userMetadata.length == 0) {
      return Collections.emptyMap();
    }
    Map<String, String> toReturn = null;
    try {
      ByteBuffer userMetadataBuffer = ByteBuffer.wrap(userMetadata);
      short version = userMetadataBuffer.getShort();
      switch (version) {
        case USER_METADATA_VERSION_V1:
          int sizeToRead = userMetadataBuffer.getInt();
          if (sizeToRead != (userMetadataBuffer.remaining() - 8)) {
            logger.trace("Size didn't match. Returning null");
          } else {
            int entryCount = userMetadataBuffer.getInt();
            int counter = 0;
            if (entryCount > 0) {
              toReturn = new HashMap<>();
            }
            while (counter++ < entryCount) {
              String key = Utils.deserializeString(userMetadataBuffer, CHARSET);
              String value = Utils.deserializeString(userMetadataBuffer, CHARSET);
              toReturn.put(Headers.USER_META_DATA_HEADER_PREFIX + key, value);
            }
            long actualCRC = userMetadataBuffer.getLong();
            CRC32 crc32 = new CRC32();
            crc32.update(userMetadata, 0, userMetadata.length - CRC_SIZE);
            long expectedCRC = crc32.getValue();
            if (actualCRC != expectedCRC) {
              logger.error("corrupt data while parsing user metadata Expected CRC {} Actual CRC {}", expectedCRC,
                  actualCRC);
              toReturn = null;
            }
          }
          break;
        default:
          toReturn = null;
          logger.trace("Failed to parse version in new format. Returning null");
      }
    } catch (RuntimeException e) {
      logger.trace("Runtime Exception on parsing user metadata. Returning null");
      toReturn = null;
    }
    return toReturn;
  }
Gets deserialized metadata from the byte array if possible
@param userMetadata the byte array which has the user metadata
@return the user metadata that is read from the byte array, or {@code null} if the {@code userMetadata} cannot be
parsed in expected format
ambry-api/src/main/java/com/github/ambry/rest/RestUtils.java