@Test
  public void testDatasetVersionTtlUpdate() throws Exception {
    //Add dataset
    Account testAccount = new ArrayList<>(accountService.getAllAccounts()).get(1);
    Container testContainer = new ArrayList<>(testAccount.getAllContainers()).get(1);
    Dataset.VersionSchema versionSchema = Dataset.VersionSchema.TIMESTAMP;
    Dataset dataset =
        new DatasetBuilder(testAccount.getName(), testContainer.getName(), DATASET_NAME).setVersionSchema(versionSchema)
            .build();
    byte[] datasetsUpdateJson = AccountCollectionSerde.serializeDatasetsInJson(dataset);
    List<ByteBuffer> body = new LinkedList<>();
    body.add(ByteBuffer.wrap(datasetsUpdateJson));
    body.add(null);
    JSONObject headers = new JSONObject().put(RestUtils.Headers.TARGET_ACCOUNT_NAME, testAccount.getName())
        .put(RestUtils.Headers.TARGET_CONTAINER_NAME, testContainer.getName());
    RestRequest restRequest =
        createRestRequest(RestMethod.POST, Operations.ACCOUNTS_CONTAINERS_DATASETS, headers, body);
    MockRestResponseChannel restResponseChannel = new MockRestResponseChannel();
    doOperation(restRequest, restResponseChannel);

    // add first dataset version
    String version = "1";
    String blobName = DATASET_NAME + SLASH + version;
    String namedBlobPathUri =
        NAMED_BLOB_PREFIX + SLASH + testAccount.getName() + SLASH + testContainer.getName() + SLASH + blobName;
    ByteBuffer content = ByteBuffer.wrap(TestUtils.getRandomBytes(10));
    body = new LinkedList<>();
    body.add(content);
    body.add(null);
    headers = new JSONObject();
    setAmbryHeadersForPut(headers, 7200, testContainer.isCacheable(), "test", "application/octet-stream", "owner", null,
        null, null);
    headers.put(RestUtils.Headers.DATASET_VERSION_QUERY_ENABLED, true);
    restRequest = createRestRequest(RestMethod.PUT, namedBlobPathUri, headers, body);
    restResponseChannel = new MockRestResponseChannel();

    BlobProperties blobProperties =
        new BlobProperties(0, testAccount.getName(), "owner", "image/gif", false, 7200, testAccount.getId(),
            testContainer.getId(), false, null, null, null);
    ReadableStreamChannel byteBufferContent = new ByteBufferReadableStreamChannel(ByteBuffer.allocate(10));
    String blobIdFromRouter =
        router.putBlobWithIdVersion(blobProperties, new byte[0], byteBufferContent, BlobId.BLOB_ID_V6).get();
    reset(namedBlobDb);
    String blobNameNew = DATASET_NAME + SLASH + "1";
    NamedBlobRecord namedBlobRecord =
        new NamedBlobRecord(testAccount.getName(), testContainer.getName(), blobNameNew, blobIdFromRouter, 3600);
    NamedBlobRecord namedBlobRecordAfterTtlUpdate =
        new NamedBlobRecord(testAccount.getName(), testContainer.getName(), blobNameNew, blobIdFromRouter,
            Utils.Infinite_Time);
    when(namedBlobDb.put(any(), any(), any())).thenReturn(
        CompletableFuture.completedFuture(new PutResult(namedBlobRecord)));
    when(namedBlobDb.delete(namedBlobRecord.getAccountName(), namedBlobRecord.getContainerName(),
        blobNameNew)).thenReturn(CompletableFuture.completedFuture(new DeleteResult(blobIdFromRouter, false)));
    when(namedBlobDb.get(namedBlobRecord.getAccountName(), namedBlobRecord.getContainerName(), blobNameNew,
        GetOption.None, false)).thenReturn(CompletableFuture.completedFuture(namedBlobRecord));
    when(namedBlobDb.updateBlobTtlAndStateToReady(any())).thenReturn(
        CompletableFuture.completedFuture(new PutResult(namedBlobRecordAfterTtlUpdate)));

    doOperation(restRequest, restResponseChannel);
    assertNotEquals("The expiration time should not be Infinite_Time", null,
        restResponseChannel.getResponseHeaders().get(DATASET_EXPIRATION_TIME));

    //Update ttl for the dataset version.
    headers = new JSONObject();
    String serviceId = "service-id";
    headers.put(RestUtils.Headers.DATASET_VERSION_QUERY_ENABLED, true);
    headers.put(RestUtils.Headers.BLOB_ID, namedBlobPathUri);
    headers.put(RestUtils.Headers.SERVICE_ID, serviceId);
    restRequest = createRestRequest(RestMethod.PUT, Operations.UPDATE_TTL, headers, null);
    restResponseChannel = new MockRestResponseChannel();
    doOperation(restRequest, restResponseChannel);
    assertEquals("Unexpected response status", ResponseStatus.Ok, restResponseChannel.getStatus());
    assertEquals("Content-Length is not 0", "0", restResponseChannel.getHeader(RestUtils.Headers.CONTENT_LENGTH));

    //get the dataset version.
    headers = new JSONObject();
    headers.put(RestUtils.Headers.DATASET_VERSION_QUERY_ENABLED, true);
    restRequest = createRestRequest(RestMethod.GET, namedBlobPathUri, headers, null);
    restResponseChannel = new MockRestResponseChannel();
    doOperation(restRequest, restResponseChannel);
    //verify ttl succeed.
    //verify status.
    assertEquals("Mismatch on status", ResponseStatus.Ok, restResponseChannel.getStatus());
    assertNull("Mismatch on expiration time", restResponseChannel.getResponseHeaders().get(DATASET_EXPIRATION_TIME));
  }
Tests blob POST, GET, HEAD, TTL update and DELETE operations.
@throws Exception
ambry-frontend/src/test/java/com/github/ambry/frontend/FrontendRestRequestServiceTest.java