]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#32,!23] Added ControlConfigParser to lib/config
authorThomas Markwalder <tmark@isc.org>
Thu, 27 Sep 2018 14:27:27 +0000 (10:27 -0400)
committerThomas Markwalder <tmark@isc.org>
Fri, 5 Oct 2018 13:05:44 +0000 (09:05 -0400)
src/lib/config/config_ctl_parser.*
    - new files implementing ControlConfigParser

src/lib/config/Makefile.am
    - added new files

src/lib/config/tests/config_ctl_parser_unittests.cc
    - new file which tests new parser

src/lib/config/tests/Makefile.am
    - added new file

src/lib/config/Makefile.am
src/lib/config/config_ctl_info.h
src/lib/config/config_ctl_parser.cc [new file with mode: 0644]
src/lib/config/config_ctl_parser.h [new file with mode: 0644]
src/lib/config/tests/Makefile.am
src/lib/config/tests/config_ctl_parser_unittests.cc [new file with mode: 0644]

index 1f2203033e4835c9fae44e273f1ed848f0210533..62b613891d6db1e712284d64be28d14b4e0573f4 100644 (file)
@@ -20,6 +20,7 @@ libkea_cfgclient_la_SOURCES += base_command_mgr.cc base_command_mgr.h
 libkea_cfgclient_la_SOURCES += client_connection.cc client_connection.h
 libkea_cfgclient_la_SOURCES += command_mgr.cc command_mgr.h
 libkea_cfgclient_la_SOURCES += config_ctl_info.h config_ctl_info.cc
+libkea_cfgclient_la_SOURCES += config_ctl_parser.h config_ctl_parser.cc
 libkea_cfgclient_la_SOURCES += config_log.h config_log.cc
 libkea_cfgclient_la_SOURCES += hooked_command_mgr.cc hooked_command_mgr.h
 libkea_cfgclient_la_SOURCES += timeouts.h
index 7c940bcd496c96be6aa8015de34aee277c8960c3..b188e527fc6a3b9686b416117a21dc462d64af13 100644 (file)
@@ -107,7 +107,7 @@ typedef std::vector<ConfigDbInfo> ConfigDbInfoList;
 /// This is class conveys the configuration control information
 /// described by the following JSON text:
 ///
-/// "ConfigCtl" :
+/// "config-ctl" :
 /// {
 ///     "config-databases":
 ///     [
diff --git a/src/lib/config/config_ctl_parser.cc b/src/lib/config/config_ctl_parser.cc
new file mode 100644 (file)
index 0000000..aba1c59
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2018 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/dhcp_config_error.h>
+#include <config/config_ctl_parser.h>
+#include <database/dbaccess_parser.h>
+#include <string>
+
+using namespace isc;
+using namespace isc::data;
+
+namespace isc {
+namespace config {
+
+ConfigControlInfoPtr
+ConfigControlParser::parse(const data::ConstElementPtr& config_control) {
+    ConfigControlInfoPtr ctl_info(new ConfigControlInfo()); 
+
+    try {
+        if (config_control->contains("config-databases")) {
+            const std::vector<data::ElementPtr>& db_list =
+                config_control->get("config-databases")->listValue();
+
+            for (auto db = db_list.cbegin(); db != db_list.end(); ++db) {
+                db::DbAccessParser parser;
+                std::string access_string;
+                parser.parse(access_string, *db);
+                // @todo do we still need access_string for this at all?
+                // can't we just use params directly and get rid of the
+                // string now that DatabaseConnection::toElement(map) exists?
+                ctl_info->addConfigDatabase(access_string);
+            }
+        }
+
+#if 0
+        // @todo, should it have user_context and what about comment?
+        ConstElementPtr user_context = shared_network_data->get("user-context");
+        if (user_context) {
+            shared_network->setContext(user_context);
+        }
+#endif
+
+    } catch (const isc::ConfigError&) {
+        // Position was already added
+        throw;
+    } catch (const std::exception& ex) {
+        isc_throw(ConfigError, ex.what() << " ("
+                  << config_control->getPosition() << ")");
+    }
+
+    return (ctl_info);
+}
+
+} // end of namespace isc::config
+} // end of namespace isc
+
diff --git a/src/lib/config/config_ctl_parser.h b/src/lib/config/config_ctl_parser.h
new file mode 100644 (file)
index 0000000..5e254bf
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2018 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 CONFIG_CONTROL_PARSER_H
+#define CONFIG_CONTROL_PARSER_H
+
+#include <cc/data.h>
+#include <cc/simple_parser.h>
+#include <config/config_ctl_info.h>
+
+namespace isc {
+namespace config {
+
+/// @brief Implements parser for config control information, "config-control"
+class ConfigControlParser : isc::data::SimpleParser {
+public:
+
+    /// @brief Parses a configuration control Element
+    ///
+    /// @param config_control Element holding the config control content 
+    /// to be parsed.
+    ///
+    /// @return Pointer to newly created ConfigControlInfo instance 
+    /// @throw DhcpConfigError when config control content is invalid.
+    ConfigControlInfoPtr
+    parse(const data::ConstElementPtr& config_control);
+};
+
+} // enf of namespace isc::config
+} // end of namespace isc
+
+#endif // CONFIG_CONTROL_PARSER_H
index 77330bf0dd10bc58cba7e76007760fff74644e84..c98f7b6188f7f50d8d04cebe66b65fd1a6861e46 100644 (file)
@@ -23,6 +23,7 @@ run_unittests_SOURCES = client_connection_unittests.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_SOURCES += command_mgr_unittests.cc
 run_unittests_SOURCES += config_ctl_info_unittests.cc
