]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[4489] Added 'readonly' parameter to DbAccessParser.
authorMarcin Siodelski <marcin@isc.org>
Wed, 13 Jul 2016 06:08:52 +0000 (08:08 +0200)
committerMarcin Siodelski <marcin@isc.org>
Thu, 28 Jul 2016 11:46:57 +0000 (13:46 +0200)
src/bin/dhcp4/dhcp4.spec
src/bin/dhcp6/dhcp6.spec
src/lib/dhcpsrv/database_connection.h
src/lib/dhcpsrv/mysql_host_data_source.cc
src/lib/dhcpsrv/parsers/dbaccess_parser.cc
src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
src/lib/dhcpsrv/testutils/schema.cc
src/lib/dhcpsrv/testutils/schema.h

index 8e24e6992ed70a5e20ad4e83f96ffd25860b8a64..43940ef68b5761f9b49b1252b8724083adf63327 100644 (file)
                 "item_type": "integer",
                 "item_optional": true,
                 "item_default": 0
+            },
+            {
+                "item_name": "readonly",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": false
             }
         ]
       },
index 3571b8e2ac35a2d04cb418200258277970ab6d48..d82429064791cd8d26dc2decb674166f1dc990f8 100644 (file)
                 "item_type": "integer",
                 "item_optional": true,
                 "item_default": 0
+            },
+            {
+                "item_name": "readonly",
+                "item_type": "boolean",
+                "item_optional": true,
+                "item_default": false
             }
         ]
       },
index 2be98baf414530b4b11cd4b218c197b25a172be8..c18c16f28cdc7b73615c462689ceaa80d720aff0 100644 (file)
@@ -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.
 ///
index a45ef83567590c950ce81cfee3eaf2d56460ab28..c4b97757e0b382ec0ce0982ee5035fd15d480fc3 100644 (file)
@@ -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'");
     }
 
index 5386e9d2d692ebfd58ebbf2b1d274fa7a827c84a..2de5485175fe77404e370c2e7c28a291c909b5c4 100644 (file)
@@ -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() << ")");
         }
     }
index 846808da1fbd1eae42e4f2be1a04628806c8221c..e71dc2530f482167cce3b2a8f3c0ce8dbf6de480 100644 (file)
@@ -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
index 058b2e358f1949ea13be74dd69bb6b5a06cb9b2e..8f57f1c21eb27ebf1cfc3ffd64382bd56d03b089 100644 (file)
@@ -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(
index 3420cc7c7e33052498203d87a4df211eeb2eb0cd..f782f27f34e4e7196dfc157a56cd2fcc5a679e7e 100644 (file)
@@ -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,
index fe842ff9e7b65b4fa003f4c4cb0ba472a50ffff7..97c4627f1b2d3675bcaccd999991ebb4b0a1ae37 100644 (file)
@@ -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.
 ///