368 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			368 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * Copyright (c) 2021 OceanBase
 | 
						|
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
						|
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
						|
 * You may obtain a copy of Mulan PubL v2 at:
 | 
						|
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
						|
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
 * See the Mulan PubL v2 for more details.
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef OCEANBASE_ROOTSERVER_TEST_FAKE_SERVER_MANAGER_H
 | 
						|
#define OCEANBASE_ROOTSERVER_TEST_FAKE_SERVER_MANAGER_H
 | 
						|
#include "rootserver/ob_server_manager.h"
 | 
						|
#include "lib/container/ob_array_iterator.h"
 | 
						|
#include "share/ob_server_status.h"
 | 
						|
#include "rootserver/ob_zone_manager.h"
 | 
						|
namespace oceanbase
 | 
						|
{
 | 
						|
namespace rootserver
 | 
						|
{
 | 
						|
class FakeServerMgr :  public ObServerManager
 | 
						|
  {
 | 
						|
  public:
 | 
						|
    FakeServerMgr() : server_id_(0) {}
 | 
						|
    ~FakeServerMgr() {}
 | 
						|
    void fake_init(ObZoneManager *zone_mgr) { inited_ = true; zone_mgr_ = zone_mgr; }
 | 
						|
    int add_server(const common::ObAddr &server, const ObZone &zone);
 | 
						|
    virtual int get_server_statuses(const common::ObZone &zone,
 | 
						|
                                    common::ObArray<share::ObServerStatus> &server_statuses) const
 | 
						|
    {
 | 
						|
      UNUSED(zone); // always get all zone
 | 
						|
      return server_statuses.assign(server_statuses_);
 | 
						|
    }
 | 
						|
 | 
						|
  private:
 | 
						|
    int64_t server_id_;
 | 
						|
    ObZoneManager * zone_mgr_;
 | 
						|
  };
 | 
						|
int FakeServerMgr::add_server(const common::ObAddr &server, const ObZone &zone)
 | 
						|
{
 | 
						|
  int ret = common::OB_SUCCESS;
 | 
						|
  share::ObServerStatus *server_status = NULL;
 | 
						|
  if (!server.is_valid() || OB_ISNULL(zone_mgr_)) {
 | 
						|
    ret = OB_INVALID_ARGUMENT;
 | 
						|
    RS_LOG(WARN, "invalid server", K(server), K(zone_mgr_), K(ret));
 | 
						|
  } else if (!zone.is_empty()) {
 | 
						|
    bool zone_active = false;
 | 
						|
    if (OB_FAIL(zone_mgr_->check_zone_active(zone, zone_active))) {
 | 
						|
      RS_LOG(WARN, "check_zone_active failed", K(zone), K(ret));
 | 
						|
    } else if (!zone_active) {
 | 
						|
      ret = common::OB_ZONE_NOT_ACTIVE;
 | 
						|
      RS_LOG(WARN, "zone not active", K(zone), K(ret));
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (OB_SUCC(ret)) {
 | 
						|
    if (OB_SUCC(find(server, server_status))) {
 | 
						|
      if (NULL == server_status) {
 | 
						|
        ret = common::OB_ERR_UNEXPECTED;
 | 
						|
        RS_LOG(WARN, "server_status is null", K(ret));
 | 
						|
      } else if (!server_status->is_status_valid()) {
 | 
						|
        ret = common::OB_ERR_UNEXPECTED;
 | 
						|
        RS_LOG(WARN, "status not valid", K(ret), "status", *server_status);
 | 
						|
      } else {
 | 
						|
        ret = common::OB_ENTRY_EXIST;
 | 
						|
        RS_LOG(WARN, "server already added", K(server), K(ret));
 | 
						|
      }
 | 
						|
    } else if (common::OB_ENTRY_NOT_EXIST != ret) {
 | 
						|
      RS_LOG(WARN, "find failed", K(server), K(ret));
 | 
						|
    } else {
 | 
						|
      ret = common::OB_SUCCESS;
 | 
						|
      share::ObServerStatus new_server_status;
 | 
						|
      new_server_status.id_ = server_id_++;
 | 
						|
      new_server_status.server_ = server;
 | 
						|
      new_server_status.zone_ = zone;
 | 
						|
      new_server_status.admin_status_ = share::ObServerStatus::OB_SERVER_ADMIN_NORMAL;
 | 
						|
      new_server_status.hb_status_ = share::ObServerStatus::OB_HEARTBEAT_ALIVE;
 | 
						|
      new_server_status.merged_version_ = 2;
 | 
						|
      if (OB_FAIL(server_statuses_.push_back(new_server_status))) {
 | 
						|
        RS_LOG(WARN, "push_back failed", K(ret));
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  RS_LOG(INFO, "add new server", K(server), K(zone), K(ret));
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
class FakeServerManager : public ObServerManager
 | 
						|
{
 | 
						|
public:
 | 
						|
  void set_is_inited(bool is_inited)
 | 
						|
  {
 | 
						|
    UNUSED(is_inited);
 | 
						|
    //inited_ = is_inited;
 | 
						|
  }
 | 
						|
 | 
						|
  void set(const common::ObZone &zone, const common::ObAddr &addr,
 | 
						|
      share::ObServerStatus::DisplayStatus stat = share::ObServerStatus::OB_SERVER_ACTIVE)
 | 
						|
  {
 | 
						|
    share::ObServerStatus *server = NULL;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == addr) {
 | 
						|
        server = &(*s);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (NULL == server) {
 | 
						|
      share::ObServerStatus new_server;
 | 
						|
      new_server.server_ = addr;
 | 
						|
      all_.push_back(new_server);
 | 
						|
      server = &all_.at(all_.count() - 1);
 | 
						|
    }
 | 
						|
    server->zone_ = zone;
 | 
						|
    server->admin_status_ = share::ObServerStatus::OB_SERVER_ADMIN_NORMAL;
 | 
						|
    if (share::ObServerStatus::OB_SERVER_ACTIVE == stat) {
 | 
						|
      server->hb_status_ = share::ObServerStatus::OB_HEARTBEAT_ALIVE;
 | 
						|
      server->start_service_time_ = common::ObTimeUtility::current_time();
 | 
						|
    } else {
 | 
						|
      server->hb_status_ = share::ObServerStatus::OB_HEARTBEAT_LEASE_EXPIRED;
 | 
						|
      server->start_service_time_ = 0;
 | 
						|
    }
 | 
						|
    if (share::ObServerStatus::OB_SERVER_DELETING == stat) {
 | 
						|
      server->admin_status_ = share::ObServerStatus::OB_SERVER_ADMIN_DELETING;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  virtual int check_server_alive(const common::ObAddr &server, bool &alive) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    alive = false;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        alive = s->is_alive();
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  int set_server_version(const common::ObAddr &server, const char *version)
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        MEMCPY(s->build_version_, version, common::OB_SERVER_VERSION_LENGTH);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
  int get_min_server_version(char min_server_version[OB_SERVER_VERSION_LENGTH])
 | 
						|
  {
 | 
						|
    int ret = OB_SUCCESS;
 | 
						|
    ObClusterVersion version_parser;
 | 
						|
    uint64_t cur_min_version = UINT64_MAX;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      char *saveptr = NULL;
 | 
						|
      char *version = STRTOK_R(s->build_version_, "_", &saveptr);
 | 
						|
      if (NULL == version || strlen(version) + 1 > OB_SERVER_VERSION_LENGTH) {
 | 
						|
        ret = OB_INVALID_ARGUMENT;
 | 
						|
        RS_LOG(WARN, "invalid build version format", "build_version", s->build_version_);
 | 
						|
      } else if (OB_FAIL(version_parser.refresh_cluster_version(version))) {
 | 
						|
        RS_LOG(WARN, "failed to parse version", "version", version);
 | 
						|
      } else {
 | 
						|
        if (version_parser.get_cluster_version() < cur_min_version) {
 | 
						|
          size_t len = strlen(version);
 | 
						|
          MEMCPY(min_server_version, version, len);
 | 
						|
          min_server_version[len] = '\0';
 | 
						|
          cur_min_version = version_parser.get_cluster_version();
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  virtual int check_server_active(const common::ObAddr &server, bool &active) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    active = false;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        active = s->is_active();
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  virtual int check_in_service(const common::ObAddr &server, bool &in_service) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    bool exist = false;
 | 
						|
    in_service = false;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        in_service = s->in_service();
 | 
						|
        exist = true;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!exist) {
 | 
						|
      ret = common::OB_ENTRY_NOT_EXIST;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  virtual int check_migrate_in_blocked(const common::ObAddr &server, bool &blocked) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    bool exist = false;
 | 
						|
    blocked = false;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        blocked = s->is_migrate_in_blocked();
 | 
						|
        exist = true;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (!exist) {
 | 
						|
      ret = common::OB_ENTRY_NOT_EXIST;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  virtual int get_server_statuses(const common::ObZone &zone,
 | 
						|
      common::ObArray<share::ObServerStatus> &server_statuses) const
 | 
						|
  {
 | 
						|
    UNUSED(zone); // always get all zone
 | 
						|
    return server_statuses.assign(all_);
 | 
						|
  }
 | 
						|
  int get_servers_of_zone(const common::ObZone &zone,
 | 
						|
      ObServerManager::ObServerArray &server_list) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    FOREACH_X(s, all_, common::OB_SUCCESS == ret) {
 | 
						|
      if (zone.is_empty() || zone == s->zone_) {
 | 
						|
        if (OB_FAIL(server_list.push_back(s->server_))) {
 | 
						|
          RS_LOG(WARN, "add server failed", K(ret));
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  virtual int get_server_status(const common::ObAddr &server,
 | 
						|
      share::ObServerStatus &server_status)
 | 
						|
  {
 | 
						|
    int ret = common::OB_ENTRY_NOT_EXIST;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        server_status = *s;
 | 
						|
        ret = common::OB_SUCCESS;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  int get_alive_servers(const common::ObZone &zone,
 | 
						|
      ObServerManager::ObIServerArray &server_list) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    FOREACH_X(s, all_, common::OB_SUCCESS == ret) {
 | 
						|
      if (!s->is_alive()) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      if (zone.is_empty() || zone == s->zone_) {
 | 
						|
        if (OB_FAIL(server_list.push_back(s->server_))) {
 | 
						|
          RS_LOG(WARN, "add server failed", K(ret));
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
  int get_server_zone(const common::ObAddr &addr, common::ObZone &zone) const
 | 
						|
  {
 | 
						|
    int ret = common::OB_ENTRY_NOT_EXIST;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == addr) {
 | 
						|
        zone = s->zone_;
 | 
						|
        ret = common::OB_SUCCESS;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  share::ObServerStatus *get(const common::ObAddr &addr)
 | 
						|
  {
 | 
						|
    share::ObServerStatus *stat = NULL;
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == addr) {
 | 
						|
        stat = &(*s);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return stat;
 | 
						|
  }
 | 
						|
 | 
						|
  int delete_server(const common::ObAddr &server, const common::ObZone &zone)
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    UNUSED(zone);
 | 
						|
    FOREACH(s, all_) {
 | 
						|
      if (s->server_ == server) {
 | 
						|
        s->admin_status_ = share::ObServerStatus::OB_SERVER_ADMIN_DELETING;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  int end_delete_server(const common::ObAddr &server, const common::ObZone &zone,
 | 
						|
                        const bool commit)
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    UNUSED(zone);
 | 
						|
    int64_t index = -1;
 | 
						|
    for (int64_t i = 0; i < all_.count(); ++i) {
 | 
						|
      if (all_.at(i).server_ == server) {
 | 
						|
        index = i;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (-1 != index) {
 | 
						|
      if (commit) {
 | 
						|
        if (OB_FAIL(all_.remove(index))) {
 | 
						|
          RS_LOG(WARN, "remove failed", K(index), K(ret));
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        all_.at(index).admin_status_ = share::ObServerStatus::OB_SERVER_ADMIN_NORMAL;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  int set_with_partition(const common::ObAddr &server)
 | 
						|
  {
 | 
						|
    UNUSED(server);
 | 
						|
    return common::OB_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  int set_force_stop_hb(const common::ObAddr &server, const bool &force_stop_hb)
 | 
						|
  {
 | 
						|
    int ret = common::OB_SUCCESS;
 | 
						|
    int64_t index = -1;
 | 
						|
    for (int64_t i = 0; i < all_.count(); ++i) {
 | 
						|
      if (all_.at(i).server_ == server) {
 | 
						|
        index = i;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (-1 != index) {
 | 
						|
      if (share::ObServerStatus::OB_SERVER_ADMIN_DELETING == all_.at(index).admin_status_) {
 | 
						|
        all_.at(index).force_stop_hb_ = force_stop_hb;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
  }
 | 
						|
 | 
						|
  void set_inited(bool inited)
 | 
						|
  {
 | 
						|
    inited_ = inited;
 | 
						|
  }
 | 
						|
public:
 | 
						|
  common::ObArray<share::ObServerStatus> all_;
 | 
						|
};
 | 
						|
 | 
						|
} // end namespace rootserver
 | 
						|
} // end namespace oceanbase
 | 
						|
#endif
 |