void handleResponse(ResponseInfo responseInfo) {
    long startTime = time.milliseconds();
    UndeleteResponse undeleteResponse =
        RouterUtils.extractResponseAndNotifyResponseHandler(responseHandler, routerMetrics, responseInfo,
            UndeleteResponse::readFrom, UndeleteResponse::getError);
    RequestInfo routerRequestInfo = responseInfo.getRequestInfo();
    int correlationId = routerRequestInfo.getRequest().getCorrelationId();
    UndeleteOperation undeleteOperation = correlationIdToUndeleteOperation.remove(correlationId);
    // If it is still an active operation, hand over the response. Otherwise, ignore.
    if (undeleteOperations.contains(undeleteOperation)) {
      boolean exceptionEncountered = false;
      try {
        undeleteOperation.handleResponse(responseInfo, undeleteResponse);
      } catch (Exception e) {
        exceptionEncountered = true;
        undeleteOperation.setOperationException(
            new RouterException("Undelete handleResponse encountered unexpected error", e,
                RouterErrorCode.UnexpectedInternalError));
      }
      if (exceptionEncountered || undeleteOperation.isOperationComplete()) {
        if (undeleteOperations.remove(undeleteOperation)) {
          onComplete(undeleteOperation);
        }
      }
      routerMetrics.undeleteManagerHandleResponseTimeMs.update(time.milliseconds() - startTime);
    } else {
      routerMetrics.ignoredResponseCount.inc();
    }
  }
Handles responses received for each of the {@link UndeleteOperation} within this UndeleteManager.
@param responseInfo the {@link ResponseInfo} containing the response.
ambry-router/src/main/java/com/github/ambry/router/UndeleteManager.java