]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#676] Modified internal representation of the tags in ServerSelector.
authorMarcin Siodelski <marcin@isc.org>
Fri, 28 Jun 2019 13:58:26 +0000 (15:58 +0200)
committerFrancis Dupont <fdupont@isc.org>
Sun, 30 Jun 2019 12:35:44 +0000 (08:35 -0400)
16 files changed:
src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc
src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc
src/hooks/dhcp/mysql_cb/mysql_cb_impl.cc
src/hooks/dhcp/mysql_cb/mysql_cb_impl.h
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc
src/lib/cc/server_tag.cc
src/lib/cc/server_tag.h
src/lib/database/Makefile.am
src/lib/database/server_selector.cc [new file with mode: 0644]
src/lib/database/server_selector.h
src/lib/database/tests/server_selector_unittest.cc
src/lib/dhcpsrv/testutils/test_config_backend.h
src/lib/dhcpsrv/testutils/test_config_backend_dhcp4.cc
src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc
src/lib/process/tests/cb_ctl_base_unittests.cc

index 3f7c0b0b8c3226880c699feb094428167004a9e3..69dfe47c596712f147d89b999a98c24e80fc92fc 100644 (file)
@@ -143,10 +143,10 @@ public:
                                         const std::string& name) {
         StampedValueCollection parameters;
 
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createString(name)
             };
 
@@ -529,10 +529,10 @@ public:
                           const SubnetID& subnet_id) {
         Subnet4Collection subnets;
 
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createInteger<uint32_t>(subnet_id)
             };
 
@@ -555,10 +555,10 @@ public:
                           const std::string& subnet_prefix) {
         Subnet4Collection subnets;
 
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createString(subnet_prefix)
             };
 
@@ -575,11 +575,11 @@ public:
     /// subnets should be inserted.
     void getAllSubnets4(const ServerSelector& server_selector,
                         Subnet4Collection& subnets) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag)
+                MySqlBinding::createString(tag.get())
             };
 
             getSubnets4(GET_ALL_SUBNETS4, in_bindings, subnets);
@@ -595,11 +595,11 @@ public:
     void getModifiedSubnets4(const ServerSelector& server_selector,
                              const boost::posix_time::ptime& modification_ts,
                              Subnet4Collection& subnets) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createTimestamp(modification_ts)
             };
 
@@ -617,11 +617,11 @@ public:
     void getSharedNetworkSubnets4(const ServerSelector& server_selector,
                                   const std::string& shared_network_name,
                                   Subnet4Collection& subnets) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createString(shared_network_name)
             };
 
@@ -1252,11 +1252,11 @@ public:
     /// structure where shared networks should be inserted.
     void getAllSharedNetworks4(const ServerSelector& server_selector,
                                SharedNetwork4Collection& shared_networks) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag)
+                MySqlBinding::createString(tag.get())
             };
 
             getSharedNetworks4(GET_ALL_SHARED_NETWORKS4, in_bindings, shared_networks);
@@ -1272,11 +1272,11 @@ public:
     void getModifiedSharedNetworks4(const ServerSelector& server_selector,
                                     const boost::posix_time::ptime& modification_ts,
                                     SharedNetwork4Collection& shared_networks) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createTimestamp(modification_ts)
             };
 
@@ -1407,7 +1407,7 @@ public:
         // a server into the dhcp4_options_server table.
         MySqlBindingCollection in_server_bindings = {
             MySqlBinding::createInteger<uint64_t>(id), // option_id
-            MySqlBinding::createString(*getServerTags(server_selector).begin()), // server_tag
+            MySqlBinding::createString(server_selector.getTags().begin()->get()), // server_tag
             in_bindings[11] // copy modification timestamp from option
         };
 
@@ -2609,9 +2609,9 @@ StampedValueCollection
 MySqlConfigBackendDHCPv4::getAllGlobalParameters4(const ServerSelector& server_selector) const {
     LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_GET_ALL_GLOBAL_PARAMETERS4);
     StampedValueCollection parameters;
-    auto tags = impl_->getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
-        MySqlBindingCollection in_bindings = { MySqlBinding::createString(tag) };
+        MySqlBindingCollection in_bindings = { MySqlBinding::createString(tag.get()) };
         impl_->getGlobalParameters(MySqlConfigBackendDHCPv4Impl::GET_ALL_GLOBAL_PARAMETERS4,
                                    in_bindings, parameters);
     }
