Commit bfe0c99c authored by Marcin Siodelski's avatar Marcin Siodelski

[#93,!51] Fetching global options is now possible.

parent 5f33dc7d
...@@ -57,6 +57,9 @@ public: ...@@ -57,6 +57,9 @@ public:
GET_OPTION_DEF4_CODE_SPACE, GET_OPTION_DEF4_CODE_SPACE,
GET_ALL_OPTION_DEFS4, GET_ALL_OPTION_DEFS4,
GET_MODIFIED_OPTION_DEFS4, GET_MODIFIED_OPTION_DEFS4,
GET_OPTION4_CODE_SPACE,
GET_ALL_OPTIONS4,
GET_MODIFIED_OPTIONS4,
GET_OPTION4_SUBNET_ID_CODE_SPACE, GET_OPTION4_SUBNET_ID_CODE_SPACE,
GET_OPTION4_SHARED_NETWORK_CODE_SPACE, GET_OPTION4_SHARED_NETWORK_CODE_SPACE,
INSERT_SUBNET4, INSERT_SUBNET4,
...@@ -67,6 +70,7 @@ public: ...@@ -67,6 +70,7 @@ public:
UPDATE_SUBNET4, UPDATE_SUBNET4,
UPDATE_SHARED_NETWORK4, UPDATE_SHARED_NETWORK4,
UPDATE_OPTION_DEF4, UPDATE_OPTION_DEF4,
UPDATE_OPTION4,
UPDATE_OPTION4_SUBNET_ID, UPDATE_OPTION4_SUBNET_ID,
UPDATE_OPTION4_SHARED_NETWORK, UPDATE_OPTION4_SHARED_NETWORK,
DELETE_SUBNET4_ID, DELETE_SUBNET4_ID,
...@@ -77,6 +81,7 @@ public: ...@@ -77,6 +81,7 @@ public:
DELETE_ALL_SHARED_NETWORKS4, DELETE_ALL_SHARED_NETWORKS4,
DELETE_OPTION_DEF4_CODE_NAME, DELETE_OPTION_DEF4_CODE_NAME,
DELETE_ALL_OPTION_DEFS4, DELETE_ALL_OPTION_DEFS4,
DELETE_OPTION4,
DELETE_OPTION4_SUBNET_ID, DELETE_OPTION4_SUBNET_ID,
DELETE_OPTION4_SHARED_NETWORK, DELETE_OPTION4_SHARED_NETWORK,
DELETE_OPTIONS4_SUBNET_ID, DELETE_OPTIONS4_SUBNET_ID,
...@@ -709,6 +714,43 @@ public: ...@@ -709,6 +714,43 @@ public:
transaction.commit(); transaction.commit();
} }
/// @brief Sends query to insert or update global DHCP option.
///
/// @param selector Server selector.
/// @param option Pointer to the option descriptor encapsulating the option.
void createUpdateOption4(const ServerSelector& selector,
const OptionDescriptorPtr& option) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint8_t>(option->option_->getType()),
createOptionValueBinding(option),
MySqlBinding::condCreateString(option->formatted_value_),
MySqlBinding::condCreateString(option->space_name_),
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(option->persistent_)),
MySqlBinding::createNull(),
MySqlBinding::createNull(),
MySqlBinding::createInteger<uint8_t>(0),
createInputContextBinding(option),
MySqlBinding::createNull(),
MySqlBinding::createNull(),
MySqlBinding::createTimestamp(option->getModificationTime())
};
OptionDescriptorPtr existing_option = getOption4(selector,
option->option_->getType(),
option->space_name_);
if (existing_option) {
in_bindings.push_back(MySqlBinding::createInteger<uint8_t>(option->option_->getType()));
in_bindings.push_back(MySqlBinding::condCreateString(option->space_name_));
conn_.updateDeleteQuery(MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4,
in_bindings);
} else {
conn_.insertQuery(MySqlConfigBackendDHCPv4Impl::INSERT_OPTION4,
in_bindings);
}
}
/// @brief Sends query to insert or update DHCP option in a subnet. /// @brief Sends query to insert or update DHCP option in a subnet.
/// ///
/// @param selector Server selector. /// @param selector Server selector.
...@@ -839,6 +881,58 @@ public: ...@@ -839,6 +881,58 @@ public:
return (option_defs); return (option_defs);
} }
/// @brief Sends query to retrieve single global option by code and
/// option space.
///
/// @param selector Server selector.
/// @param code Option code.
/// @param space Option space name.
///
/// @return Pointer to the returned option or NULL if such option
/// doesn't exist.
OptionDescriptorPtr
getOption4(const ServerSelector& selector, const uint16_t code,
const std::string& space) {
OptionContainer options;
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(code)),
MySqlBinding::createString(space)
};
getOptions(GET_OPTION4_CODE_SPACE, in_bindings, Option::V4, options);
return (options.empty() ? OptionDescriptorPtr() :
OptionDescriptorPtr(new OptionDescriptor(*options.begin())));
}
/// @brief Sends query to retrieve all global options.
///
/// @param selector Server selector.
/// @return Container holding returned options.
OptionContainer
getAllOptions4(const ServerSelector& selector) {
OptionContainer options;
MySqlBindingCollection in_bindings;
getOptions(MySqlConfigBackendDHCPv4Impl::GET_ALL_OPTIONS4,
in_bindings, Option::V4, options);
return (options);
}
/// @brief Sends query to retrieve global options with modification
/// time later than specified timestamp.
///
/// @param selector Server selector.
/// @return Container holding returned options.
OptionContainer
getModifiedOptions4(const ServerSelector& selector,
const boost::posix_time::ptime& modification_time) {
OptionContainer options;
MySqlBindingCollection in_bindings = {
MySqlBinding::createTimestamp(modification_time)
};
getOptions(MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_OPTIONS4,
in_bindings, Option::V4, options);
return (options);
}
/// @brief Sends query to retrieve single option by code and option space /// @brief Sends query to retrieve single option by code and option space
/// for a giben subnet id. /// for a giben subnet id.
/// ///
...@@ -966,6 +1060,23 @@ public: ...@@ -966,6 +1060,23 @@ public:
return (conn_.updateDeleteQuery(DELETE_OPTION_DEF4_CODE_NAME, in_bindings)); return (conn_.updateDeleteQuery(DELETE_OPTION_DEF4_CODE_NAME, in_bindings));
} }
/// @brief Deletes global option.
///
/// @param selector Server selector.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
void deleteOption4(const db::ServerSelector& /* selector */,
const uint16_t code,
const std::string& space) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint8_t>(code),
MySqlBinding::createString(space)
};
// Run DELETE.
conn_.updateDeleteQuery(DELETE_OPTION4, in_bindings);
}
/// @brief Deletes subnet level option. /// @brief Deletes subnet level option.
/// ///
/// @param selector Server selector. /// @param selector Server selector.
...@@ -1373,6 +1484,66 @@ TaggedStatementArray tagged_statements = { { ...@@ -1373,6 +1484,66 @@ TaggedStatementArray tagged_statements = { {
"WHERE modification_ts > ? " "WHERE modification_ts > ? "
"ORDER BY d.id" }, "ORDER BY d.id" },
// Retrieves global option by code and space.
{ MySqlConfigBackendDHCPv4Impl::GET_OPTION4_CODE_SPACE,
"SELECT"
" option_id,"
" code,"
" value,"
" formatted_value,"
" space,"
" persistent,"
" dhcp4_subnet_id,"
" scope_id,"
" user_context,"
" shared_network_name,"
" pool_id,"
" modification_ts "
"FROM dhcp4_options "
"WHERE scope_id = 0 AND code = ? AND space = ? "
"ORDER BY option_id"
},
// Retrieves all global options.
{ MySqlConfigBackendDHCPv4Impl::GET_ALL_OPTIONS4,
"SELECT"
" option_id,"
" code,"
" value,"
" formatted_value,"
" space,"
" persistent,"
" dhcp4_subnet_id,"
" scope_id,"
" user_context,"
" shared_network_name,"
" pool_id,"
" modification_ts "
"FROM dhcp4_options "
"WHERE scope_id = 0 "
"ORDER BY option_id"
},
// Retrieves modified options.
{ MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_OPTIONS4,
"SELECT"
" option_id,"
" code,"
" value,"
" formatted_value,"
" space,"
" persistent,"
" dhcp4_subnet_id,"
" scope_id,"
" user_context,"
" shared_network_name,"
" pool_id,"
" modification_ts "
"FROM dhcp4_options "
"WHERE scope_id = 0 AND modification_ts > ? "
"ORDER BY option_id"
},
// Retrieves an option for a given subnet, option code and space. // Retrieves an option for a given subnet, option code and space.
{ MySqlConfigBackendDHCPv4Impl::GET_OPTION4_SUBNET_ID_CODE_SPACE, { MySqlConfigBackendDHCPv4Impl::GET_OPTION4_SUBNET_ID_CODE_SPACE,
"SELECT" "SELECT"
...@@ -1552,6 +1723,24 @@ TaggedStatementArray tagged_statements = { { ...@@ -1552,6 +1723,24 @@ TaggedStatementArray tagged_statements = { {
" user_context = ? " " user_context = ? "
"WHERE code = ? AND space = ?" }, "WHERE code = ? AND space = ?" },
// Update existing global option.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4,
"UPDATE dhcp4_options SET"
" code = ?,"
" value = ?,"
" formatted_value = ?,"
" space = ?,"
" persistent = ?,"
" dhcp_client_class = ?,"
" dhcp4_subnet_id = ?,"
" scope_id = ?,"
" user_context = ?,"
" shared_network_name = ?,"
" pool_id = ?,"
" modification_ts = ? "
"WHERE scope_id = 0 AND code = ? AND space = ?"
},
// Update existing subnet level option. // Update existing subnet level option.
{ MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4_SUBNET_ID, { MySqlConfigBackendDHCPv4Impl::UPDATE_OPTION4_SUBNET_ID,
"UPDATE dhcp4_options SET" "UPDATE dhcp4_options SET"
...@@ -1625,6 +1814,11 @@ TaggedStatementArray tagged_statements = { { ...@@ -1625,6 +1814,11 @@ TaggedStatementArray tagged_statements = { {
{ MySqlConfigBackendDHCPv4Impl::DELETE_ALL_OPTION_DEFS4, { MySqlConfigBackendDHCPv4Impl::DELETE_ALL_OPTION_DEFS4,
"DELETE FROM dhcp4_option_def" }, "DELETE FROM dhcp4_option_def" },
// Delete single global option.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4,
"DELETE FROM dhcp4_options "
"WHERE scope_id = 0 AND code = ? AND space = ?" },
// Delete single option from a subnet. // Delete single option from a subnet.
{ MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4_SUBNET_ID, { MySqlConfigBackendDHCPv4Impl::DELETE_OPTION4_SUBNET_ID,
"DELETE FROM dhcp4_options " "DELETE FROM dhcp4_options "
...@@ -1745,6 +1939,25 @@ getModifiedOptionDefs4(const ServerSelector& server_selector, ...@@ -1745,6 +1939,25 @@ getModifiedOptionDefs4(const ServerSelector& server_selector,
return (impl_->getModifiedOptionDefs4(server_selector, modification_time)); return (impl_->getModifiedOptionDefs4(server_selector, modification_time));
} }
OptionDescriptorPtr
MySqlConfigBackendDHCPv4::getOption4(const ServerSelector& selector,
const uint16_t code,
const std::string& space) const {
return (impl_->getOption4(selector, code, space));
}
OptionContainer
MySqlConfigBackendDHCPv4::getAllOptions4(const ServerSelector& selector) const {
return (impl_->getAllOptions4(selector));
}
OptionContainer
MySqlConfigBackendDHCPv4::
getModifiedOptions4(const ServerSelector& selector,
const boost::posix_time::ptime& modification_time) const {
return (impl_->getModifiedOptions4(selector, modification_time));
}
util::OptionalValue<std::string> util::OptionalValue<std::string>
MySqlConfigBackendDHCPv4::getGlobalStringParameter4(const ServerSelector& /* server_selector */, MySqlConfigBackendDHCPv4::getGlobalStringParameter4(const ServerSelector& /* server_selector */,
const std::string& /* name */) const { const std::string& /* name */) const {
...@@ -1781,8 +1994,9 @@ MySqlConfigBackendDHCPv4::createUpdateOptionDef4(const ServerSelector& server_se ...@@ -1781,8 +1994,9 @@ MySqlConfigBackendDHCPv4::createUpdateOptionDef4(const ServerSelector& server_se
} }
void void
MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& /* server_selector */, MySqlConfigBackendDHCPv4::createUpdateOption4(const ServerSelector& selector,
const OptionDescriptorPtr& /* option */) { const OptionDescriptorPtr& option) {
impl_->createUpdateOption4(selector, option);
} }
void void
...@@ -1861,10 +2075,10 @@ MySqlConfigBackendDHCPv4::deleteAllOptionDefs4(const ServerSelector& /* server_s ...@@ -1861,10 +2075,10 @@ MySqlConfigBackendDHCPv4::deleteAllOptionDefs4(const ServerSelector& /* server_s
} }
uint64_t uint64_t
MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& /* server_selector */, MySqlConfigBackendDHCPv4::deleteOption4(const ServerSelector& selector,
const uint16_t /* code */, const uint16_t code,
const std::string& /* space */) { const std::string& space) {
return (0); impl_->deleteOption4(selector, code, space);
} }
uint64_t uint64_t
......
...@@ -116,6 +116,33 @@ public: ...@@ -116,6 +116,33 @@ public:
getModifiedOptionDefs4(const db::ServerSelector& server_selector, getModifiedOptionDefs4(const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const; const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves single option by code and space.
///
/// @param selector Server selector.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
virtual OptionDescriptorPtr
getOption4(const db::ServerSelector& selector, const uint16_t code,
const std::string& space) const;
/// @brief Retrieves all global options.
///
/// @param selector Server selector.
/// @return Collection of global options or empty collection if no
/// option found.
virtual OptionContainer
getAllOptions4(const db::ServerSelector& selector) const;
/// @brief Retrieves option modified after specified time.
///
/// @param selector Server selector.
/// @param modification_time Lower bound option modification time.
/// @return Collection of global options or empty collection if no
/// option found.
virtual OptionContainer
getModifiedOptions4(const db::ServerSelector& selector,
const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves global string parameter value. /// @brief Retrieves global string parameter value.
/// ///
/// @param server_selector Server selector. /// @param server_selector Server selector.
......
...@@ -618,7 +618,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getAllOptionDefs4) { ...@@ -618,7 +618,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getAllOptionDefs4) {
} }
// Test that option definitions modified after given time can be fetched. // Test that option definitions modified after given time can be fetched.
TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptionDefinitions4) { TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptionDefs4) {
// Explicitly set timestamps of option definitions. First option // Explicitly set timestamps of option definitions. First option
// definition has a timestamp pointing to the future. Second option // definition has a timestamp pointing to the future. Second option
// definition has timestamp pointing to the past (yesterday). // definition has timestamp pointing to the past (yesterday).
...@@ -654,6 +654,107 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptionDefinitions4) { ...@@ -654,6 +654,107 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptionDefinitions4) {
ASSERT_TRUE(option_defs.empty()); ASSERT_TRUE(option_defs.empty());
} }
// This test verifies that global option can be added, updated and deleted.
TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateDeleteOption4) {
// Add option to the database.
OptionDescriptorPtr opt_boot_file_name = test_options_[0];
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
opt_boot_file_name);
// Make sure we can retrieve this option and that it is equal to the
// option we have inserted into the database.
OptionDescriptorPtr returned_opt_boot_file_name =
cbptr_->getOption4(ServerSelector::UNASSIGNED(),
opt_boot_file_name->option_->getType(),
opt_boot_file_name->space_name_);
ASSERT_TRUE(returned_opt_boot_file_name);
EXPECT_TRUE(returned_opt_boot_file_name->equals(*opt_boot_file_name));
// Modify option and update it in the database.
opt_boot_file_name->persistent_ = !opt_boot_file_name->persistent_;
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
opt_boot_file_name);
// Retrieve the option again and make sure that updates were
// properly propagated to the database.
returned_opt_boot_file_name = cbptr_->getOption4(ServerSelector::UNASSIGNED(),
opt_boot_file_name->option_->getType(),
opt_boot_file_name->space_name_);
ASSERT_TRUE(returned_opt_boot_file_name);
EXPECT_TRUE(returned_opt_boot_file_name->equals(*opt_boot_file_name));
// Delete option from the database and make sure it is gone.
cbptr_->deleteOption4(ServerSelector::UNASSIGNED(),
opt_boot_file_name->option_->getType(),
opt_boot_file_name->space_name_);
EXPECT_FALSE(cbptr_->getOption4(ServerSelector::UNASSIGNED(),
opt_boot_file_name->option_->getType(),
opt_boot_file_name->space_name_));
}
// This test verifies that all global options can be retrieved.
TEST_F(MySqlConfigBackendDHCPv4Test, getAllOptions4) {
// Add three global options to the database.
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
test_options_[0]);
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
test_options_[1]);
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
test_options_[5]);
// Retrieve all these options.
OptionContainer returned_options = cbptr_->getAllOptions4(ServerSelector::UNASSIGNED());
ASSERT_EQ(3, returned_options.size());
// Get the container index used to search options by option code.
const OptionContainerTypeIndex& index = returned_options.get<1>();
// Verify that all options we put into the database were
// returned.
auto option0 = index.find(test_options_[0]->option_->getType());
ASSERT_FALSE(option0 == index.end());
EXPECT_TRUE(option0->equals(*test_options_[0]));
auto option1 = index.find(test_options_[1]->option_->getType());
ASSERT_FALSE(option1 == index.end());
EXPECT_TRUE(option1->equals(*test_options_[1]));
auto option5 = index.find(test_options_[5]->option_->getType());
ASSERT_FALSE(option5 == index.end());
EXPECT_TRUE(option5->equals(*test_options_[5]));
}
// This test verifies that modified global options can be retrieved.
TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptions4) {
// Assign timestamps to the options we're going to store in the
// database.
test_options_[0]->setModificationTime(timestamps_["tomorrow"]);
test_options_[1]->setModificationTime(timestamps_["yesterday"]);
test_options_[5]->setModificationTime(timestamps_["today"]);
// Put options into the database.
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
test_options_[0]);
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
test_options_[1]);
cbptr_->createUpdateOption4(ServerSelector::UNASSIGNED(),
test_options_[5]);
// Get options with the timestamp later than today. Only
// one option should be returned.
OptionContainer returned_options =
cbptr_->getModifiedOptions4(ServerSelector::UNASSIGNED(),
timestamps_["today"]);
ASSERT_EQ(1, returned_options.size());
// The returned option should be the one with the timestamp
// set to tomorrow.
const OptionContainerTypeIndex& index = returned_options.get<1>();
auto option0 = index.find(test_options_[0]->option_->getType());
ASSERT_FALSE(option0 == index.end());
EXPECT_TRUE(option0->equals(*test_options_[0]));
}
// This test verifies that subnet level option can be added, updated and // This test verifies that subnet level option can be added, updated and
// deleted. // deleted.
TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateDeleteSubnetOption4) { TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateDeleteSubnetOption4) {
......
...@@ -118,6 +118,33 @@ public: ...@@ -118,6 +118,33 @@ public:
getModifiedOptionDefs4(const db::ServerSelector& server_selector, getModifiedOptionDefs4(const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const = 0; const boost::posix_time::ptime& modification_time) const = 0;
/// @brief Retrieves single option by code and space.
///
/// @param selector Server selector.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
virtual OptionDescriptorPtr
getOption4(const db::ServerSelector& selector, const uint16_t code,
const std::string& space) const = 0;
/// @brief Retrieves all global options.
///
/// @param selector Server selector.
/// @return Collection of global options or empty collection if no
/// option found.
virtual OptionContainer
getAllOptions4(const db::ServerSelector& selector) const = 0;
/// @brief Retrieves option modified after specified time.
///
/// @param selector Server selector.
/// @param modification_time Lower bound option modification time.
/// @return Collection of global options or empty collection if no
/// option found.
virtual OptionContainer
getModifiedOptions4(const db::ServerSelector& selector,
const boost::posix_time::ptime& modification_time) const = 0;
/// @brief Retrieves global string parameter value. /// @brief Retrieves global string parameter value.
/// ///
/// @param server_selector Server selector. /// @param server_selector Server selector.
......
...@@ -138,6 +138,40 @@ public: ...@@ -138,6 +138,40 @@ public:
const db::ServerSelector& server_selector, const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const; const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves single option by code and space.
///
/// @param backend_selector Backend selector.
/// @param server_selector Server selector.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
virtual OptionDescriptorPtr
getOption4(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const uint16_t code,
const std::string& space) const;
/// @brief Retrieves all global options.
///
/// @param backend_selector Backend selector.
/// @param server_selector Server selector.
/// @return Collection of global options or empty collection if no
/// option found.
virtual OptionContainer
getAllOptions4(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector) const;
/// @brief Retrieves option modified after specified time.
///
/// @param backend_selector Backend selector.
/// @param server_selector Server selector.
/// @param modification_time Lower bound option modification time.
/// @return Collection of global options or empty collection if no
/// option found.
virtual OptionContainer
getModifiedOptions4(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves global string parameter value. /// @brief Retrieves global string parameter value.
/// ///
/// @param backend_selector Backend selector. /// @param backend_selector Backend selector.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment