@Test
  public void updateNamedBlobAllowedTest() throws Exception {
    JSONObject headers = new JSONObject();
    FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, TestUtils.TTL_SECS, !REF_CONTAINER.isCacheable(),
        SERVICE_ID, CONTENT_TYPE, OWNER_ID, null, REF_CONTAINER_NO_UPDATE.getName(), null);
    headers.put(RestUtils.Headers.NAMED_UPSERT, false);
    byte[] content = TestUtils.getRandomBytes(1024);
    RestRequest request = getRestRequest(headers, request_noupdate_path, content);

    RestResponseChannel restResponseChannel = new MockRestResponseChannel();
    FutureResult<Void> future = new FutureResult<>();
    namedBlobPutHandler.handle(request, restResponseChannel, future::done);

    future.get(TIMEOUT_SECS, TimeUnit.SECONDS);
    // in id converter, the callback is invoked before the lastConvertedId is set, we need to wait
    // for a while before we can check the lastConvertedId.
    Thread.sleep(100);
    assertEquals("Unexpected location header", idConverterFactory.lastConvertedId,
        restResponseChannel.getHeader(RestUtils.Headers.LOCATION));
    InMemoryRouter.InMemoryBlob blob = router.getActiveBlobs().get(idConverterFactory.lastInput);
    assertEquals("Unexpected blob content stored", ByteBuffer.wrap(content), blob.getBlob());
    assertEquals("Unexpected TTL in blob", TestUtils.TTL_SECS, blob.getBlobProperties().getTimeToLiveInSeconds());
    assertEquals("Unexpected TTL in named blob DB", TestUtils.TTL_SECS,
        idConverterFactory.lastBlobProperties.getTimeToLiveInSeconds());
    assertEquals("Unexpected response status", restResponseChannel.getStatus(), ResponseStatus.Ok);
  }
Allow non-upsert put for container with NamedBlobMode = NO_UPDATE
ambry-frontend/src/test/java/com/github/ambry/frontend/NamedBlobPutHandlerTest.java