Browse Source

[3668] Added support for lfc-interval parameter in the DbAccessParser.

Marcin Siodelski 10 years ago
parent
commit
24731bc51a

+ 6 - 0
src/bin/dhcp4/dhcp4.spec

@@ -197,6 +197,12 @@
                 "item_type": "boolean",
                 "item_optional": true,
                 "item_default": true
+            },
+            {
+                "item_name": "lfc-interval",
+                "item_type": "integer",
+                "item_optional": true,
+                "item_default": 0
             }
         ]
       },

+ 6 - 0
src/bin/dhcp6/dhcp6.spec

@@ -191,6 +191,12 @@
                 "item_type": "boolean",
                 "item_optional": true,
                 "item_default": true
+            },
+            {
+                "item_name": "lfc-interval",
+                "item_type": "integer",
+                "item_optional": true,
+                "item_default": 0
             }
         ]
       },

+ 21 - 8
src/lib/dhcpsrv/parsers/dbaccess_parser.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -18,6 +18,7 @@
 #include <dhcpsrv/parsers/dbaccess_parser.h>
 
 #include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
 
 #include <map>
 #include <string>
@@ -55,17 +56,21 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
     // use of it).
     values_copy["universe"] = ctx_.universe_ == Option::V4 ? "4" : "6";
 
+    int64_t lfc_interval = 0;
     // 3. Update the copy with the passed keywords.
     BOOST_FOREACH(ConfigPair param, config_value->mapValue()) {
         try {
-            // The persist parameter is the only boolean parameter at the
-            // moment. It needs special handling.
-            if (param.first != "persist") {
-                values_copy[param.first] = param.second->stringValue();
-
-            } else {
+            if (param.first == "persist") {
                 values_copy[param.first] = (param.second->boolValue() ?
                                             "true" : "false");
+
+            } else if (param.first == "lfc-interval") {
+                lfc_interval = param.second->intValue();
+                values_copy[param.first] =
+                    boost::lexical_cast<std::string>(lfc_interval);
+
+            } else {
+                values_copy[param.first] = param.second->stringValue();
             }
         } catch (const isc::data::TypeError& ex) {
             // Append position of the element.
@@ -84,13 +89,21 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) {
                   "to be accessed (" << config_value->getPosition() << ")");
     }
 
-    // b. Check if the 'type; keyword known and throw an exception if not.
+    // b. Check if the 'type' keyword known and throw an exception if not.
     string dbtype = type_ptr->second;
     if ((dbtype != "memfile") && (dbtype != "mysql") && (dbtype != "postgresql")) {
         isc_throw(BadValue, "unknown backend database type: " << dbtype
                   << " (" << config_value->getPosition() << ")");
     }
 
+    // c. Check that the lfc-interval is a number and it is within a resonable
+    // range.
+    if ((lfc_interval < 0) || (lfc_interval > std::numeric_limits<uint32_t>::max())) {
+        isc_throw(BadValue, "lfc-interval value: " << lfc_interval
+                  << " is out of range, expected value: 0.."
+                  << std::numeric_limits<uint32_t>::max());
+    }
+
     // 5. If all is OK, update the stored keyword/value pairs.  We do this by
     // swapping contents - values_copy is destroyed immediately after the
     // operation (when the method exits), so we are not interested in its new

+ 3 - 4
src/lib/dhcpsrv/parsers/dbaccess_parser.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -67,9 +67,8 @@ public:
     /// Parses the set of strings forming the database access specification and
     /// checks that all are OK.  In particular it checks:
     ///
-    /// - "type" is "memfile" or "mysql"
-    /// - If "type" is "memfile", checks that no other values are present: if
-    ///   they are, logs a warning that they will be ignored.
+    /// - "type" is "memfile", "mysql" or "postgresql"
+    /// - "lfc-interval" is a number from the range of 0 to 4294967295.
     ///
     /// Once all has been validated, constructs the database access string
     /// expected by the lease manager.

+ 73 - 6
src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -93,13 +93,15 @@ public:
             }
 
             // Add the keyword and value - make sure that they are quoted.
-            // The only parameter which is not quoted is persist as it
-            // is a boolean value.
+            // The parameters which are not quoted are persist and
+            // lfc-interval as they are boolean and integer respectively.
             result += quote + keyval[i] + quote + colon + space;
-            if (std::string(keyval[i]) != "persist") {
-                result += quote + keyval[i + 1] + quote;
-            } else {
+            if (getNonQuotedParams().find(std::string(keyval[i])) !=
+                getNonQuotedParams().end()) {
                 result += keyval[i + 1];
+
+            } else {
+                result += quote + keyval[i + 1] + quote;
             }
         }
 
@@ -172,6 +174,21 @@ public:
             EXPECT_EQ(corresponding->second, actual->second);
         }
     }
+
+private:
+
+    /// @brief Returns a set of parameters which should be quoted in the
+    /// test configuration.
+    ///
+    /// In particular, this method is called by the @c toJson to determine
+    /// that the parameter being included in the JSON configuration should
+    /// be quoted or not.
+    const std::set<std::string>& getNonQuotedParams() const {
+        static const char* params[] = { "persist", "lfc-interval" };
+        static std::set<std::string> params_set(params, params + sizeof(params));
+        return (params_set);
+    }
+
 };
 
 
@@ -287,6 +304,56 @@ TEST_F(DbAccessParserTest, persistV6Memfile) {
                       config, Option::V6);
 }
 
+// This test checks that the parser accepts the valid value of the
+// lfc-interval parameter.
+TEST_F(DbAccessParserTest, validLFCInterval) {
+    const char* config[] = {"type", "memfile",
+                            "name", "/opt/kea/var/kea-leases6.csv",
+                            "lfc-interval", "3600",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+    ASSERT_NO_THROW(parser.build(json_elements));
+    checkAccessString("Valid LFC Interval", parser.getDbAccessParameters(),
+                      config, Option::V6);
+}
+
+// This test checks that the parser rejects the negative value of the
+// lfc-interval parameter.
+TEST_F(DbAccessParserTest, negativeLFCInterval) {
+    const char* config[] = {"type", "memfile",
+                            "name", "/opt/kea/var/kea-leases6.csv",
+                            "lfc-interval", "-1",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+    EXPECT_THROW(parser.build(json_elements), BadValue);
+}
+
+// This test checks that the parser rejects the too large (greater than
+// the max uint32_t) value of the lfc-interval parameter.
+TEST_F(DbAccessParserTest, largeLFCInterval) {
+    const char* config[] = {"type", "memfile",
+                            "name", "/opt/kea/var/kea-leases6.csv",
+                            "lfc-interval", "4294967296",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+    EXPECT_THROW(parser.build(json_elements), BadValue);
+}
+
 // Check that the parser works with a valid MySQL configuration
 TEST_F(DbAccessParserTest, validTypeMysql) {
     const char* config[] = {"type",     "mysql",