]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#641,!352] Implemented db::Server class and data::ServerTag.
authorMarcin Siodelski <marcin@isc.org>
Mon, 3 Jun 2019 11:22:47 +0000 (13:22 +0200)
committerMarcin Siodelski <marcin@isc.org>
Mon, 10 Jun 2019 12:39:17 +0000 (08:39 -0400)
13 files changed:
src/lib/cc/Makefile.am
src/lib/cc/server_tag.cc [new file with mode: 0644]
src/lib/cc/server_tag.h [new file with mode: 0644]
src/lib/cc/stamped_element.cc
src/lib/cc/stamped_element.h
src/lib/cc/tests/Makefile.am
src/lib/cc/tests/server_tag_unittest.cc [new file with mode: 0644]
src/lib/cc/tests/stamped_element_unittest.cc
src/lib/database/Makefile.am
src/lib/database/server.cc [new file with mode: 0644]
src/lib/database/server.h [new file with mode: 0644]
src/lib/database/tests/Makefile.am
src/lib/database/tests/server_unittest.cc [new file with mode: 0644]

index 5fb66266061058559486fb29725ea629213e419e..9a747fc6512414c4f4a933ed706f738e8d2ec280 100644 (file)
@@ -10,6 +10,7 @@ libkea_cc_la_SOURCES += element_value.h
 libkea_cc_la_SOURCES += cfg_to_element.h dhcp_config_error.h
 libkea_cc_la_SOURCES += command_interpreter.cc command_interpreter.h
 libkea_cc_la_SOURCES += json_feed.cc json_feed.h
+libkea_cc_la_SOURCES += server_tag.cc server_tag.h
 libkea_cc_la_SOURCES += simple_parser.cc simple_parser.h
 libkea_cc_la_SOURCES += stamped_element.cc stamped_element.h
 libkea_cc_la_SOURCES += stamped_value.cc stamped_value.h
@@ -31,6 +32,7 @@ libkea_cc_include_HEADERS = \
        dhcp_config_error.h \
        element_value.h \
        json_feed.h \
+       server_tag.h \
        simple_parser.h \
        stamped_element.h \
        stamped_value.h \
diff --git a/src/lib/cc/server_tag.cc b/src/lib/cc/server_tag.cc
new file mode 100644 (file)
index 0000000..931d256
--- /dev/null
@@ -0,0 +1,36 @@
+// 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 <cc/server_tag.h>
+#include <exceptions/exceptions.h>
+#include <util/strutil.h>
+
+namespace isc {
+namespace data {
+
+std::string ServerTag::ALL = "all";
+
+ServerTag::ServerTag()
+    : tag_(ALL) {
+}
+
+ServerTag::ServerTag(const std::string& tag)
+    : tag_(util::str::trim(tag)) {
+    if (tag_.empty()) {
+        isc_throw(BadValue, "server-tag must not be empty");
+
+    } else if (tag_.length() > 256) {
+        isc_throw(BadValue, "server-tag must not be longer than 256 characters");
+    }
+}
+
+bool
+ServerTag::amAll() const {
+    return (tag_ == ALL);
+}
+
+} // end of namespace isc::data
+} // end of namespace isc
diff --git a/src/lib/cc/server_tag.h b/src/lib/cc/server_tag.h
new file mode 100644 (file)
index 0000000..95502ae
--- /dev/null
@@ -0,0 +1,58 @@
+// 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/.
+
+#ifndef SERVER_TAG_H
+#define SERVER_TAG_H
+
+#include <string>
+
+namespace isc {
+namespace data {
+
+/// @brief Represents a server tag.
+///
+/// The server tag is a label identifying a server or all servers which
+/// configuration is stored in the database. The label "all" is reserved
+/// and it means "all servers". A configuration object in the database
+/// associated with this server tag belongs to all servers. The server
+/// tag must not be empty and must not be longer than 256 characters
+/// (excluding leading and terminating whitespaces, which are trimmed).
+class ServerTag {
+public:
+
+    /// @brief Server tag for all servers as text.
+    static std::string ALL;
+
+    /// @brief Default constructor.
+    ///
+    /// Creates server tag for all servers.
+    ServerTag();
+
+    /// @brief Constructor.
+    ///
+    /// @param tag server tag provided as string.
+    explicit ServerTag(const std::string& tag);
+
+    /// @brief Checks if the server tag is set to "all servers".
+    ///
+    /// @return true if the server tag is set to all servers, false
+    /// otherwise.
+    bool amAll() const;
+    /// @brief Returns server tag as string.
+    std::string get() const {
+        return (tag_);
+    }
+
+private:
+
+    /// @brief Holds server tag as string.
+    std::string tag_;
+};
+
+} // end of namespace isc::data
+} // end of namespace isc
+
+#endif // SERVER_TAG_H
index 01bd7e172baa9da86deecf423b6f4ac8d53b4f25..49a586f70e9fb84dde2499fae16f3121e00b0aec 100644 (file)
@@ -23,6 +23,16 @@ StampedElement::updateModificationTime() {
     setModificationTime(boost::posix_time::second_clock::local_time());
 }
 
