1 // Copyright (C) 2018-2019,2021 Internet Systems Consortium, Inc. ("ISC") 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, v. 2.0. If a copy of the MPL was not distributed with this 5 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 7 #ifndef SERVER_SELECTOR_H 8 #define SERVER_SELECTOR_H 9 10 #include <cc/server_tag.h> 11 #include <set> 12 #include <string> 13 14 namespace isc { 15 namespace db { 16 17 /// @brief Server selector for associating objects in a database with 18 /// specific servers. 19 /// 20 /// Configuration information stored in the configuration backends can be 21 /// associated with selected servers, all servers or no particular server. 22 /// For example: a particular subnet definition in the database may be 23 /// associated with one server or can be shared by multiple servers. 24 /// In the latter case, a subnet may be associated with a subset of 25 /// servers or all servers. An administrator may also add the 26 /// configuration data into the database and do not associate this data 27 /// with any particular server. 28 /// 29 /// When fetching the configuration data from a database or when storing 30 /// data in the database there is a need to specify which servers this 31 /// data is associated with. The @c ServerSelector class represents 32 /// such associations. 33 /// 34 /// It includes three modes of selection: UNASSIGNED, ALL and SUBSET and 35 /// several factory functions making associations described above. 36 /// 37 /// The @c ServerSelector class should be used in objects derived from 38 /// @c BaseConfigBackendPool and in objects derived from 39 /// @c BaseConfigBackend to indicate which servers the specific calls 40 /// exposed by these objects refer to. 41 /// 42 /// @todo Add server selector for selecting only those configuration 43 /// elements that are associated with all servers (and not with any 44 /// particular server tags). Translating this to SQL queries it would 45 /// probably be an empty or non-existing server tag. 46 class ServerSelector { 47 public: 48 49 /// @brief Type of the server selection. 50 enum class Type { 51 UNASSIGNED, 52 ALL, 53 SUBSET, 54 ANY 55 }; 56 57 /// @brief Factory returning "unassigned" server selector. UNASSIGNED()58 static ServerSelector UNASSIGNED() { 59 ServerSelector selector(Type::UNASSIGNED); 60 return (selector); 61 } 62 63 /// @brief Factory returning "all servers" selector. ALL()64 static ServerSelector ALL() { 65 ServerSelector selector(Type::ALL); 66 return (selector); 67 } 68 69 /// @brief Factory returning selector of one server. 70 /// 71 /// @param server_tag tag of the single server to be selected. ONE(const std::string & server_tag)72 static ServerSelector ONE(const std::string& server_tag) { 73 ServerSelector selector((data::ServerTag(server_tag))); 74 return (selector); 75 } 76 77 /// @brief Factory returning "multiple servers" selector. 78 /// 79 /// @param server_tags set of server tags to be selected. 80 /// @throw InvalidOperation if no server tags provided. 81 static ServerSelector MULTIPLE(const std::set<std::string>& server_tags); 82 83 /// @brief Factory returning "any server" selector. ANY()84 static ServerSelector ANY() { 85 ServerSelector selector(Type::ANY); 86 return (selector); 87 } 88 89 /// @brief Returns type of the selector. getType()90 Type getType() const { 91 return (type_); 92 } 93 94 /// @brief Returns tags associated with the selector. 95 /// 96 /// @return server tags for multiple selections and for one server, 97 /// empty set for all servers and and unassigned. getTags()98 std::set<data::ServerTag> getTags() const { 99 return (tags_); 100 } 101 102 /// @brief Convenience method checking if the server selector has no tags. 103 /// 104 /// @return true when the server selector has no tags, false otherwise. hasNoTags()105 bool hasNoTags() const { 106 return (tags_.empty()); 107 } 108 109 /// @brief Convenience method checking if the server selector is "unassigned". 110 /// 111 /// @return true if the selector is "unassigned", false otherwise. amUnassigned()112 bool amUnassigned() const { 113 return (getType() == Type::UNASSIGNED); 114 } 115 116 /// @brief Convenience method checking if the server selector is "all". 117 /// 118 /// @return true if the selector is "all", false otherwise. amAll()119 bool amAll() const { 120 return (getType() == Type::ALL); 121 } 122 123 /// @brief Convenience method checking if the server selector is "any". 124 /// 125 /// @return true if the selector is "any", false otherwise. amAny()126 bool amAny() const { 127 return (getType() == Type::ANY); 128 } 129 130 /// @brief Convenience method checking if the server selector has multiple tags. 131 /// 132 /// @return true if it has multiple tags, false otherwise. hasMultipleTags()133 bool hasMultipleTags() const { 134 return (tags_.size() > 1); 135 } 136 137 private: 138 139 /// @brief Constructor used for "unassigned" and "all" selection types. 140 /// 141 /// @param type selector type. 142 explicit ServerSelector(const Type& type); 143 144 /// @brief Constructor used for selecting a single server. 145 /// 146 /// @param server_tag tag of the server to be selected. 147 explicit ServerSelector(const data::ServerTag& server_tag); 148 149 /// @brief Constructor used for selecting multiple servers. 150 /// 151 /// @param server_tags set of server tags. 152 explicit ServerSelector(const std::set<data::ServerTag>& server_tags); 153 154 /// @brief Selection type used. 155 Type type_; 156 157 /// @brief Holds tags of explicitly selected servers. 158 std::set<data::ServerTag> tags_; 159 }; 160 161 162 } // end of namespace isc::db 163 } // end of namespace isc 164 165 #endif 166