private void testEncryptDecryptFlow(SecretKeySpec perBlobKey, CountDownLatch encryptCallBackCount,
      CountDownLatch decryptCallBackCount, Mode mode) {
    TestBlobData randomData = getRandomBlob(referenceClusterMap);
    ByteBuf content = mode != Mode.UserMetadata ? randomData.blobContent.retainedDuplicate() : null;
    ByteBuffer userMetadata = mode != Mode.Data ? randomData.userMetadata : null;
    cryptoJobHandler.submitJob(
        new EncryptJob(randomData.blobId.getAccountId(), randomData.blobId.getContainerId(), content, userMetadata,
            perBlobKey, cryptoService, kms, null, new CryptoJobMetricsTracker(routerMetrics.encryptJobMetrics),
            new EncryptCallbackVerifier(randomData.blobId, false, encryptCallBackCount,
                new DecryptCallbackVerifier(randomData.blobId, content != null ? content.retainedDuplicate() : null,
                    userMetadata, false, decryptCallBackCount), mode)));
    randomData.blobContent.release();
  }
Tests encryption and decryption flow for happy path
@param perBlobKey the {@link SecretKeySpec} representing the per blob key
@param encryptCallBackCount {@link CountDownLatch} to track encryption callbacks
@param decryptCallBackCount {@link CountDownLatch} to track decryption callbacks
@param mode State to be tested for encrypt decrypt flow. Blob content only, UserMetadata only, or both
ambry-router/src/test/java/com/github/ambry/router/CryptoJobHandlerTest.java