@@ -2626,10 +2626,10 @@ MySqlConfigBackendDHCPv4::getModifiedGlobalParameters4(const db::ServerSelector&
     LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_GET_MODIFIED_GLOBAL_PARAMETERS4)
         .arg(util::ptimeToText(modification_time));
     StampedValueCollection parameters;
-    auto tags = impl_->getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag),
+            MySqlBinding::createString(tag.get()),
             MySqlBinding::createTimestamp(modification_time)
         };
         impl_->getGlobalParameters(MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_GLOBAL_PARAMETERS4,
index 8f3e0166606f026e3807748666307513c3161368..aeb1fdbce88bc4c31611c65a20a5abdd2c752915 100644 (file)
@@ -150,10 +150,10 @@ public:
                                         const std::string& name) {
         StampedValueCollection parameters;
 
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createString(name)
             };
 
@@ -585,10 +585,10 @@ public:
                           const SubnetID& subnet_id) {
         Subnet6Collection subnets;
 
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createInteger<uint32_t>(subnet_id)
             };
 
@@ -611,10 +611,10 @@ public:
                           const std::string& subnet_prefix) {
         Subnet6Collection subnets;
 
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createString(subnet_prefix)
             };
 
@@ -631,11 +631,11 @@ public:
     /// subnets should be inserted.
     void getAllSubnets6(const ServerSelector& server_selector,
                         Subnet6Collection& subnets) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag)
+                MySqlBinding::createString(tag.get())
             };
 
             getSubnets6(GET_ALL_SUBNETS6, in_bindings, subnets);
@@ -651,11 +651,11 @@ public:
     void getModifiedSubnets6(const ServerSelector& server_selector,
                              const boost::posix_time::ptime& modification_ts,
                              Subnet6Collection& subnets) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createTimestamp(modification_ts)
             };
 
@@ -673,11 +673,11 @@ public:
     void getSharedNetworkSubnets6(const ServerSelector& server_selector,
                                   const std::string& shared_network_name,
                                   Subnet6Collection& subnets) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createString(shared_network_name)
             };
 
@@ -1452,11 +1452,11 @@ public:
     /// structure where shared networks should be inserted.
     void getAllSharedNetworks6(const ServerSelector& server_selector,
                                SharedNetwork6Collection& shared_networks) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag)
+                MySqlBinding::createString(tag.get())
             };
 
             getSharedNetworks6(GET_ALL_SHARED_NETWORKS6, in_bindings, shared_networks);
@@ -1472,11 +1472,11 @@ public:
     void getModifiedSharedNetworks6(const ServerSelector& server_selector,
                                     const boost::posix_time::ptime& modification_ts,
                                     SharedNetwork6Collection& shared_networks) {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
 
         for (auto tag : tags) {
             MySqlBindingCollection in_bindings = {
-                MySqlBinding::createString(tag),
+                MySqlBinding::createString(tag.get()),
                 MySqlBinding::createTimestamp(modification_ts)
             };
 
@@ -1618,7 +1618,7 @@ public:
         // a server into the dhcp6_options_server table.
         MySqlBindingCollection in_server_bindings = {
             MySqlBinding::createInteger<uint64_t>(id), // option_id
-            MySqlBinding::createString(*getServerTags(server_selector).begin()), // server_tag
+            MySqlBinding::createString(server_selector.getTags().begin()->get()), // server_tag
             in_bindings[11] // copy modification timestamp from option
         };
 
@@ -2971,9 +2971,9 @@ StampedValueCollection
 MySqlConfigBackendDHCPv6::getAllGlobalParameters6(const ServerSelector& server_selector) const {
     LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_GET_ALL_GLOBAL_PARAMETERS6);
     StampedValueCollection parameters;
-    auto tags = impl_->getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
-        MySqlBindingCollection in_bindings = { MySqlBinding::createString(tag) };
+        MySqlBindingCollection in_bindings = { MySqlBinding::createString(tag.get()) };
         impl_->getGlobalParameters(MySqlConfigBackendDHCPv6Impl::GET_ALL_GLOBAL_PARAMETERS6,
                                    in_bindings, parameters);
     }
@@ -2988,10 +2988,10 @@ MySqlConfigBackendDHCPv6::getModifiedGlobalParameters6(const db::ServerSelector&
     LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_GET_MODIFIED_GLOBAL_PARAMETERS6)
         .arg(util::ptimeToText(modification_time));
     StampedValueCollection parameters;
-    auto tags = impl_->getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag),
+            MySqlBinding::createString(tag.get()),
             MySqlBinding::createTimestamp(modification_time)
         };
         impl_->getGlobalParameters(MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_GLOBAL_PARAMETERS6,
index 0a78d31eab8d4b4712cb1f93ba183b8d1de77850..dd6a4421f14d2c53efaa2ccef142ee66c43e15f0 100644 (file)
@@ -193,13 +193,13 @@ MySqlConfigBackendImpl::getRecentAuditEntries(const int index,
         MySqlBinding::createString(AUDIT_ENTRY_LOG_MESSAGE_BUF_LENGTH) // log_message
     };
 
-    auto tags = getServerTags(server_selector);
+    auto tags = server_selector.getTags();
 
     for (auto tag : tags) {
 
         // There is only one input binding, modification time.
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag),
+            MySqlBinding::createString(tag.get()),
             MySqlBinding::createTimestamp(modification_time)
         };
 
