Commit 05767377 authored by Marcin Siodelski's avatar Marcin Siodelski

[#440,!218] Implemented getSharedNetworkSubnets4 for DHCPv4 CB.

parent 23058ff4
......@@ -60,6 +60,7 @@ public:
GET_SUBNET4_PREFIX,
GET_ALL_SUBNETS4,
GET_MODIFIED_SUBNETS4,
GET_SHARED_NETWORK_SUBNETS4,
GET_POOL4_RANGE,
GET_SHARED_NETWORK4_NAME,
GET_ALL_SHARED_NETWORKS4,
......@@ -587,6 +588,28 @@ public:
}
}
/// @brief Sends query to retrieve all subnets belonging to a shared network.
///
/// @param server_selector Server selector.
/// @param shared_network_name Name of the shared network for which the
/// subnets should be retrieved.
/// @param [out] subnets Reference to the subnet collection structure where
/// subnets should be inserted.
void getSharedNetworkSubnets4(const ServerSelector& server_selector,
const std::string& shared_network_name,
Subnet4Collection& subnets) {
auto tags = getServerTags(server_selector);
for (auto tag : tags) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createString(tag),
MySqlBinding::createString(shared_network_name)
};
getSubnets4(GET_SHARED_NETWORK_SUBNETS4, in_bindings, subnets);
}
}
/// @brief Sends query to retrieve multiple pools.
///
/// Query should order pools by id.
......@@ -728,11 +751,31 @@ public:
// Create binding with shared network name if the subnet belongs to a
// shared network.
MySqlBindingPtr shared_network_binding;
SharedNetwork4Ptr shared_network;
subnet->getSharedNetwork(shared_network);
MySqlBindingPtr shared_network_binding =
(shared_network ? MySqlBinding::createString(shared_network->getName()) :
MySqlBinding::createNull());
// Check if the subnet is associated with a shared network instance.
// If it is, create the binding using the name of the shared network
// returned by this instance.
if (shared_network) {
shared_network_binding = MySqlBinding::createString(shared_network->getName());
// If the subnet is associated with a shared network by name (no
// shared network instance), use this name to create the binding.
// This may be the case if the subnet is added as a result of
// receiving a control command that merely specifies shared
// network name. In that case, it is expected that the shared
// network data is already stored in the database.
} else if (!subnet->getSharedNetworkName().empty()) {
shared_network_binding = MySqlBinding::createString(subnet->getSharedNetworkName());
// If the subnet is not associated with a shared network, create
// null binding.
} else {
shared_network_binding = MySqlBinding::createNull();
}
// Create input bindings.
MySqlBindingCollection in_bindings = {
......@@ -2094,6 +2137,11 @@ TaggedStatementArray tagged_statements = { {
MYSQL_GET_SUBNET4(AND s.modification_ts > ?)
},
// Select subnets belonging to a shared network.
{ MySqlConfigBackendDHCPv4Impl::GET_SHARED_NETWORK_SUBNETS4,
MYSQL_GET_SUBNET4(AND s.shared_network_name = ?)
},
// Select pool by address range.
{ MySqlConfigBackendDHCPv4Impl::GET_POOL4_RANGE,
"SELECT"
......@@ -2475,6 +2523,14 @@ MySqlConfigBackendDHCPv4::getModifiedSubnets4(const ServerSelector& server_selec
return (subnets);
}
Subnet4Collection
MySqlConfigBackendDHCPv4::getSharedNetworkSubnets4(const ServerSelector& server_selector,
const std::string& shared_network_name) const {
Subnet4Collection subnets;
impl_->getSharedNetworkSubnets4(server_selector, shared_network_name, subnets);
return (subnets);
}
SharedNetwork4Ptr
MySqlConfigBackendDHCPv4::getSharedNetwork4(const ServerSelector& server_selector,
const std::string& name) const {
......
......@@ -65,6 +65,16 @@ public:
getModifiedSubnets4(const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves all subnets belonging to a specified shared network.
///
/// @param server_selector Server selector.
/// @param shared_network_name Name of the shared network for which the
/// subnets should be retrieved.
/// @return Collection of subnets or empty collection if no subnet found.
virtual Subnet4Collection
getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
const std::string& shared_network_name) const;
/// @brief Retrieves shared network by name.
///
/// @param server_selector Server selector.
......
......@@ -801,6 +801,55 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSubnets4) {
ASSERT_TRUE(subnets.empty());
}
// Test that subnets belonging to a shared network can be retrieved.
TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetworkSubnets4) {
// Assign test subnets into shared networks level1 and level2.
test_subnets_[1]->setSharedNetworkName("level1");
test_subnets_[2]->setSharedNetworkName("level2");
test_subnets_[3]->setSharedNetworkName("level2");
// Store shared networks in the database.
for (auto network : test_networks_) {
cbptr_->createUpdateSharedNetwork4(ServerSelector::ALL(), network);
}
// Store subnets in the database.
for (auto subnet : test_subnets_) {
cbptr_->createUpdateSubnet4(ServerSelector::ALL(), subnet);
}
// Fetch all subnets belonging to shared network level1.
Subnet4Collection subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ALL(),
"level1");
ASSERT_EQ(1, subnets.size());
// Returned subnet should match test subnet #1.
EXPECT_EQ(test_subnets_[1]->toElement()->str(), subnets[0]->toElement()->str());
// All subnets should also be returned for explicitly specified server tag.
subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ONE("server1"), "level1");
ASSERT_EQ(1, subnets.size());
// Returned subnet should match test subnet #1.
EXPECT_EQ(test_subnets_[1]->toElement()->str(), subnets[0]->toElement()->str());
// Fetch all subnets belonging to shared network level2.
subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ALL(), "level2");
ASSERT_EQ(2, subnets.size());
// Verify the subnets. It is safe to assume the order in which they have
// been returned, because the SELECT statement orders by subnet id.
EXPECT_EQ(test_subnets_[2]->toElement()->str(), subnets[0]->toElement()->str());
EXPECT_EQ(test_subnets_[3]->toElement()->str(), subnets[1]->toElement()->str());
// All subnets should also be returned for explicitly specified server tag.
subnets = cbptr_->getSharedNetworkSubnets4(ServerSelector::ONE("server1"), "level2");
ASSERT_EQ(2, subnets.size());
EXPECT_EQ(test_subnets_[2]->toElement()->str(), subnets[0]->toElement()->str());
EXPECT_EQ(test_subnets_[3]->toElement()->str(), subnets[1]->toElement()->str());
}
// Test that shared network can be inserted, fetched, updated and then
// fetched again.
TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetwork4) {
......
......@@ -57,6 +57,16 @@ public:
virtual Subnet4Collection
getAllSubnets4(const db::ServerSelector& server_selector) const = 0;
/// @brief Retrieves all subnets belonging to a specified shared network.
///
/// @param server_selector Server selector.
/// @param shared_network_name Name of the shared network for which the
/// subnets should be retrieved.
/// @return Collection of subnets or empty collection if no subnet found.
virtual Subnet4Collection
getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
const std::string& shared_network_name) const = 0;
/// @brief Retrieves subnets modified after specified time.
///
/// @param server_selector Server selector.
......
......@@ -57,6 +57,17 @@ ConfigBackendPoolDHCPv4::getModifiedSubnets4(const BackendSelector& backend_sele
return (subnets);
}
Subnet4Collection
ConfigBackendPoolDHCPv4::getSharedNetworkSubnets4(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const std::string& shared_network_name) const {
Subnet4Collection subnets;
getMultiplePropertiesConst<Subnet4Collection, const std::string&>
(&ConfigBackendDHCPv4::getSharedNetworkSubnets4, backend_selector, server_selector,
subnets, shared_network_name);
return (subnets);
}
SharedNetwork4Ptr
ConfigBackendPoolDHCPv4::getSharedNetwork4(const BackendSelector& backend_selector,
const ServerSelector& server_selector,
......
......@@ -72,6 +72,18 @@ public:
const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves all subnets belonging to a specified shared network.
///
/// @param backend_selector Backend selector.
/// @param server_selector Server selector.
/// @param shared_network_name Name of the shared network for which the
/// subnets should be retrieved.
/// @return Collection of subnets or empty collection if no subnet found.
virtual Subnet4Collection
getSharedNetworkSubnets4(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const std::string& shared_network_name) const;
/// @brief Retrieves shared network by name.
///
/// @param backend_selector Backend selector.
......
......@@ -66,6 +66,31 @@ TestConfigBackendDHCPv4::getModifiedSubnets4(const db::ServerSelector& /* server
return (subnets);
}
Subnet4Collection
TestConfigBackendDHCPv4::getSharedNetworkSubnets4(const db::ServerSelector& /* server_selector */,
const std::string& shared_network_name) const {
Subnet4Collection subnets;
// Subnet collection does not include the index by shared network name.
// We need to iterate over the subnets and pick those that are associated
// with a shared network.
for (auto subnet = subnets_.begin(); subnet != subnets_.end();
++subnet) {
// The subnet can be associated with a shared network instance or
// it may just point to the shared network name. The former is
// the case when the subnet belongs to the server configuration.
// The latter is the case when the subnet is fetched from the
// database.
SharedNetwork4Ptr network;
(*subnet)->getSharedNetwork(network);
if (((network && (network->getName() == shared_network_name)) ||
((*subnet)->getSharedNetworkName() == shared_network_name))) {
subnets.push_back(*subnet);
}
}
return (subnets);
}
SharedNetwork4Ptr
TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& /* server_selector */,
const std::string& name) const {
......
......@@ -90,6 +90,16 @@ public:
getModifiedSubnets4(const db::ServerSelector& server_selector,
const boost::posix_time::ptime& modification_time) const;
/// @brief Retrieves all subnets belonging to a specified shared network.
///
/// @param server_selector Server selector.
/// @param shared_network_name Name of the shared network for which the
/// subnets should be retrieved.
/// @return Collection of subnets or empty collection if no subnet found.
virtual Subnet4Collection
getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
const std::string& shared_network_name) const;
/// @brief Retrieves shared network by name.
///
/// @param server_selector Server 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