private void stitchDatasetVersionAndVerify(byte[] requestBody, List<ChunkInfo> expectedStitchedChunks)
      throws Exception {
    for (long ttl : new long[]{TestUtils.TTL_SECS, Utils.Infinite_Time}) {
      JSONObject headers = new JSONObject();
      FrontendRestRequestServiceTest.setAmbryHeadersForPut(headers, ttl, !REF_CONTAINER.isCacheable(), SERVICE_ID,
          CONTENT_TYPE, OWNER_ID, null, null, null);
      headers.put(RestUtils.Headers.DATASET_VERSION_QUERY_ENABLED, true);
      headers.put(RestUtils.Headers.UPLOAD_NAMED_BLOB_MODE, "STITCH");
      RestRequest request = getRestRequest(headers, dataset_version_request_path, requestBody);
      RestResponseChannel restResponseChannel = new MockRestResponseChannel();
      FutureResult<Void> future = new FutureResult<>();
      idConverterFactory.lastInput = null;
      idConverterFactory.lastBlobProperties = null;
      idConverterFactory.lastConvertedId = null;
      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("List of chunks stitched does not match expected", expectedStitchedChunks, blob.getStitchedChunks());
      ByteArrayOutputStream expectedContent = new ByteArrayOutputStream();
      expectedStitchedChunks.stream()
          .map(chunkInfo -> router.getActiveBlobs().get(chunkInfo.getBlobId()).getBlob().array())
          .forEach(buf -> expectedContent.write(buf, 0, buf.length));
      assertEquals("Unexpected blob content stored", ByteBuffer.wrap(expectedContent.toByteArray()), blob.getBlob());
      //check actual size of stitched blob
      assertEquals("Unexpected blob size", Long.toString(getStitchedBlobSize(expectedStitchedChunks)),
          restResponseChannel.getHeader(RestUtils.Headers.BLOB_SIZE));
      assertEquals("Unexpected TTL in named blob DB", -1,
          idConverterFactory.lastBlobProperties.getTimeToLiveInSeconds());
      assertEquals("Unexpected TTL in blob", -1, blob.getBlobProperties().getTimeToLiveInSeconds());
    }
  }
Make a stitch call using {@link NamedBlobPutHandler} and verify the result of the operation.
@param requestBody the body of the stitch request to supply.
@param expectedStitchedChunks the expected chunks stitched together.
@throws Exception
ambry-frontend/src/test/java/com/github/ambry/frontend/NamedBlobPutHandlerTest.java