@Override
  public void run() {
    logger.info("Starting FileCopyThread: {} for replicaId: {}", threadName, fileCopyStatusListener.getReplicaId());

    try {
      ReplicaId replicaId = fileCopyStatusListener.getReplicaId();
      if (replicaId == null) {
        throw new IllegalStateException("ReplicaId cannot be null");
      }

      //TODO add logic to get the source and target replica id
      ReplicaId targetReplicaId = FileCopyUtils.getPeerForFileCopy(replicaId.getPartitionId(), replicaId.getDataNodeId().getDatacenterName());

      if (targetReplicaId == null) {
        logger.warn("No peer replica found for file copy for replicaId: {}", replicaId);
        fileCopyStatusListener.onFileCopyFailure(new IOException("No peer replica found for file copy"));
        return;
      }

      FileCopyInfo fileCopyInfo = new FileCopyInfo(START_CORRELATION_ID, CLIENT_ID, replicaId, targetReplicaId);
      fileCopyHandler.start();
      // Start the file copy process

      long startTime = System.currentTimeMillis();
      fileCopyHandler.copy(fileCopyInfo);
      logger.info("File copy completed for partition: {} in {} seconds",
          replicaId.getPartitionId().getId(), (System.currentTimeMillis() - startTime) / 1000);

      fileCopyStatusListener.onFileCopySuccess();
    } catch (Exception e) {
      fileCopyStatusListener.onFileCopyFailure(e);
    } finally {
      shutDownLatch.countDown();
    }
  }
Constructor for FileCopyThread
@param fileCopyHandler the file copy handler
@param fileCopyStatusListener the file copy status listener
ambry-file-transfer/src/main/java/com/github/ambry/filetransfer/FileCopyThread.java