@@ -341,10 +341,10 @@ void
 MySqlConfigBackendImpl::getAllOptionDefs(const int index,
                      const ServerSelector& server_selector,
                      OptionDefContainer& option_defs) {
-    auto tags = getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag)
+            MySqlBinding::createString(tag.get())
         };
         getOptionDefs(index, in_bindings, option_defs);
     }
@@ -355,10 +355,10 @@ MySqlConfigBackendImpl::getModifiedOptionDefs(const int index,
                                               const ServerSelector& server_selector,
                                               const boost::posix_time::ptime& modification_time,
                                               OptionDefContainer& option_defs) {
-    auto tags = getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag),
+            MySqlBinding::createString(tag.get()),
             MySqlBinding::createTimestamp(modification_time)
         };
         getOptionDefs(index, in_bindings, option_defs);
@@ -587,10 +587,10 @@ MySqlConfigBackendImpl::getAllOptions(const int index,
                                       const ServerSelector& server_selector) {
     OptionContainer options;
 
-    auto tags = getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag)
+            MySqlBinding::createString(tag.get())
         };
         getOptions(index, in_bindings, universe, options);
     }
@@ -605,10 +605,10 @@ MySqlConfigBackendImpl::getModifiedOptions(const int index,
                                            const boost::posix_time::ptime& modification_time) {
     OptionContainer options;
 
-    auto tags = getServerTags(server_selector);
+    auto tags = server_selector.getTags();
     for (auto tag : tags) {
         MySqlBindingCollection in_bindings = {
-            MySqlBinding::createString(tag),
+            MySqlBinding::createString(tag.get()),
             MySqlBinding::createTimestamp(modification_time)
         };
         getOptions(index, in_bindings, universe, options);
index 456ee26d4d0117e3f4f9703bf9a6bd751e22983a..f37d9de10486d278e1f2ba33a76e531d7163ef04 100644 (file)
@@ -164,25 +164,6 @@ public:
                                            const db::MySqlBindingPtr& min_binding,
                                            const db::MySqlBindingPtr& max_binding);
 
-    /// @brief Returns server tags associated with the particular selector.
-    ///
-    /// @param server_selector Server selector.
-    /// @return Set of server tags.
-    std::set<std::string> getServerTags(const db::ServerSelector& server_selector) const {
-        std::set<std::string> tags;
-        switch (server_selector.getType()) {
-        case db::ServerSelector::Type::ALL:
-            tags.insert("all");
-            return (tags);
-
-        default:
-            return (server_selector.getTags());
-        }
-
-        // Unassigned server case.
-        return (tags);
-    }
-
     /// @brief Returns server tag associated with the particular selector.
     ///
     /// This method expects that there is exactly one server tag associated with
@@ -196,14 +177,14 @@ public:
     /// is more than one server tag associated with the selector.
     std::string getServerTag(const db::ServerSelector& server_selector,
                              const std::string& operation) const {
-        auto tags = getServerTags(server_selector);
+        auto tags = server_selector.getTags();
         if (tags.size() != 1) {
             isc_throw(InvalidOperation, "expected exactly one server tag to be specified"
                       " while " << operation << ". Got: "
                       << getServerTagsAsText(server_selector));
         }
 
-        return (*tags.begin());
+        return (tags.begin()->get());
     }
 
     /// @brief Returns server tags associated with the particular selector
@@ -212,12 +193,12 @@ public:
     /// This method is useful for logging purposes.
     std::string getServerTagsAsText(const db::ServerSelector& server_selector) const {
         std::ostringstream s;
-        auto server_tags = getServerTags(server_selector);
+        auto server_tags = server_selector.getTags();
         for (auto tag : server_tags) {
             if (s.tellp() != 0) {
                 s << ", ";
             }
-            s << tag;
+            s << tag.get();
         }
 
         return (s.str());
index e0f0dc883e02d465407d97430657a68374139d21..8dca6fe89045a336f3c65489f0093cf0cfd35c4e 100644 (file)
@@ -392,7 +392,7 @@ public:
 
             } else if (tags.size() == 1) {
                 // Get the server tag for which we run the current test.
-                tag = *tags.begin();
+                tag = tags.begin()->get();
             }
         }
 
