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
dhcp_config_error.h \
element_value.h \
json_feed.h \
+ server_tag.h \
simple_parser.h \
stamped_element.h \
stamped_value.h \
--- /dev/null
+// 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
--- /dev/null
+// 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
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();
#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>
/// @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.
boost::posix_time::ptime timestamp_;
/// @brief Holds server tag.
- std::string server_tag_;
+ ServerTag server_tag_;
};
} // end of namespace isc::data
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
--- /dev/null
+// 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);
+ }
+}
+
+}
// 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.
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
db_exceptions.h \
db_log.h \
db_messages.h \
+ server.h \
server_selector.h
--- /dev/null
+// 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
--- /dev/null
+// 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
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)
--- /dev/null
+// 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);
+}
+
+}