GfErrType ThinClientPoolDM::sendRequestToEP()

in cppcache/src/ThinClientPoolDM.cpp [1841:1995]


GfErrType ThinClientPoolDM::sendRequestToEP(const TcrMessage& request,
                                            TcrMessageReply& reply,
                                            TcrEndpoint* currentEndpoint) {
  LOGDEBUG("ThinClientPoolDM::sendRequestToEP()");
  int isAuthRequireExcepMaxTry = 2;
  bool isAuthRequireExcep = true;
  GfErrType error = GF_NOERR;
  while (isAuthRequireExcep && isAuthRequireExcepMaxTry >= 0) {
    isAuthRequireExcep = false;
    TcrConnection* conn = getFromEP(currentEndpoint);

    bool isTmpConnectedStatus = false;
    bool putConnInPool = true;
    if (conn == nullptr) {
      LOGDEBUG(
          "ThinClientPoolDM::sendRequestToEP(): got nullptr connection from "
          "pool, "
          "creating new connection in the pool.");
      bool maxConnLimit = false;
      error =
          createPoolConnectionToAEndPoint(conn, currentEndpoint, maxConnLimit);
      if (conn == nullptr || error != GF_NOERR) {
        LOGDEBUG(
            "ThinClientPoolDM::sendRequestToEP(): couldnt create a pool "
            "connection, creating a temporary connection.");
        error =
            currentEndpoint->createNewConnection(conn, false, false,
                                                 m_connManager.getCacheImpl()
                                                     ->getDistributedSystem()
                                                     .getSystemProperties()
                                                     .connectTimeout(),
                                                 false);
        putConnInPool = false;
        currentEndpoint->setConnectionStatus(true);
      }
    }

    if (conn == nullptr || error != GF_NOERR) {
      LOGFINE("3Failed to connect to %s", currentEndpoint->name().c_str());
      if (conn != nullptr) {
        _GEODE_SAFE_DELETE(conn);
      }
      if (putConnInPool) {
        reducePoolSize(1);
      }
      currentEndpoint->setConnectionStatus(false);
      return error;
    } else if (!putConnInPool && !currentEndpoint->connected()) {
      isTmpConnectedStatus = true;
      currentEndpoint->setConnectionStatus(true);
    }

    int32_t type = request.getMessageType();

    if (!(type == TcrMessage::QUERY || type == TcrMessage::PUTALL ||
          type == TcrMessage::PUT_ALL_WITH_CALLBACK ||
          type == TcrMessage::EXECUTE_FUNCTION ||
          type == TcrMessage::EXECUTE_REGION_FUNCTION ||
          type == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP ||
          type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE)) {
      reply.setTimeout(getReadTimeout());
    }

    reply.setDM(this);
    std::shared_ptr<UserAttributes> ua = nullptr;
    // in multi user mode need to chk whether user is authenticated or not
    // and then follow usual process which we did in send syncrequest.
    // need to user initiative ops
    LOGDEBUG("ThinClientPoolDM::sendRequestToEP: m_isMultiUserMode = %d",
             m_isMultiUserMode);
    bool isServerException = false;
    if (TcrMessage::isUserInitiativeOps((request)) &&
        (m_isSecurityOn || m_isMultiUserMode)) {
      if (!m_isMultiUserMode && !currentEndpoint->isAuthenticated()) {
        // first authenticate him on this endpoint
        error = sendUserCredentials(getCredentials(currentEndpoint), conn,
                                    false, isServerException);
      } else if (m_isMultiUserMode) {
        ua = UserAttributes::threadLocalUserAttributes;
        if (ua) {
          UserConnectionAttributes* uca =
              ua->getConnectionAttribute(currentEndpoint);

          if (uca == nullptr) {
            error = sendUserCredentials(ua->getCredentials(), conn, false,
                                        isServerException);
          }
        } else {
          LOGWARN("Attempted operation type %d without credentials",
                  request.getMessageType());
          if (conn) {
            putInQueue(conn, false, request.forTransaction());
          }
          return GF_NOT_AUTHORIZED_EXCEPTION;
        }
      }
    }

    LOGDEBUG("ThinClientPoolDM::sendRequestToEP after getting creds");
    if (error == GF_NOERR && conn != nullptr) {
      error =
          currentEndpoint->sendRequestConnWithRetry(request, reply, conn, true);
    }

    if (isServerException) return error;

    if (error == GF_NOERR) {
      int32_t replyMsgType = reply.getMessageType();
      if (replyMsgType == TcrMessage::EXCEPTION ||
          replyMsgType == TcrMessage::CQ_EXCEPTION_TYPE ||
          replyMsgType == TcrMessage::CQDATAERROR_MSG_TYPE) {
        error = ThinClientRegion::handleServerException(
            "ThinClientPoolDM::sendRequestToEP", reply.getException());
      }

      if (putConnInPool) {
        put(conn, false);
      } else {
        if (isTmpConnectedStatus) currentEndpoint->setConnectionStatus(false);
        conn->close();
        _GEODE_SAFE_DELETE(conn);
      }
    } else if (error != GF_NOERR) {
      currentEndpoint->setConnectionStatus(false);
      if (putConnInPool) {
        removeEPConnections(1);
      }
      removeEPFromMetadataIfError(error, currentEndpoint);
    }

    if (error == GF_NOERR || error == GF_CACHESERVER_EXCEPTION ||
        error == GF_AUTHENTICATION_REQUIRED_EXCEPTION) {
      if ((m_isSecurityOn || m_isMultiUserMode)) {
        if (reply.getMessageType() == TcrMessage::EXCEPTION) {
          if (isAuthRequireException(reply.getException())) {
            if (!m_isMultiUserMode) {
              currentEndpoint->setAuthenticated(false);
            } else if (ua != nullptr) {
              ua->unAuthenticateEP(currentEndpoint);
            }
            LOGFINEST(
                "After getting AuthenticationRequiredException trying "
                "again.");
            isAuthRequireExcepMaxTry--;
            isAuthRequireExcep = true;
            if (isAuthRequireExcepMaxTry >= 0) error = GF_NOERR;
            continue;
          }
        }
      }
    }
  }
  LOGDEBUG("ThinClientPoolDM::sendRequestToEP Done.");
  return error;
}