From: Marcin Siodelski Date: Wed, 13 Jul 2016 06:08:52 +0000 (+0200) Subject: [4489] Added 'readonly' parameter to DbAccessParser. X-Git-Tag: trac4631_base~9^2~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ef05ff339c5b11a93e42e7831f7dd324cc2720f1;p=thirdparty%2Fkea.git [4489] Added 'readonly' parameter to DbAccessParser. --- diff --git a/src/bin/dhcp4/dhcp4.spec b/src/bin/dhcp4/dhcp4.spec index 8e24e6992e..43940ef68b 100644 --- a/src/bin/dhcp4/dhcp4.spec +++ b/src/bin/dhcp4/dhcp4.spec @@ -275,6 +275,12 @@ "item_type": "integer", "item_optional": true, "item_default": 0 + }, + { + "item_name": "readonly", + "item_type": "boolean", + "item_optional": true, + "item_default": false } ] }, diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec index 3571b8e2ac..d824290647 100644 --- a/src/bin/dhcp6/dhcp6.spec +++ b/src/bin/dhcp6/dhcp6.spec @@ -302,6 +302,12 @@ "item_type": "integer", "item_optional": true, "item_default": 0 + }, + { + "item_name": "readonly", + "item_type": "boolean", + "item_optional": true, + "item_default": false } ] }, diff --git a/src/lib/dhcpsrv/database_connection.h b/src/lib/dhcpsrv/database_connection.h index 2be98baf41..c18c16f28c 100644 --- a/src/lib/dhcpsrv/database_connection.h +++ b/src/lib/dhcpsrv/database_connection.h @@ -54,6 +54,15 @@ public: isc::Exception(file, line, what) {} }; +/// @brief Invalid 'readonly' value specification. +/// +/// Thrown when the value of the 'readonly' boolean parameter is invalid. +class DbInvalidReadOnly : public Exception { +public: + DbInvalidReadOnly(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) {} +}; + /// @brief Common database connection class. /// diff --git a/src/lib/dhcpsrv/mysql_host_data_source.cc b/src/lib/dhcpsrv/mysql_host_data_source.cc index a45ef83567..c4b97757e0 100644 --- a/src/lib/dhcpsrv/mysql_host_data_source.cc +++ b/src/lib/dhcpsrv/mysql_host_data_source.cc @@ -1988,11 +1988,11 @@ MySqlHostDataSourceImpl(const MySqlConnection::ParameterMap& parameters) // the default value of "false". } - if (readonly_value == "true" || readonly_value == "1") { + if (readonly_value == "true") { is_readonly_ = true; - } else if ((readonly_value != "false") && (readonly_value != "0")) { - isc_throw(BadValue, "invalid value '" << readonly_value + } else if (readonly_value != "false") { + isc_throw(DbInvalidReadOnly, "invalid value '" << readonly_value << "' specified for boolean parameter 'readonly'"); } diff --git a/src/lib/dhcpsrv/parsers/dbaccess_parser.cc b/src/lib/dhcpsrv/parsers/dbaccess_parser.cc index 5386e9d2d6..2de5485175 100644 --- a/src/lib/dhcpsrv/parsers/dbaccess_parser.cc +++ b/src/lib/dhcpsrv/parsers/dbaccess_parser.cc @@ -53,7 +53,7 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) { // 2. Update the copy with the passed keywords. BOOST_FOREACH(ConfigPair param, config_value->mapValue()) { try { - if (param.first == "persist") { + if ((param.first == "persist") || (param.first == "readonly")) { values_copy[param.first] = (param.second->boolValue() ? "true" : "false"); @@ -72,7 +72,8 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) { } } catch (const isc::data::TypeError& ex) { // Append position of the element. - isc_throw(isc::data::TypeError, ex.what() << " (" + isc_throw(BadValue, "invalid value type specified for " + "parameter '" << param.first << "' (" << param.second->getPosition() << ")"); } } diff --git a/src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc b/src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc index 846808da1f..e71dc2530f 100644 --- a/src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc @@ -88,7 +88,7 @@ public: } // Add the keyword and value - make sure that they are quoted. - // The parameters which are not quoted are persist and + // The parameters which are not quoted are persist, readonly and // lfc-interval as they are boolean and integer respectively. result += quote + keyval[i] + quote + colon + space; if (!quoteValue(std::string(keyval[i]))) { @@ -176,7 +176,8 @@ private: /// @return true if the value of the parameter should be quoted. bool quoteValue(const std::string& parameter) const { return ((parameter != "persist") && (parameter != "lfc-interval") && - (parameter != "connect-timeout")); + (parameter != "connect-timeout") && + (parameter != "readonly")); } }; @@ -560,4 +561,45 @@ TEST_F(DbAccessParserTest, getDbAccessString) { EXPECT_EQ(dbaccess, "name=keatest type=mysql"); } +// Check that the configuration is accepted for the valid value +// of "readonly". +TEST_F(DbAccessParserTest, validReadOnly) { + const char* config[] = {"type", "mysql", + "user", "keatest", + "password", "keatest", + "name", "keatest", + "readonly", "true", + NULL}; + + string json_config = toJson(config); + ConstElementPtr json_elements = Element::fromJSON(json_config); + EXPECT_TRUE(json_elements); + + TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB); + EXPECT_NO_THROW(parser.build(json_elements)); + + checkAccessString("Valid readonly parameter", + parser.getDbAccessParameters(), + config); +} + +// Check that for the invalid value of the "readonly" parameter +// an exception is thrown. +TEST_F(DbAccessParserTest, invalidReadOnly) { + const char* config[] = {"type", "mysql", + "user", "keatest", + "password", "keatest", + "name", "keatest", + "readonly", "1", + NULL}; + + string json_config = toJson(config); + ConstElementPtr json_elements = Element::fromJSON(json_config); + EXPECT_TRUE(json_elements); + + TestDbAccessParser parser("lease-database", DbAccessParser::LEASE_DB); + EXPECT_THROW(parser.build(json_elements), BadValue); +} + + }; // Anonymous namespace diff --git a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc index 058b2e358f..8f57f1c21e 100644 --- a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc @@ -162,6 +162,9 @@ TEST(MySqlHostDataSource, OpenDatabase) { EXPECT_THROW(HostDataSourceFactory::create(connectionString( MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_2)), DbInvalidTimeout); + EXPECT_THROW(HostDataSourceFactory::create(connectionString( + MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, + VALID_TIMEOUT, INVALID_READONLY_DB)), DbInvalidReadOnly); // Check for missing parameters EXPECT_THROW(HostDataSourceFactory::create(connectionString( diff --git a/src/lib/dhcpsrv/testutils/schema.cc b/src/lib/dhcpsrv/testutils/schema.cc index 3420cc7c7e..f782f27f34 100644 --- a/src/lib/dhcpsrv/testutils/schema.cc +++ b/src/lib/dhcpsrv/testutils/schema.cc @@ -32,6 +32,7 @@ const char* VALID_TIMEOUT = "connect-timeout=10"; const char* INVALID_TIMEOUT_1 = "connect-timeout=foo"; const char* INVALID_TIMEOUT_2 = "connect-timeout=-17"; const char* VALID_READONLY_DB = "readonly=true"; +const char* INVALID_READONLY_DB = "readonly=5"; string connectionString(const char* type, const char* name, const char* host, const char* user, const char* password, const char* timeout, diff --git a/src/lib/dhcpsrv/testutils/schema.h b/src/lib/dhcpsrv/testutils/schema.h index fe842ff9e7..97c4627f1b 100644 --- a/src/lib/dhcpsrv/testutils/schema.h +++ b/src/lib/dhcpsrv/testutils/schema.h @@ -28,6 +28,7 @@ extern const char* VALID_TIMEOUT; extern const char* INVALID_TIMEOUT_1; extern const char* INVALID_TIMEOUT_2; extern const char* VALID_READONLY_DB; +extern const char* INVALID_READONLY_DB; /// @brief Given a combination of strings above, produce a connection string. ///