| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #pragma once |
| |
| #include <gen_cpp/cloud.pb.h> |
| |
| #include <map> |
| #include <shared_mutex> |
| #include <string> |
| |
| #include "meta-store/txn_kv.h" |
| #include "meta-store/txn_kv_error.h" |
| |
| namespace doris::cloud { |
| |
| enum class Role : int { |
| UNDEFINED, |
| SQL_SERVER, |
| COMPUTE_NODE, |
| }; |
| |
| struct NodeInfo { |
| Role role; |
| std::string instance_id; |
| std::string cluster_name; |
| std::string cluster_id; |
| NodeInfoPB node_info; |
| }; |
| |
| struct ClusterInfo { |
| ClusterPB cluster; |
| }; |
| |
| /** |
| * This class manages resources referenced by cloud cloud. |
| * It manage a in-memory |
| */ |
| class ResourceManager { |
| public: |
| ResourceManager(std::shared_ptr<TxnKv> txn_kv) : txn_kv_(txn_kv) {}; |
| virtual ~ResourceManager() = default; |
| /** |
| * Loads all instance into memory and build an index |
| * |
| * @return 0 for success, non-zero for failure |
| */ |
| virtual int init(); |
| |
| /** |
| * Gets nodes with given cloud unique id |
| * |
| * @param cloud_unique_id the cloud_unique_id attached to the node when it was added to the |
| * instance |
| * @param node output param |
| * @return empty string for success, otherwise failure reason returned |
| */ |
| virtual std::string get_node(const std::string& cloud_unique_id, std::vector<NodeInfo>* nodes); |
| |
| virtual std::pair<MetaServiceCode, std::string> add_cluster(const std::string& instance_id, |
| const ClusterInfo& cluster); |
| |
| /** |
| * Drops a cluster |
| * |
| * @param cluster cluster to drop, only cluster name and cluster id are concered |
| * @return empty string for success, otherwise failure reason returned |
| */ |
| virtual std::pair<MetaServiceCode, std::string> drop_cluster(const std::string& instance_id, |
| const ClusterInfo& cluster); |
| |
| /** |
| * Update a cluster |
| * |
| * @param cluster cluster to update, only cluster name and cluster id are concered |
| * @param action update operation code snippet |
| * @param replace_if_existing_empty_target_cluster, find cluster.cluster_name is a empty cluster(no node), drop it |
| * @filter filter condition |
| * @return empty string for success, otherwise failure reason returned |
| */ |
| virtual std::string update_cluster( |
| const std::string& instance_id, const ClusterInfo& cluster, |
| std::function<bool(const ClusterPB&)> filter, |
| std::function<std::string(ClusterPB&, std::vector<ClusterPB>& clusters_in_instance)> |
| action, |
| bool replace_if_existing_empty_target_cluster = false); |
| |
| /** |
| * Get instance from underlying storage with given transaction. |
| * |
| * @param txn if txn is not given, get with a new txn inside this function |
| * |
| * @return a <code, msg> pair, code == TXN_OK for success, otherwise error |
| */ |
| virtual std::pair<TxnErrorCode, std::string> get_instance(std::shared_ptr<Transaction> txn, |
| const std::string& instance_id, |
| InstanceInfoPB* inst_pb); |
| /** |
| * Modifies the nodes associated with a given instance. |
| * This function allows adding and removing nodes from the instance. |
| * |
| * @param instance_id The ID of the instance to modify nodes for. |
| * @param to_add A vector of NodeInfo structures representing nodes to be added. |
| * @param to_del A vector of NodeInfo structures representing nodes to be removed. |
| * @return An error message if the operation fails, or an empty string for success. |
| */ |
| virtual std::string modify_nodes(const std::string& instance_id, |
| const std::vector<NodeInfo>& to_add, |
| const std::vector<NodeInfo>& to_del); |
| |
| /** |
| * Checks the validity of the parameters for a cluster. |
| * This function verifies if the provided cluster parameters meet the required conditions. |
| * |
| * @param cluster The ClusterPB structure containing the cluster parameters to validate. |
| * @param err Output parameter to store any error message if validation fails. |
| * @param check_master_num Flag indicating whether to check the number of master nodes. |
| * @param check_cluster_name Flag indicating whether to check the cluster name is empty, just add_cluster need. |
| * @return True if the parameters are valid, false otherwise. |
| */ |
| bool check_cluster_params_valid(const ClusterPB& cluster, std::string* err, |
| bool check_master_num, bool check_cluster_name); |
| |
| /** |
| * Validates the cluster name against a regex pattern. |
| * |
| * @param cluster The ClusterPB object containing the cluster information. |
| * @param err Output parameter to store error message if validation fails. |
| * @param need check cluster name |
| * @return true if the cluster name is valid, false otherwise. |
| */ |
| bool validate_cluster_name(const ClusterPB& cluster, std::string* err, bool check_cluster_name); |
| |
| /** |
| * Validates the nodes in the cluster, checking for cloud unique IDs |
| * and counting master and follower nodes. |
| * |
| * @param cluster The ClusterPB object containing the cluster information. |
| * @param err Output parameter to store error message if validation fails. |
| * @param check_master_num Flag indicating whether to check master and follower counts. |
| * @return true if the nodes are valid, false otherwise. |
| */ |
| bool validate_nodes(const ClusterPB& cluster, std::string* err, bool check_master_num); |
| |
| /** |
| * Validates the counts of master and follower nodes for SQL clusters. |
| * |
| * @param master_num The number of master nodes. |
| * @param follower_num The number of follower nodes. |
| * @param err Output parameter to store error message if validation fails. |
| * @return true if the counts are valid, false otherwise. |
| */ |
| bool validate_master_follower_count(int master_num, int follower_num, std::string* err); |
| |
| /** |
| * Validates the specifics of virtual clusters, including cluster names |
| * and policies. |
| * |
| * @param cluster The ClusterPB object containing the cluster information. |
| * @param err Output parameter to store error message if validation fails. |
| * @return true if the virtual cluster is valid, false otherwise. |
| */ |
| bool validate_virtual_cluster(const ClusterPB& cluster, std::string* err); |
| |
| /** |
| * Check cloud_unique_id is degraded format, and get instance_id from cloud_unique_id |
| * degraded format : "${version}:${instance_id}:${unique_id}" |
| * @param degraded cloud_unique_id |
| * |
| * @return a <is_degraded_format, instance_id> pair, if is_degraded_format == true , instance_id, if is_degraded_format == false, instance_id="" |
| */ |
| static std::pair<bool, std::string> get_instance_id_by_cloud_unique_id( |
| const std::string& cloud_unique_id); |
| |
| /** |
| * check instance_id is a valid instance, check by get fdb kv |
| * |
| * @param instance_id |
| * |
| * @return true, instance_id in fdb kv |
| */ |
| bool is_instance_id_registered(const std::string& instance_id); |
| |
| /** |
| * Refreshes the cache of given instance. This process removes the instance in cache |
| * and then replaces it with persisted instance state read from underlying KV storage. |
| * |
| * @param instance_id instance to manipulate |
| * @return a pair of code and msg |
| */ |
| virtual std::pair<MetaServiceCode, std::string> refresh_instance( |
| const std::string& instance_id); |
| |
| /** |
| * Refreshes the cache of given instance from provided InstanceInfoPB. This process |
| * removes the instance in cache and then replaces it with provided instance state. |
| * |
| * @param instance_id instance to manipulate |
| * @param instance the instance info to refresh from |
| */ |
| virtual void refresh_instance(const std::string& instance_id, const InstanceInfoPB& instance); |
| |
| virtual bool is_version_read_enabled(std::string_view instance_id) const; |
| |
| virtual bool is_version_write_enabled(std::string_view instance_id) const; |
| |
| virtual bool get_source_snapshot_info(const std::string& instance_id, |
| std::string* source_instance_id, |
| Versionstamp* source_snapshot_version); |
| |
| std::pair<MetaServiceCode, std::string> validate_sub_clusters( |
| const std::vector<std::string>& check_clusters, |
| const std::vector<ClusterPB>& clusters_in_instance); |
| |
| private: |
| void add_cluster_to_index_no_lock(const std::string& instance_id, const ClusterPB& cluster); |
| |
| MultiVersionStatus get_instance_multi_version_status(std::string_view instance_id) const; |
| |
| mutable std::shared_mutex mtx_; |
| // cloud_unique_id -> NodeInfo |
| std::multimap<std::string, NodeInfo> node_info_; |
| |
| // instance_id -> MultiVersionStatus |
| std::unordered_map<std::string, MultiVersionStatus> instance_multi_version_status_; |
| |
| // instance_id -> (source_instance_id, source_snapshot_version) |
| std::unordered_map<std::string, std::pair<std::string, Versionstamp>> |
| instance_source_snapshot_info_; |
| |
| std::shared_ptr<TxnKv> txn_kv_; |
| }; |
| |
| } // namespace doris::cloud |