void getDatasetVersionInfoAndVerify(String accountName, String containerName, String datasetName, String version,
      HttpHeaders headers, long expectTtl, HttpHeaders expectedHeaders) throws Exception {
    FullHttpRequest httpRequest = buildRequest(HttpMethod.GET,
        buildUriForDatasetVersion(accountName, containerName, datasetName, version) + "/"
            + RestUtils.SubResource.BlobInfo, headers, null);
    NettyClient.ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
    HttpResponse response = getHttpResponse(responseParts);
    assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
    checkCommonGetHeadHeaders(response.headers());
    verifyTrackingHeaders(response);
    verifyBlobProperties(expectedHeaders, false, response);
    verifyAccountAndContainerHeaders(accountName, containerName, response);
    assertEquals(RestUtils.Headers.BLOB_SIZE + " does not match", expectedHeaders.get(RestUtils.Headers.BLOB_SIZE),
        response.headers().get(RestUtils.Headers.BLOB_SIZE));
    if (expectTtl != -1) {
      assertEquals("Unexpected ttl value", expectTtl,
          (gmtToEpoch(response.headers().get(RestUtils.Headers.DATASET_EXPIRATION_TIME)) - gmtToEpoch(
                 response.headers().get(RestUtils.Headers.CREATION_TIME))) / 1000);
    }
    assertTrue("Channel should be active", HttpUtil.isKeepAlive(response));
    assertEquals(RestUtils.Headers.LIFE_VERSION + " does not match",
        expectedHeaders.get(RestUtils.Headers.LIFE_VERSION), response.headers().get(RestUtils.Headers.LIFE_VERSION));
  }
Verify Named blob List operation.
@param accountName The account name.
@param containerName The container name
@param ownerId The owner id
@param prefix The prefix of blob name.
@param numberOfBlobs The expected number of named blobs returned by list operation.
@throws Exception
ambry-frontend/src/integration-test/java/com/github/ambry/frontend/FrontendIntegrationTestBase.java