+std::string
+StampedElement:: getServerTag() const {
+    return (server_tag_.get());
+}
+
+bool
+StampedElement::allServers() const {
+    return (server_tag_.amAll());
+}
+
 ElementPtr
 StampedElement::getMetadata() const {
     ElementPtr metadata = Element::createMap();
index ae67026cffccfc649b4ce812bb944c9cf0d026ca..1f877b51ce6d2dd3de23527e6f350d33a2f7af4e 100644 (file)
@@ -8,7 +8,9 @@
 #define STAMPED_ELEMENT_H
 
 #include <cc/data.h>
+#include <cc/server_tag.h>
 #include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/scoped_ptr.hpp>
 #include <cstdint>
 #include <string>
 
@@ -69,15 +71,22 @@ public:
 
     /// @brief Sets new server tag.
     ///
-    /// @param server_tag
+    /// @param server_tag new server tag.
+    /// @throw BadValue if the server tag length exceeds 256 characters.
     void setServerTag(const std::string& server_tag) {
-        server_tag_ = server_tag;
+        server_tag_ = ServerTag(server_tag);
     }
 
     /// @brief Returns server tag.
-    std::string getServerTag() const {
-        return (server_tag_);
-    }
+    ///
+    /// @return Server tag as string.
+    std::string getServerTag() const;
+
+    /// @brief Checks if the stamped element is for all servers.
+    ///
+    /// @return true if the stamped element is associated with all servers,
+    /// false otherwise.
+    bool allServers() const;
 
     /// @brief Returns an object representing metadata to be returned
     /// with objects from the configuration backend.
@@ -97,7 +106,7 @@ private:
     boost::posix_time::ptime timestamp_;
 
     /// @brief Holds server tag.
-    std::string server_tag_;
+    ServerTag server_tag_;
 };
 
 } // end of namespace isc::data
index 31a5d5e25d956ff7a97c905e271164a3f4758cc7..b02a87b4011d83cf10ef269169bdc247a68d1dd1 100644 (file)
@@ -19,6 +19,7 @@ run_unittests_SOURCES += data_unittests.cc
 run_unittests_SOURCES += data_file_unittests.cc
 run_unittests_SOURCES += element_value_unittests.cc
 run_unittests_SOURCES += json_feed_unittests.cc
+run_unittests_SOURCES += server_tag_unittest.cc
 run_unittests_SOURCES += simple_parser_unittest.cc
 run_unittests_SOURCES += stamped_element_unittest.cc
 run_unittests_SOURCES += stamped_value_unittest.cc