index b07a5a6d063ac88980520d6a08b5fe973d7547ab..b788ae89904a2199fa7b4f7e53275af59950fb15 100644 (file)
@@ -432,7 +432,7 @@ public:
 
             } else if (tags.size() == 1) {
                 // Get the server tag for which we run the current test.
-                tag = *tags.begin();
+                tag = tags.begin()->get();
             }
         }
 
index e99d75bef43df17f2e06f8fc12d9f733e1acadc8..56b20aa31d42cb01e87a405dbdab097dcd38904b 100644 (file)
@@ -35,5 +35,11 @@ ServerTag::amAll() const {
     return (tag_ == ALL);
 }
 
+std::ostream&
+operator<<(std::ostream& os, const ServerTag& server_tag) {
+    os << server_tag.get();
+    return (os);
+}
+
 } // end of namespace isc::data
 } // end of namespace isc
index c85fc1bd5c0d7e69ddfc6f9b2866dd6abb87f50d..abfa75036c705e6a62d934e29bdad15b968dfaa9 100644 (file)
@@ -50,12 +50,30 @@ public:
         return (tag_);
     }
 
+    /// @brief Overload of the less operator for using @c ServerTag in sets.
+    ///
+    /// @param other other server tag to compare to.
+    /// @return true if this server tag is less than the other server tag.
+    bool operator<(const ServerTag& other) const {
+        return (tag_ < other.tag_);
+    }
+
 private:
 
     /// @brief Holds server tag as string.
     std::string tag_;
 };
 
+/// @brief Insert the @c ServerTag as a string into stream.
+///
+/// @param os stream to insert server tag into.
+/// @param server_tag server tag to be converted to text and
+/// inserted into a stream.
+/// @return Reference to the stream object with inserted server
+/// tag.
+std::ostream&
+operator<<(std::ostream& os, const ServerTag& server_tag);
+
 } // end of namespace isc::data
 } // end of namespace isc
 
index b5c2b595bb5ca250e494dca5a39f355e68f057d2..20a7eda516d2eb1df763cebbfdf674ffeeac1953 100644 (file)
@@ -20,7 +20,7 @@ libkea_database_la_SOURCES += db_log.cc db_log.h
 libkea_database_la_SOURCES += db_messages.cc db_messages.h
 libkea_database_la_SOURCES += server.cc server.h
 libkea_database_la_SOURCES += server_collection.cc server_collection.h
-libkea_database_la_SOURCES += server_selector.h
+libkea_database_la_SOURCES += server_selector.cc server_selector.h
 
 libkea_database_la_LIBADD  = $(top_builddir)/src/lib/cc/libkea-cc.la
 libkea_database_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