+run_unittests_SOURCES += config_ctl_parser_unittests.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
diff --git a/src/lib/config/tests/config_ctl_parser_unittests.cc b/src/lib/config/tests/config_ctl_parser_unittests.cc
new file mode 100644 (file)
index 0000000..845acd1
--- /dev/null
@@ -0,0 +1,97 @@
+// Copyright (C) 2018 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/dhcp_config_error.h>
+#include <config/config_ctl_parser.h>
+#include <exceptions/exceptions.h>
+
+#include <gtest/gtest.h>
+
+#include <sstream>
+#include <iostream>
+
+using namespace isc::config;
+using namespace isc::data;
+
+// Verifies valid configurations are parsed correctly.  The test
+// uses round-trip comparison of configuration Elements to determine
+// if parsing was correct.
+TEST(ConfigCtlInfoParser, validConfigs) {
+    std::string configs[] = {
+       "{}",
+
+       "{ \"config-databases\": [] }", 
+
+       "{ \"config-databases\": [ \n"
+       "    { \n"
+       "        \"type\": \"mysql\", \n"
+       "        \"user\":\"tom\", \n"
+       "        \"password\":\"terrific\" \n"
+       "    }, \n"
+       "    { \n"
+       "        \"type\": \"postgresql\",\n"
+       "        \"user\":\"bob\", \n"
+       "        \"password\":\"wonder\" \n"
+       "    } \n"
+       "] } \n" 
+    };
+
+    for (auto config : configs) {
+        ConfigControlParser parser;
+        ConfigControlInfoPtr ctl_info;
+
+        // Turn the JSON config into Elements.
+        ElementPtr source_elem;
+        ASSERT_NO_THROW (source_elem = Element::fromJSON(config)) <<
+                " JSON error, test is broken: " << config;
+
+        // Parse the Elements into a ConfigControlInfo.
+        ASSERT_NO_THROW(ctl_info = parser.parse(source_elem));
+        ASSERT_TRUE(ctl_info);
+
+        // Turn the newly constructed info instance back into elements.
+        ElementPtr parsed_elem;
+        ASSERT_NO_THROW(parsed_elem = ctl_info->toElement());
+
+        // When the config is empty, ControlConfigInfo::toElement still
+        // generates a map with an empty db list.  Replace source for
+        // element comparison below. 
+        if (source_elem->size() == 0) {
+            ASSERT_NO_THROW (source_elem = Element::fromJSON(
+                            "{ \"config-databases\": [] }"));
+        }
+
+        // The parsed element should match the source element.
+        EXPECT_TRUE(parsed_elem->equals(*source_elem)) << "config: " << config;
+    }
+}
+
+// Verify that invalid configurations fail to parse gracefully.
+TEST(ConfigCtlInfoParser, invalidConfigs) {
+    // Note that configurations are must be valid JSON, but invalid logically.
+    std::string configs[] = {
+       "{ \"config-databases\": \"not_list\" }", 
+       "{ \"config-databases\": [ \n"
+       "    { \n"
+       "        \"bogus\": \"param\" \n"
+       "    } \n"
+       "] } \n" 
+    };
+
+    for (auto config : configs) {
+        ConfigControlParser parser;
+
+        // Turn the JSON config into Elements.
+        ElementPtr source_elem;
+        ASSERT_NO_THROW (source_elem = Element::fromJSON(config)) <<
+                " JSON error, test is broken: " << config;
+
+        // Parse the Elements into a ConfigControlInfo.
+        ASSERT_THROW(parser.parse(source_elem), isc::ConfigError) 
+                     << "config: " << config;
+    }
+}