diff --git a/src/lib/cc/tests/server_tag_unittest.cc b/src/lib/cc/tests/server_tag_unittest.cc
new file mode 100644 (file)
index 0000000..95cfd4f
--- /dev/null
@@ -0,0 +1,85 @@
+// 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 <config.h>
+#include <cc/server_tag.h>
+#include <exceptions/exceptions.h>
+#include <boost/scoped_ptr.hpp>
+#include <gtest/gtest.h>
+#include <string>
+
+using namespace isc;
+using namespace isc::data;
+
+namespace {
+
+// This test verifies that the constructors of the ServerTag class
+// work properly.
+TEST(ServerTagTest, constructors) {
+    boost::scoped_ptr<ServerTag> tag;
+
+    {
+        SCOPED_TRACE("default constructor for all servers");
+        ASSERT_NO_THROW(tag.reset(new ServerTag()));
+        EXPECT_EQ(ServerTag::ALL, tag->get());
+        EXPECT_TRUE(tag->amAll());
+    }
+
+    {
+        SCOPED_TRACE("all servers");
+        ASSERT_NO_THROW(tag.reset(new ServerTag(ServerTag::ALL)));
+        EXPECT_EQ(ServerTag::ALL, tag->get());
+        EXPECT_TRUE(tag->amAll());
+    }
+
+    {
+        SCOPED_TRACE("no whitespace");
+        ASSERT_NO_THROW(tag.reset(new ServerTag("xyz")));
+        EXPECT_EQ("xyz", tag->get());
+        EXPECT_FALSE(tag->amAll());
+    }
+
+    {
+        SCOPED_TRACE("leading whitespace");
+        ASSERT_NO_THROW(tag.reset(new ServerTag("  left")));
+        EXPECT_EQ("left", tag->get());
+        EXPECT_FALSE(tag->amAll());
+    }
+
+    {
+        SCOPED_TRACE("terminating whitespace");
+        ASSERT_NO_THROW(tag.reset(new ServerTag("right  ")));
+        EXPECT_EQ("right", tag->get());
+        EXPECT_FALSE(tag->amAll());
+    }
+
+    {
+        SCOPED_TRACE("leading and terminating whitespace");
+        ASSERT_NO_THROW(tag.reset(new ServerTag("  both left-right  ")));
+        EXPECT_EQ("both left-right", tag->get());
+        EXPECT_FALSE(tag->amAll());
+    }
+}
+
+// This test verifies that malformed server tags are rejected.
+TEST(ServerTagTest, malformed) {
+    {
+        SCOPED_TRACE("empty tag");
+        EXPECT_THROW(ServerTag(""), BadValue);
+    }
+
+    {
+        SCOPED_TRACE("only whitespaces");
+        EXPECT_THROW(ServerTag("   "), BadValue);
+    }
+
+    {
+        SCOPED_TRACE("too long tag, max is 256");
+        EXPECT_THROW(ServerTag(std::string(257, 'c')), BadValue);
+    }
+}
+
+}
index c67fded8045f7081e3951394e5494b494d22d43b..22121c7366193e2de69f8bca7444942b0e4c14cb 100644 (file)
@@ -23,8 +23,8 @@ TEST(StampedElementTest, create) {
     // Default identifier is 0.
     EXPECT_EQ(0, element.getId());
 
-    // Default server tag is empty.
-    EXPECT_TRUE(element.getServerTag().empty());
+    // Default server tag is 'all'.
+    EXPECT_EQ(ServerTag::ALL, element.getServerTag());
 
     // Checking that the delta between now and the timestamp is within
     // 5s range should be sufficient.
index e716c418ced13c3975c336e3c029bf6196877b20..519c4e6482e9386dad74c07e5b416aa6c0685ada 100644 (file)
@@ -18,6 +18,7 @@ libkea_database_la_SOURCES += dbaccess_parser.h dbaccess_parser.cc
 libkea_database_la_SOURCES += db_exceptions.h
 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_selector.h
 
 libkea_database_la_LIBADD  = $(top_builddir)/src/lib/cc/libkea-cc.la
@@ -73,4 +74,5 @@ libkea_database_include_HEADERS = \
        db_exceptions.h \
        db_log.h \
        db_messages.h \
+       server.h \
        server_selector.h
diff --git a/src/lib/database/server.cc b/src/lib/database/server.cc
new file mode 100644 (file)
index 0000000..2bdee22
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.h>
+#include <exceptions/exceptions.h>
+#include <boost/make_shared.hpp>
+
+using namespace isc::db;
+using namespace isc::data;
+
+namespace isc {
+namespace db {
+
+Server::Server(const ServerTag& tag, const std::string& description)
+    : StampedElement(), description_(description) {
+
+    if (description_.length() > 65536) {
+        isc_throw(BadValue, "server description must not be longer than"
+                  " 65536 characters");
+    }
+
+    setServerTag(tag.get());
+}
+
+ServerPtr
+Server::create(const ServerTag& tag, const std::string& description) {
+    return (boost::make_shared<Server>(tag, description));
+}
+
+} // end of namespace isc::db
+} // end of namespace isc
diff --git a/src/lib/database/server.h b/src/lib/database/server.h
new file mode 100644 (file)
index 0000000..4162d1b
--- /dev/null
@@ -0,0 +1,70 @@
+// 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/.
+
+#ifndef DB_SERVER_H
+#define DB_SERVER_H
+
+#include <cc/stamped_element.h>
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+namespace isc {
+namespace db {
+
+class Server;
+
+/// @brief Shared pointer to the @c Server class.
+typedef boost::shared_ptr<Server> ServerPtr;
+
+/// @brief Represents information about the Kea server in the database.
+///
+/// The configuration backend holds the information about the servers
+/// for which the backend holds the configuration information. The
+/// information includes the server tag (unique name), server description
+/// provided by the administrator and the metadata.
+///
+/// This class extends the base class with the server description field.
+class Server : public data::StampedElement {
+private:
+
+    /// @brief Private constructor.
+    ///
+    /// @param tag server tag.
+    /// @param server description.
+    Server(const data::ServerTag& tag, const std::string& description);
+
+public:
+
+    /// @brief Factory function to be used to create an instance of the
+    /// @c Server object.
+    ///
+    /// @param tag server tag.
+    /// @param server description.
+    ///
+    /// @return Pointer to the server instance.
+    /// @throw BadValue if the server tag exceeds 256 characters or the
+    /// description exceeds 65536 characters.
+    static ServerPtr create(const data::ServerTag& tag,
+                            const std::string& description = "");
+
+    /// @brief Returns the description of the server.
+    ///
+    /// @return Description of the server or an empty string if no
+    /// description was specified.
+    std::string getDescription() const {
+        return (description_);
+    }
+
+private:
+
+    /// @brief Description of the server.
+    std::string description_;
+};
+
+} // end of namespace isc::db
+} // end of namespace isc
+
+#endif // DB_SERVER_H
index c05c29ce92d897d753b6de8b9bf65462fe778310..f8548924efdf8c8cc6fc8463abc698f580ec114d 100644 (file)
@@ -24,6 +24,7 @@ libdatabase_unittests_SOURCES += backend_selector_unittest.cc
 libdatabase_unittests_SOURCES += database_connection_unittest.cc
 libdatabase_unittests_SOURCES += dbaccess_parser_unittest.cc
 libdatabase_unittests_SOURCES += run_unittests.cc
+libdatabase_unittests_SOURCES += server_unittest.cc
 libdatabase_unittests_SOURCES += server_selector_unittest.cc
 
 libdatabase_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
diff --git a/src/lib/database/tests/server_unittest.cc b/src/lib/database/tests/server_unittest.cc
new file mode 100644 (file)
index 0000000..ac1e512
--- /dev/null
@@ -0,0 +1,35 @@
+// 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 <config.h>
+#include <database/server.h>
+#include <exceptions/exceptions.h>
+#include <gtest/gtest.h>
+#include <string>
+
+using namespace isc;
+using namespace isc::data;
+using namespace isc::db;
+
+namespace {
+
+TEST(ServerTest, constructor) {
+    ServerPtr server;
+
+    ASSERT_NO_THROW(
+        server = Server::create(ServerTag("xyz"), "my first server")
+    );
+    ASSERT_TRUE(server);
+    EXPECT_EQ("xyz", server->getServerTag());
+    EXPECT_EQ("my first server", server->getDescription());
+}
+
+TEST(ServerTest, tooLongDescription) {
+    EXPECT_THROW(Server::create(ServerTag("xyz"), std::string(65537, 'c')),
+                 BadValue);
+}
+
+}