diff --git a/src/lib/database/server_selector.cc b/src/lib/database/server_selector.cc
new file mode 100644 (file)
index 0000000..0659e43
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <database/server_selector.h>
+#include <exceptions/exceptions.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace db {
+
+ServerSelector
+ServerSelector::MULTIPLE(const std::set<std::string>& server_tags) {
+    if (server_tags.empty()) {
+        isc_throw(InvalidOperation, "ServerSelector: expecting at least one"
+                  " server tag");
+    }
+
+    std::set<ServerTag> tags;
+
+    // Create a set of tags from strings.
+    for (auto tag : server_tags) {
+        tags.insert(ServerTag(tag));
+    }
+
+    ServerSelector selector(tags);
+    return (selector);
+}
+
+ServerSelector::ServerSelector(const Type& type)
+    : type_(type), tags_() {
+    if (type_ == Type::ALL) {
+        tags_.insert(ServerTag());
+    }
+}
+
+ServerSelector::ServerSelector(const ServerTag& server_tag)
+    : type_(server_tag.amAll() ? Type::ALL : Type::SUBSET), tags_({server_tag}) {
+}
+
+ServerSelector::ServerSelector(const std::set<ServerTag>& server_tags)
+    : type_(Type::SUBSET), tags_(server_tags) {
+}
+
+} // end of namespace isc::db
+} // end of namespace isc
index 909044ca7aade6e468a8db9aece4d9bd80217dec..3290b07a8122fe48b946da8f09e2bec680aca10d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -7,6 +7,7 @@
 #ifndef SERVER_SELECTOR_H
 #define SERVER_SELECTOR_H
 
+#include <cc/server_tag.h>
 #include <set>
 #include <string>
 
@@ -68,17 +69,15 @@ public:
     ///
     /// @param server_tag tag of the single server to be selected.
     static ServerSelector ONE(const std::string& server_tag) {
-        ServerSelector selector(server_tag);
+        ServerSelector selector((data::ServerTag(server_tag)));
         return (selector);
     }
 
     /// @brief Factory returning "multiple servers" selector.
     ///
     /// @param server_tags set of server tags to be selected.
-    static ServerSelector MULTIPLE(const std::set<std::string>& server_tags) {
-        ServerSelector selector(server_tags);
-        return (selector);
-    }
+    /// @throw InvalidOperation if no server tags provided.
+    static ServerSelector MULTIPLE(const std::set<std::string>& server_tags);
 
     /// @brief Returns type of the selector.
     Type getType() const {
@@ -89,7 +88,7 @@ public:
     ///
     /// @return server tags for mutliple selections and for one server,
     /// empty set for all servers and and unassigned.
-    std::set<std::string> getTags() const {
+    std::set<data::ServerTag> getTags() const {
         return (tags_);
     }
 
@@ -100,35 +99,35 @@ public:
         return (getType() == Type::UNASSIGNED);
     }
 
+    /// @brief Convenience method checking if the server selector has multiple tags.
+    ///
+    /// @return true if it has multiple tags, false otherwise.
+    bool hasMultipleTags() const {
+        return (tags_.size() > 1);
+    }
+
 private:
 
     /// @brief Constructor used for "unassigned" and "all" slection types.
     ///
     /// @param type selector type.
-    explicit ServerSelector(const Type& type)
-        : type_(type), tags_() {
-    }
+    explicit ServerSelector(const Type& type);
 
     /// @brief Constructor used for selecting a single server.
     ///
     /// @param server_tag tag of the server to be selected.
-    explicit ServerSelector(const std::string& server_tag)
-        : type_(Type::SUBSET), tags_() {
-        tags_.insert(server_tag);
-    }
+    explicit ServerSelector(const data::ServerTag& server_tag);
 
     /// @brief Constructor used for selecting multiple servers.
     ///
     /// @param server_tags set of server tags.
-    explicit ServerSelector(const std::set<std::string>& server_tags)
-        : type_(Type::SUBSET), tags_(server_tags) {
-    }
+    explicit ServerSelector(const std::set<data::ServerTag>& server_tags);
 
     /// @brief Selection type used.
     Type type_;
 
     /// @brief Holds tags of explicitly selected servers.
-    std::set<std::string> tags_;
+    std::set<data::ServerTag> tags_;
 };
 
 
index 28ee65925bd0c74e7654521136493b8c194566fd..2eaed14bb10f87735c998bb8de8d63e0666357bf 100644 (file)
@@ -1,13 +1,15 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include <config.h>
+#include <cc/server_tag.h>
 #include <database/server_selector.h>
 #include <gtest/gtest.h>
 
