void getBlobAndVerify(String blobId, ByteRange range, GetOption getOption, boolean resolveRangeOnEmptyBlob,
      HttpHeaders expectedHeaders, boolean isPrivate, ByteBuffer expectedContent, String accountName,
      String containerName, Container container) throws ExecutionException, InterruptedException, RestServiceException {
    HttpHeaders headers = new DefaultHttpHeaders();
    if (range != null) {
      headers.add(RestUtils.Headers.RANGE, RestTestUtils.getRangeHeaderString(range));
    }
    if (getOption != null) {
      headers.add(RestUtils.Headers.GET_OPTION, getOption.toString());
    }
    if (resolveRangeOnEmptyBlob) {
      headers.add(RestUtils.Headers.RESOLVE_RANGE_ON_EMPTY_BLOB, true);
    }
    FullHttpRequest httpRequest = buildRequest(HttpMethod.GET, blobId, headers, null);
    NettyClient.ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    verifyGetBlobResponse(responseParts, range, resolveRangeOnEmptyBlob, expectedHeaders, isPrivate, expectedContent,
        accountName, containerName, container);
  }
Gets the blob with blob ID {@code blobId} and verifies that the headers and content match with what is expected.
@param blobId the blob ID of the blob to GET.
@param range the {@link ByteRange} for the request.
@param getOption the options to use while getting the blob.
@param resolveRangeOnEmptyBlob {@code true} to send the {@link RestUtils.Headers#RESOLVE_RANGE_ON_EMPTY_BLOB}
                               header.
@param expectedHeaders the expected headers in the response.
@param isPrivate {@code true} if the blob is private, {@code false} if not.
@param expectedContent the expected content of the blob.
@param accountName the account name that should be in the response
@param containerName the container name that should be in the response
@throws ExecutionException
@throws InterruptedException
ambry-frontend/src/integration-test/java/com/github/ambry/frontend/FrontendIntegrationTestBase.java