return (s.str());
}
+ElementPtr
+CfgDbAccess::toElementDbAccessString(const std::string& dbaccess) {
+ ElementPtr result = Element::createMap();
+ // Code from DatabaseConnection::parse
+ if (dbaccess.empty()) {
+ return (result);
+ }
+ std::vector<std::string> tokens;
+ boost::split(tokens, dbaccess, boost::is_any_of(std::string("\t ")));
+ BOOST_FOREACH(std::string token, tokens) {
+ size_t pos = token.find("=");
+ if (pos != std::string::npos) {
+ std::string keyword = token.substr(0, pos);
+ std::string value = token.substr(pos + 1);
+ if ((keyword == "lfc-interval") ||
+ (keyword == "connect-timeout") ||
+ (keyword == "request-timeout") ||
+ (keyword == "port") ||
+ (keyword == "max-reconnect-tries") ||
+ (keyword == "reconnect-wait-time") ||
+ (keyword == "tcp-keepalive")) {
+ // integer parameters
+ int64_t int_value;
+ try {
+ int_value = boost::lexical_cast<int64_t>(value);
+ result->set(keyword, Element::create(int_value));
+ } catch (...) {
+ isc_throw(ToElementError, "invalid DB access "
+ << "integer parameter: "
+ << keyword << "=" << value);
+ }
+ } else if ((keyword == "persist") ||
+ (keyword == "readonly") ||
+ (keyword == "tcp-nodelay")) {
+ if (value == "true") {
+ result->set(keyword, Element::create(true));
+ } else if (value == "false") {
+ result->set(keyword, Element::create(false));
+ } else {
+ isc_throw(ToElementError, "invalid DB access "
+ << "boolean parameter: "
+ << keyword << "=" << value);
+ }
+ } else if ((keyword == "type") ||
+ (keyword == "user") ||
+ (keyword == "password") ||
+ (keyword == "host") ||
+ (keyword == "name") ||
+ (keyword == "contact-points") ||
+ (keyword == "keyspace")) {
+ result->set(keyword, Element::create(value));
+ } else {
+ isc_throw(ToElementError, "unknown DB access parameter: "
+ << keyword << "=" << value);
+ }
+ } else {
+ isc_throw(ToElementError, "Cannot unparse " << token
+ << ", expected format is name=value");
+ }
+ }
+ return (result);
+}
+
} // end of isc::dhcp namespace
} // end of isc namespace
#include <config.h>
#include <cc/data.h>
+#include <database/dbaccess_parser.h>
#include <dhcpsrv/cfg_db_access.h>
#include <dhcpsrv/host_data_source_factory.h>
#include <dhcpsrv/host_mgr.h>
#endif
+// Check that the toElementDbAccessString() handles all valid parameters
+TEST(CfgDbAccess, toElementDbAccessStringValid) {
+ const char* configs[] = {
+ "{\n"
+ "\"type\": \"memfile\", \n"
+ "\"user\": \"user_str\", \n"
+ "\"name\": \"name_str\", \n"
+ "\"host\": \"host_str\", \n"
+ "\"password\": \"password_str\", \n"
+ "\"contact-points\": \"contact_str\", \n"
+ "\"keyspace\": \"keyspace_str\", \n"
+ "\"lfc-interval\" : 100, \n"
+ "\"connect-timeout\" : 200, \n"
+ "\"port\" : 300, \n"
+ "\"persist\" : true, \n"
+ "\"readonly\" : false \n"
+ "}\n"
+ };
+
+ db::DbAccessParser parser;
+ std::string access_str;
+ data::ConstElementPtr json_elements;
+
+ ASSERT_NO_THROW(json_elements = data::Element::fromJSON(configs[0]));
+ ASSERT_NO_THROW(parser.parse(access_str, json_elements));
+
+ data::ElementPtr round_trip = CfgDbAccess::toElementDbAccessString(access_str);
+
+ ASSERT_TRUE(json_elements->equals(*round_trip));
+}
+
+// Check that toElementDbAccessString() catches invalid parameters.
+TEST(CfgDbAccess, toElementDbAccessStringInvalid) {
+ std::vector<std::string> access_strs = {
+ "bogus-param=memfile",
+ "lfc-interval=not-an-integer",
+ "connect-timeout=not-an-integer",
+ "port=not-an-integer",
+ "persist=not-boolean",
+ "readonly=not-boolean"
+ };
+
+ for (auto access_str : access_strs) {
+ ASSERT_THROW(CfgDbAccess::toElementDbAccessString(access_str),
+ isc::ToElementError)
+ << "access string should have failed, string=["
+ << access_str << "]";
+ }
+}
+
+// Check that toElementDbAccessString() handles empty access string
+TEST(CfgDbAccess, toElementDbAccessStringEmpty) {
+ data::ConstElementPtr elements;
+ ASSERT_NO_THROW(elements = CfgDbAccess::toElementDbAccessString(""));
+ ASSERT_TRUE(elements);
+ ASSERT_EQ(0, elements->size());
+}
+
} // end of anonymous namespace