+using namespace isc::data;
 using namespace isc::db;
 
 namespace {
@@ -18,6 +20,7 @@ TEST(ServerSelectorTest, unassigned) {
     EXPECT_EQ(ServerSelector::Type::UNASSIGNED, selector.getType());
     EXPECT_TRUE(selector.amUnassigned());
     EXPECT_TRUE(selector.getTags().empty());
+    EXPECT_FALSE(selector.hasMultipleTags());
 }
 
 // Check that server selector can be set to ALL.
@@ -25,7 +28,11 @@ TEST(ServerSelectorTest, all) {
     ServerSelector selector = ServerSelector::ALL();
     EXPECT_EQ(ServerSelector::Type::ALL, selector.getType());
     EXPECT_FALSE(selector.amUnassigned());
-    EXPECT_TRUE(selector.getTags().empty());
+
+    auto tags = selector.getTags();
+    EXPECT_EQ(1, tags.size());
+    EXPECT_EQ(1, tags.count(ServerTag("all")));
+    EXPECT_FALSE(selector.hasMultipleTags());
 }
 
 // Check that a single server can be selected.
@@ -34,9 +41,10 @@ TEST(ServerSelectorTest, one) {
     EXPECT_EQ(ServerSelector::Type::SUBSET, selector.getType());
     EXPECT_FALSE(selector.amUnassigned());
 
-    std::set<std::string> tags = selector.getTags();
+    auto tags = selector.getTags();
     ASSERT_EQ(1, tags.size());
-    EXPECT_EQ(1, tags.count("some-tag"));
+    EXPECT_EQ(1, tags.count(ServerTag("some-tag")));
+    EXPECT_FALSE(selector.hasMultipleTags());
 }
 
 // Check that multiple servers can be selected.
@@ -45,11 +53,12 @@ TEST(ServerSelectorTest, multiple) {
     EXPECT_EQ(ServerSelector::Type::SUBSET, selector.getType());
     EXPECT_FALSE(selector.amUnassigned());
 
-    std::set<std::string> tags = selector.getTags();
+    auto tags = selector.getTags();
     ASSERT_EQ(3, tags.size());
-    EXPECT_EQ(1, tags.count("tag1"));
-    EXPECT_EQ(1, tags.count("tag2"));
-    EXPECT_EQ(1, tags.count("tag3"));
+    EXPECT_EQ(1, tags.count(ServerTag("tag1")));
+    EXPECT_EQ(1, tags.count(ServerTag("tag2")));
+    EXPECT_EQ(1, tags.count(ServerTag("tag3")));
+    EXPECT_TRUE(selector.hasMultipleTags());
 }
 
 }
index acb7515ecc528df14299cbf4c3e41384145bfe94..8cffe006aeec55ba0e2cfd49ba0d17b89e100afe 100644 (file)
@@ -79,9 +79,9 @@ public:
             return ("all");
         }
         // Return first tag found.
-        std::set<std::string> tags = server_selector.getTags();
+        auto tags = server_selector.getTags();
         if (!tags.empty()) {
-            return (*tags.begin());
+            return (tags.begin()->get());
         }
         return ("");
     }
