void handleResponse(ResponseInfo responseInfo, ReplicateBlobResponse replicateBlobResponse) {
    ReplicateBlobRequest replicateBlobRequest = (ReplicateBlobRequest) responseInfo.getRequestInfo().getRequest();
    RequestInfo replicateBlobRequestInfo = replicateBlobRequestInfos.remove(replicateBlobRequest.getCorrelationId());
    // ReplicateBlobRequestInfo can be null if this request was timed out before this response is received. No
    // metric is updated here, as corresponding metrics have been updated when the request was timed out.
    if (replicateBlobRequestInfo == null) {
      return;
    }
    ReplicaId replica = replicateBlobRequestInfo.getReplicaId();
    // Track the over all time taken for the response since the creation of the request.
    long requestLatencyMs = time.milliseconds() - replicateBlobRequestInfo.getRequestCreateTime();
    routerMetrics.routerRequestLatencyMs.update(requestLatencyMs);
    routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).replicateBlobRequestLatencyMs.update(
        requestLatencyMs);
    // Check the error code from NetworkClient.
    if (responseInfo.getError() != null) {
      logger.error("ReplicateBlobRequest {} with response correlationId {} timed out for replica {} ",
          replicateBlobRequest.getBlobId(), replicateBlobRequest.getCorrelationId(), replica.getDataNodeId());
      onErrorResponse(replica, new RouterException(
          "Operation to ReplicateBlob " + blobId + " timed out because of " + responseInfo.getError() + " at DataNode "
              + responseInfo.getDataNode(), RouterErrorCode.OperationTimedOut));
    } else {
      if (replicateBlobResponse == null) {
        logger.error(
            "ReplicateBlobRequest {} with correlationId {} received UnexpectedInternalError on deserialization for replica {} ",
            replicateBlobRequest.getBlobId(), replicateBlobRequest.getCorrelationId(), replica.getDataNodeId());
        onErrorResponse(replica, new RouterException("Response deserialization received an unexpected error",
            RouterErrorCode.UnexpectedInternalError));
      } else {
        // The true case below should not really happen. This means a response has been received
        // not for its original request. We will immediately fail this operation.
        if (replicateBlobResponse.getCorrelationId() != replicateBlobRequest.getCorrelationId()) {
          logger.error(
              "ReplicateBlobRequest {} the correlation id in the response {} is not the same as the id in the request: {}",
              replicateBlobRequest.getBlobId(), replicateBlobResponse.getCorrelationId(),
              replicateBlobRequest.getCorrelationId());
          routerMetrics.unknownReplicaResponseError.inc();
          onErrorResponse(replica,
              new RouterException("Received wrong response that is not for the corresponding request.",
                  RouterErrorCode.UnexpectedInternalError));
        } else {
          ServerErrorCode serverError = replicateBlobResponse.getError();
          if (serverError == ServerErrorCode.NoError || serverError == ServerErrorCode.BlobAlreadyExists) {
            operationTracker.onResponse(replica, TrackedRequestFinalState.SUCCESS);
            logger.info("ReplicateBlob {} successful for replica {} in {} with correlationId {} ",
                replicateBlobRequest.getBlobId(), replica.getDataNodeId(), replica.getDataNodeId().getDatacenterName(),
                replicateBlobRequest.getCorrelationId());
            if (RouterUtils.isRemoteReplica(routerConfig, replica)) {
              routerMetrics.crossColoSuccessCount.inc();
            }
          } else if (serverError == ServerErrorCode.DiskUnavailable) {
            logger.error("Replica {} {} returned Disk_Unavailable for a ReplicateBlob request with correlationId : {} ",
                replicateBlobRequest.getBlobId(), replica.getDataNodeId(), replicateBlobRequest.getCorrelationId());
            operationTracker.onResponse(replica, TrackedRequestFinalState.DISK_DOWN);
            setOperationException(
                new RouterException("Server returned: " + serverError, RouterErrorCode.AmbryUnavailable));
            routerMetrics.routerRequestErrorCount.inc();
            routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).replicateBlobRequestErrorCount.inc();
          } else {
            logger.error(
                "Replica {} {} returned error {} for a ReplicateBlob request with response correlationId : {} ",
                replicateBlobRequest.getBlobId(), replica.getDataNodeId(), serverError,
                replicateBlobRequest.getCorrelationId());
            RouterErrorCode routerErrorCode = processServerError(serverError);
            if (serverError == ServerErrorCode.BlobAuthorizationFailure) {
              // this is a successful response and one that completes the operation regardless of whether the
              // success target has been reached or not.
              operationCompleted = true;
            }
            // any server error code that is not equal to ServerErrorCode.No_Error, the onErrorResponse should be invoked
            onErrorResponse(replica, new RouterException("Server returned: " + serverError, routerErrorCode));
          }
        }
      }
    }
    checkAndMaybeComplete();
  }
Handles a response for a ReplicateBlob operation. It determines whether the request was successful,
updates operation tracker, and notifies the response handler for failure detection.
can be different cases during handling a response. For the same ReplicateBlob operation, it is possible
that different {@link ServerErrorCode} are received from different replicas. These error codes
are eventually resolved to a single {@link RouterErrorCode}.
@param responseInfo The {@link ResponseInfo} to be handled.
@param replicateBlobResponse The {@link ReplicateBlobResponse} associated with this response.
ambry-router/src/main/java/com/github/ambry/router/ReplicateBlobOperation.java