Browse Source

[4489] Added 'readonly' parameter to DbAccessParser.

Marcin Siodelski 8 years ago
parent
commit
ef05ff339c

+ 6 - 0
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
             }
         ]
       },

+ 6 - 0
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
             }
         ]
       },

+ 9 - 0
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.
 ///

+ 3 - 3
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'");
     }
 

+ 3 - 2
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() << ")");
         }
     }

+ 44 - 2
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

+ 3 - 0
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(

+ 1 - 0
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,

+ 1 - 0
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.
 ///