public ServerErrorCode repairPutBlob(ReplicateBlobRequest replicateBlobRequest, BlobId convertedBlobId,
      GetResponse remoteGetResponse) throws IOException {
    String remoteHostName = replicateBlobRequest.getSourceHostName();
    int remoteHostPort = replicateBlobRequest.getSourceHostPort();
    Store store = storeManager.getStore(convertedBlobId.getPartition());
    ServerErrorCode errorCode;
    try {
      // getBlobFromRemoteReplicate has checked partitionResponseInfoList's size is 1 and it has one MessageInfo.
      PartitionResponseInfo partitionResponseInfo = remoteGetResponse.getPartitionResponseInfoList().get(0);
      List<MessageInfo> messageInfoList = partitionResponseInfo.getMessageInfoList();
      MessageInfo remoteMessageInfo = messageInfoList.get(0);

      // Transfer the input stream with transformer
      Message output = MessageSievingInputStream.transferInputStream(Collections.singletonList(transformer.get()),
          remoteGetResponse.getInputStream(), remoteMessageInfo);
      if (output == null) {
        logger.error("ReplicateBlobRequest transferInputStream {} returned null, {} {} {}", remoteMessageInfo,
            remoteHostName, remoteHostPort, convertedBlobId);
        errorCode = ServerErrorCode.UnknownError;
      } else {
        // write the message to the local store
        MessageFormatWriteSet writeset =
            new MessageFormatWriteSet(output.getStream(), Collections.singletonList(output.getMessageInfo()), false);
        store.put(writeset);

        // also applyTtlUpdate and applyDelete if needed.
        // the operation time of TtlUpdate and Delete will be same as the source replica's PutBlob creation time.
        // But it's ok. Replication thread should have the same behavior.
        // We don't care the operation time of TtlUpdate and Delete that much.
        if (remoteMessageInfo.isTtlUpdated()) {
          applyTtlUpdate(remoteMessageInfo, replicateBlobRequest);
        }
        if (remoteMessageInfo.isDeleted()) {
          applyDelete(remoteMessageInfo, replicateBlobRequest);
        }
        logger.info("ReplicateBlobRequest replicated Blob {} from remote host {} {}", convertedBlobId, remoteHostName,
            remoteHostPort);
        errorCode = ServerErrorCode.NoError;
      } // if (output == null)
    } catch (StoreException e) { // catch the store write exception
      if (e.getErrorCode() == StoreErrorCodes.AlreadyExist) {
        logger.info("ReplicateBlobRequest Blob {} already exists for {}", convertedBlobId, replicateBlobRequest);
        errorCode = ServerErrorCode.NoError;
      } else {
        logger.error("ReplicateBlobRequest unknown exception to replicate {} of {}", convertedBlobId,
            replicateBlobRequest, e);
        errorCode = ErrorMapping.getStoreErrorMapping(e.getErrorCode());
      }
    }
    return errorCode;
  }
Get the Blob from the remote replica
@param replicateBlobRequest the {@link ReplicateBlobRequest}
@return a pair of the {@link ServerErrorCode} and the {@link GetResponse}.
ambry-server/src/main/java/com/github/ambry/server/AmbryRequests.java