protected void replicateBlob(String blobId, String serviceId, DataNodeId sourceDataNode,
      FutureResult<Void> futureResult, Callback<Void> callback) {
    try {
      replicateBlobManager.submitReplicateBlobOperation(blobId, serviceId, sourceDataNode, futureResult, callback);
      routerCallback.onPollReady();
    } catch (RouterException e) {
      routerMetrics.operationDequeuingRate.mark();
      routerMetrics.onReplicateBlobError(e);
      nonBlockingRouter.completeOperation(futureResult, callback, null, e);
    }
  }
Requests for a blob to be replicated asynchronously and invokes the {@link Callback} when the request
completes.
@param blobId ID of the blob that needs to be replicated.
@param serviceId The service ID of the service replicating the blob. This can be null if unknown.
@param sourceDataNode The source {@link DataNodeId} where to get the Blob.
@param futureResult A future that would contain the BlobId eventually.
@param callback The {@link Callback} which will be invoked on the completion of the request .
ambry-router/src/main/java/com/github/ambry/router/OperationController.java