index b6e2a262659dd596a1389acfe4f57a082a9ab175..d6eb91dac10e051bbf21ca2d0a005128086cc8f4 100644 (file)
@@ -186,11 +186,26 @@ TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& /* server
 }
 
 StampedValuePtr
-TestConfigBackendDHCPv4::getGlobalParameter4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::getGlobalParameter4(const db::ServerSelector& server_selector,
                                              const std::string& name) const {
     const auto& index = globals_.get<StampedValueNameIndexTag>();
-    auto global_it = index.find(name);
-    return ((global_it != index.cend()) ? (*global_it) : StampedValuePtr());
+    auto global_range = index.equal_range(name);
+    for (auto global_it = global_range.first; global_it != global_range.second;
+         ++global_it) {
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            if ((*global_it)->hasServerTag(ServerTag(tag))) {
+                return (*global_it);
+            }
+        }
+    }
+
+    auto global_all_it = index.find(name);
+    if ((global_all_it != index.end()) && ((*global_all_it)->hasAllServerTag())) {
+        return (*global_all_it);
+    }
+
+    return (StampedValuePtr());
 }
 
 
@@ -354,14 +369,18 @@ TestConfigBackendDHCPv4::createUpdateGlobalParameter4(const db::ServerSelector&
     value->setServerTag(getServerTag(server_selector));
 
     auto& index = globals_.get<StampedValueNameIndexTag>();
-    auto global_it = index.find(value->getName());
-
-    if (global_it != index.end()) {
-        index.replace(global_it, value);
+    auto global_it_pair = index.equal_range(value->getName());
 
-    } else {
-        index.insert(value);
+    for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
+         ++global_it) {
+        auto existing_value = *global_it;
+        if (existing_value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+            index.replace(global_it, value);
+            return;
+        }
     }
+
+    index.insert(value);
 }
 
 void
@@ -536,10 +555,20 @@ TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& /* server_selec
 }
 
 uint64_t
-TestConfigBackendDHCPv4::deleteGlobalParameter4(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv4::deleteGlobalParameter4(const db::ServerSelector& server_selector,
                                                 const std::string& name) {
     auto& index = globals_.get<StampedValueNameIndexTag>();
-    return (index.erase(name));
+    auto global_it_pair = index.equal_range(name);
+
+    for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
+         ++global_it) {
+        auto value = *global_it;
+        if (value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+            index.erase(global_it);
+            return (1);
+        }
+    }
+    return (0);
 }
 
 uint64_t
index b9aa88b21e8915f9ce4428a686857654a2b4c73a..5d6489875558d3c05b58d3a7c0564fb0237d9f19 100644 (file)
@@ -185,11 +185,26 @@ TestConfigBackendDHCPv6::getModifiedOptions6(const db::ServerSelector& /* server
 }
 
 StampedValuePtr
-TestConfigBackendDHCPv6::getGlobalParameter6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::getGlobalParameter6(const db::ServerSelector& server_selector,
                                              const std::string& name) const {
     const auto& index = globals_.get<StampedValueNameIndexTag>();
-    auto global_it = index.find(name);
-    return ((global_it != index.cend()) ? (*global_it) : StampedValuePtr());
+    auto global_range = index.equal_range(name);
+    for (auto global_it = global_range.first; global_it != global_range.second;
+         ++global_it) {
+        auto tags = server_selector.getTags();
+        for (auto tag : tags) {
+            if ((*global_it)->hasServerTag(ServerTag(tag))) {
+                return (*global_it);
+            }
+        }
+    }
+
+    auto global_all_it = index.find(name);
+    if ((global_all_it != index.end()) && ((*global_all_it)->hasAllServerTag())) {
+        return (*global_all_it);
+    }
+
+    return (StampedValuePtr());
 }
 
 
@@ -373,14 +388,18 @@ TestConfigBackendDHCPv6::createUpdateGlobalParameter6(const db::ServerSelector&
     value->setServerTag(getServerTag(server_selector));
 
     auto& index = globals_.get<StampedValueNameIndexTag>();
-    auto global_it = index.find(value->getName());
-
-    if (global_it != index.end()) {
-        index.replace(global_it, value);
+    auto global_it_pair = index.equal_range(value->getName());
 
-    } else {
-        index.insert(value);
+    for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
+         ++global_it) {
+        auto existing_value = *global_it;
+        if (existing_value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+            index.replace(global_it, value);
+            return;
+        }
     }
+
+    index.insert(value);
 }
 
 void
@@ -573,10 +592,20 @@ TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& /* server_selec
 }
 
 uint64_t
-TestConfigBackendDHCPv6::deleteGlobalParameter6(const db::ServerSelector& /* server_selector */,
+TestConfigBackendDHCPv6::deleteGlobalParameter6(const db::ServerSelector& server_selector,
                                                 const std::string& name) {
     auto& index = globals_.get<StampedValueNameIndexTag>();
-    return (index.erase(name));
+    auto global_it_pair = index.equal_range(name);
+
+    for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
+         ++global_it) {
+        auto value = *global_it;
+        if (value->hasServerTag(ServerTag(getServerTag(server_selector)))) {
+            index.erase(global_it);
+            return (1);
+        }
+    }
+    return (0);
 }
 
 uint64_t
index d1eabf7404df57aea84ff882e0a03193487eb9c4..eb27040e55edceb9ee194e206705eb37de9407a7 100644 (file)
@@ -524,7 +524,7 @@ TEST_F(CBControlBaseTest, fetchFromServer) {
     // correct.
     auto tags = cb_ctl_.getServerSelector().getTags();
     ASSERT_EQ(1, tags.size());
-    EXPECT_EQ("a-tag", *tags.begin());
+    EXPECT_EQ("a-tag", tags.begin()->get());
 }
 
 // This test verifies that incremental configuration changes can be