Commit 194f7617 authored by Marcin Siodelski's avatar Marcin Siodelski

[#99,!176] Implemented test config backend for DHCPv4.

parent 7fbbfde2
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#define STAMPED_VALUE_H #define STAMPED_VALUE_H
#include <cc/stamped_element.h> #include <cc/stamped_element.h>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
...@@ -20,9 +24,6 @@ class StampedValue; ...@@ -20,9 +24,6 @@ class StampedValue;
/// @brief Pointer to the stamped value. /// @brief Pointer to the stamped value.
typedef boost::shared_ptr<StampedValue> StampedValuePtr; typedef boost::shared_ptr<StampedValue> StampedValuePtr;
/// @brief Collection of pointers to values.
typedef std::vector<StampedValuePtr> StampedValueCollection;
/// @brief This class represents string or signed integer configuration /// @brief This class represents string or signed integer configuration
/// element associated with the modification timestamp. /// element associated with the modification timestamp.
/// ///
...@@ -91,8 +92,43 @@ private: ...@@ -91,8 +92,43 @@ private:
std::string value_; std::string value_;
}; };
/// @brief Pointer to the stamped value. /// @name Definition of the multi index container for @c StampedValue.
typedef boost::shared_ptr<StampedValue> StampedValuePtr; ///
//@{
/// @brief Tag for the index for access by value name.
struct StampedValueNameIndexTag { };
/// @brief Tag for the index for access by modification time.
struct StampedValueModificationTimeIndexTag { };
/// @brief Multi index container for @c StampedValue.
typedef boost::multi_index_container<
StampedValuePtr,
boost::multi_index::indexed_by<
// Index used to access value by name.
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<StampedValueNameIndexTag>,
boost::multi_index::const_mem_fun<
StampedValue,
std::string,
&StampedValue::getName
>
>,
// Index used to access value by modification time.
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<StampedValueModificationTimeIndexTag>,
boost::multi_index::const_mem_fun<
StampedElement,
boost::posix_time::ptime,
&StampedElement::getModificationTime
>
>
>
> StampedValueCollection;
//@}
} // end of namespace isc::data } // end of namespace isc::data
} // end of namespace isc } // end of namespace isc
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp> #include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp> #include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp> #include <boost/multi_index_container.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
...@@ -811,6 +812,16 @@ typedef boost::multi_index_container< ...@@ -811,6 +812,16 @@ typedef boost::multi_index_container<
std::string, std::string,
&OptionDefinition::getName &OptionDefinition::getName
> >
>,
// Start definition of index #3
boost::multi_index::ordered_non_unique<
// Use option definition modification time as the index key.
// This value is returned by the StampedElement::getModificationTime
boost::multi_index::const_mem_fun<
data::StampedElement,
boost::posix_time::ptime,
&data::StampedElement::getModificationTime
>
> >
> >
> OptionDefContainer; > OptionDefContainer;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <dhcpsrv/key_from_key.h> #include <dhcpsrv/key_from_key.h>
#include <boost/multi_index_container.hpp> #include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp> #include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/mem_fun.hpp> #include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/member.hpp> #include <boost/multi_index/member.hpp>
...@@ -198,6 +199,15 @@ typedef boost::multi_index_container< ...@@ -198,6 +199,15 @@ typedef boost::multi_index_container<
bool, bool,
&OptionDescriptor::persistent_ &OptionDescriptor::persistent_
> >
>,
// Start definition of index #3.
// Use StampedElement::getModificationTime as a key.
boost::multi_index::ordered_non_unique<
boost::multi_index::const_mem_fun<
data::StampedElement,
boost::posix_time::ptime,
&data::StampedElement::getModificationTime
>
> >
> >
> OptionContainer; > OptionContainer;
...@@ -404,6 +414,31 @@ public: ...@@ -404,6 +414,31 @@ public:
return (*od_itr); return (*od_itr);
} }
/// @brief Deletes option for the specified key and option code.
///
/// The key should be a string, in which case it specifies an option space
/// name, or an uint32_t value, in which case it specifies a vendor
/// identifier.
///
/// @param key Option space name or vendor identifier.
/// @param option_code Code of the option to be returned.
/// @tparam Selector one of: @c std::string or @c uint32_t
///
/// @return Number of deleted options.
template<typename Selector>
size_t del(const Selector& key, const uint16_t option_code) {
// Check for presence of options.
OptionContainerPtr options = getAll(key);
if (!options || options->empty()) {
// There are no options, so there is nothing to do.
return (0);
}
// Some options present, locate the one we are interested in.
auto& idx = options->get<1>();
return (idx.erase(option_code));
}
/// @brief Returns a list of configured option space names. /// @brief Returns a list of configured option space names.
/// ///
/// The returned option space names exclude vendor option spaces, /// The returned option space names exclude vendor option spaces,
......
...@@ -34,6 +34,10 @@ struct SharedNetworkNameIndexTag { }; ...@@ -34,6 +34,10 @@ struct SharedNetworkNameIndexTag { };
/// @brief A tag for accessing index by server identifier. /// @brief A tag for accessing index by server identifier.
struct SharedNetworkServerIdIndexTag { }; struct SharedNetworkServerIdIndexTag { };
/// @brief Tag for the index for searching by shared network modification
/// time.
struct SharedNetworkModificationTimeIndexTag { };
/// @brief Shared network holding IPv4 subnets. /// @brief Shared network holding IPv4 subnets.
/// ///
/// Specialization of the @ref Network4 class for IPv4 shared networks. /// Specialization of the @ref Network4 class for IPv4 shared networks.
...@@ -188,8 +192,14 @@ typedef boost::multi_index_container< ...@@ -188,8 +192,14 @@ typedef boost::multi_index_container<
boost::multi_index::tag<SharedNetworkServerIdIndexTag>, boost::multi_index::tag<SharedNetworkServerIdIndexTag>,
boost::multi_index::const_mem_fun<Network4, asiolink::IOAddress, boost::multi_index::const_mem_fun<Network4, asiolink::IOAddress,
&Network4::getServerId> &Network4::getServerId>
>,
// Fourth index allows for searching using subnet modification time.
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<SharedNetworkModificationTimeIndexTag>,
boost::multi_index::const_mem_fun<data::StampedElement,
boost::posix_time::ptime,
&data::StampedElement::getModificationTime>
> >
> >
> SharedNetwork4Collection; > SharedNetwork4Collection;
...@@ -340,6 +350,13 @@ typedef boost::multi_index_container< ...@@ -340,6 +350,13 @@ typedef boost::multi_index_container<
boost::multi_index::tag<SharedNetworkNameIndexTag>, boost::multi_index::tag<SharedNetworkNameIndexTag>,
boost::multi_index::const_mem_fun<SharedNetwork6, std::string, boost::multi_index::const_mem_fun<SharedNetwork6, std::string,
&SharedNetwork6::getName> &SharedNetwork6::getName>
>,
// Third index allows for searching using subnet modification time.
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<SharedNetworkModificationTimeIndexTag>,
boost::multi_index::const_mem_fun<data::StampedElement,
boost::posix_time::ptime,
&data::StampedElement::getModificationTime>
> >
> >
> SharedNetwork6Collection; > SharedNetwork6Collection;
......
...@@ -744,6 +744,9 @@ struct SubnetPrefixIndexTag { }; ...@@ -744,6 +744,9 @@ struct SubnetPrefixIndexTag { };
/// @brief Tag for the index for searching by server identifier. /// @brief Tag for the index for searching by server identifier.
struct SubnetServerIdIndexTag { }; struct SubnetServerIdIndexTag { };
/// @brief Tag for the index for searching by subnet modification time.
struct SubnetModificationTimeIndexTag { };
/// @brief A collection of @c Subnet4 objects /// @brief A collection of @c Subnet4 objects
/// ///
/// This container provides a set of indexes which can be used to retrieve /// This container provides a set of indexes which can be used to retrieve
...@@ -788,11 +791,19 @@ typedef boost::multi_index_container< ...@@ -788,11 +791,19 @@ typedef boost::multi_index_container<
boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText> boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText>
>, >,
// Fourth index allows for searching using an output from getServerId // Fourth index allows for searching using an output from getServerId.
boost::multi_index::ordered_non_unique< boost::multi_index::ordered_non_unique<
boost::multi_index::tag<SubnetServerIdIndexTag>, boost::multi_index::tag<SubnetServerIdIndexTag>,
boost::multi_index::const_mem_fun<Network4, asiolink::IOAddress, boost::multi_index::const_mem_fun<Network4, asiolink::IOAddress,
&Network4::getServerId> &Network4::getServerId>
>,
// Fifth index allows for searching using subnet modification time.
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<SubnetModificationTimeIndexTag>,
boost::multi_index::const_mem_fun<data::StampedElement,
boost::posix_time::ptime,
&data::StampedElement::getModificationTime>
> >
> >
> Subnet4Collection; > Subnet4Collection;
...@@ -838,6 +849,13 @@ typedef boost::multi_index_container< ...@@ -838,6 +849,13 @@ typedef boost::multi_index_container<
boost::multi_index::ordered_unique< boost::multi_index::ordered_unique<
boost::multi_index::tag<SubnetPrefixIndexTag>, boost::multi_index::tag<SubnetPrefixIndexTag>,
boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText> boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText>
>,
// Fourth index allows for searching using subnet modification time.
boost::multi_index::ordered_non_unique<
boost::multi_index::tag<SubnetModificationTimeIndexTag>,
boost::multi_index::const_mem_fun<data::StampedElement,
boost::posix_time::ptime,
&data::StampedElement::getModificationTime>
> >
> >
> Subnet6Collection; > Subnet6Collection;
......
...@@ -9,13 +9,15 @@ ...@@ -9,13 +9,15 @@
#include <database/database_connection.h> #include <database/database_connection.h>
#include <test_config_backend_dhcp4.h> #include <test_config_backend_dhcp4.h>
using namespace isc::data;
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
namespace test { namespace test {
bool bool
TestConfigBackendDHCPv4::registerBackendType(ConfigBackendDHCPv4Mgr& mgr, TestConfigBackendDHCPv4::registerBackendType(ConfigBackendDHCPv4Mgr& mgr,
const std::string& db_type) { const std::string& db_type) {
return(mgr.registerBackendFactory(db_type, return(mgr.registerBackendFactory(db_type,
[](const db::DatabaseConnection::ParameterMap& params) [](const db::DatabaseConnection::ParameterMap& params)
-> dhcp::ConfigBackendDHCPv4Ptr { -> dhcp::ConfigBackendDHCPv4Ptr {
...@@ -26,54 +28,82 @@ TestConfigBackendDHCPv4::registerBackendType(ConfigBackendDHCPv4Mgr& mgr, ...@@ -26,54 +28,82 @@ TestConfigBackendDHCPv4::registerBackendType(ConfigBackendDHCPv4Mgr& mgr,
void void
TestConfigBackendDHCPv4::unregisterBackendType(ConfigBackendDHCPv4Mgr& mgr, TestConfigBackendDHCPv4::unregisterBackendType(ConfigBackendDHCPv4Mgr& mgr,
const std::string& db_type) { const std::string& db_type) {
mgr.unregisterBackendFactory(db_type); mgr.unregisterBackendFactory(db_type);
} }
Subnet4Ptr Subnet4Ptr
TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector */,
const std::string& /* subnet_prefix */) const{ const std::string& subnet_prefix) const{
return (Subnet4Ptr()); const auto& index = subnets_.get<SubnetPrefixIndexTag>();
auto subnet_it = index.find(subnet_prefix);
return ((subnet_it != index.cend()) ? (*subnet_it) : Subnet4Ptr());
} }
Subnet4Ptr Subnet4Ptr
TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& /* server_selector */,
const SubnetID& /* subnet_id */) const { const SubnetID& subnet_id) const {
return (Subnet4Ptr()); const auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
auto subnet_it = index.find(subnet_id);
return ((subnet_it != index.cend()) ? (*subnet_it) : Subnet4Ptr());
} }
Subnet4Collection Subnet4Collection
TestConfigBackendDHCPv4::getAllSubnets4(const db::ServerSelector& /* server_selector */) const { TestConfigBackendDHCPv4::getAllSubnets4(const db::ServerSelector& /* server_selector */) const {
return(subnets_); return (subnets_);
} }
Subnet4Collection Subnet4Collection
TestConfigBackendDHCPv4::getModifiedSubnets4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getModifiedSubnets4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const { const boost::posix_time::ptime& modification_time) const {
return(subnets_); const auto& index = subnets_.get<SubnetModificationTimeIndexTag>();
Subnet4Collection subnets;
auto lb = index.lower_bound(modification_time);
for (auto subnet = lb; subnet != index.end(); ++subnet) {
subnets.push_back(*subnet);
}
return (subnets);
} }
SharedNetwork4Ptr SharedNetwork4Ptr
TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& /* server_selector */,
const std::string& /* name */) const { const std::string& name) const {
return(SharedNetwork4Ptr()); const auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
auto network_it = index.find(name);
return ((network_it != index.cend()) ? (*network_it) : SharedNetwork4Ptr());
} }
SharedNetwork4Collection SharedNetwork4Collection
TestConfigBackendDHCPv4::getAllSharedNetworks4(const db::ServerSelector& /* server_selector */) const{ TestConfigBackendDHCPv4::getAllSharedNetworks4(const db::ServerSelector& /* server_selector */) const{
return(shared_networks_); return (shared_networks_);
} }
SharedNetwork4Collection SharedNetwork4Collection
TestConfigBackendDHCPv4::getModifiedSharedNetworks4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getModifiedSharedNetworks4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const { const boost::posix_time::ptime& modification_time) const {
return(shared_networks_); const auto& index = shared_networks_.get<SharedNetworkModificationTimeIndexTag>();
SharedNetwork4Collection shared_networks;
auto lb = index.lower_bound(modification_time);
for (auto shared_network = lb; shared_network != index.end(); ++shared_network) {
shared_networks.push_back(*shared_network);
}
return (shared_networks);
} }
OptionDefinitionPtr OptionDefinitionPtr
TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& /* server_selector */,
const uint16_t /* code */, const uint16_t code,
const std::string& /* space */) const { const std::string& space) const {
const auto& index = option_defs_.get<1>();
auto option_def_it_pair = index.equal_range(code);
for (auto option_def_it = option_def_it_pair.first;
option_def_it != option_def_it_pair.second;
++option_def_it) {
if ((*option_def_it)->getOptionSpaceName() == space) {
return (*option_def_it);
}
}
return (OptionDefinitionPtr()); return (OptionDefinitionPtr());
} }
...@@ -84,14 +114,30 @@ TestConfigBackendDHCPv4::getAllOptionDefs4(const db::ServerSelector& /* server_s ...@@ -84,14 +114,30 @@ TestConfigBackendDHCPv4::getAllOptionDefs4(const db::ServerSelector& /* server_s
OptionDefContainer OptionDefContainer
TestConfigBackendDHCPv4::getModifiedOptionDefs4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getModifiedOptionDefs4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const { const boost::posix_time::ptime& modification_time) const {
return (option_defs_); const auto& index = option_defs_.get<3>();
OptionDefContainer option_defs;
auto lb = index.lower_bound(modification_time);
for (auto option_def = lb; option_def != index.end(); ++option_def) {
option_defs.push_back(*option_def);
}
return (option_defs);
} }
OptionDescriptorPtr OptionDescriptorPtr
TestConfigBackendDHCPv4::getOption4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getOption4(const db::ServerSelector& /* server_selector */,
const uint16_t /* code */, const uint16_t code,
const std::string& /* space */) const { const std::string& space) const {
const auto& index = options_.get<1>();
auto option_it_pair = index.equal_range(code);
for (auto option_it = option_it_pair.first; option_it != option_it_pair.second;
++option_it) {
if (option_it->space_name_ == space) {
return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
}
}
return (OptionDescriptorPtr()); return (OptionDescriptorPtr());
} }
...@@ -102,153 +148,306 @@ TestConfigBackendDHCPv4::getAllOptions4(const db::ServerSelector& /* server_sele ...@@ -102,153 +148,306 @@ TestConfigBackendDHCPv4::getAllOptions4(const db::ServerSelector& /* server_sele
OptionContainer OptionContainer
TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const { const boost::posix_time::ptime& modification_time) const {
return (options_); const auto& index = options_.get<3>();
OptionContainer options;
auto lb = index.lower_bound(modification_time);
for (auto option = lb; option != index.end(); ++option) {
options.push_back(*option);
}
return (options);
} }
data::StampedValuePtr StampedValuePtr
TestConfigBackendDHCPv4::getGlobalParameter4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getGlobalParameter4(const db::ServerSelector& /* server_selector */,
const std::string& /* name */) const { const std::string& name) const {
return(data::StampedValuePtr()); const auto& index = globals_.get<StampedValueNameIndexTag>();
auto global_it = index.find(name);
return ((global_it != index.cend()) ? (*global_it) : StampedValuePtr());
} }
data::StampedValueCollection StampedValueCollection
TestConfigBackendDHCPv4::getAllGlobalParameters4(const db::ServerSelector& /* server_selector */) const { TestConfigBackendDHCPv4::getAllGlobalParameters4(const db::ServerSelector& /* server_selector */) const {
return (globals_); return (globals_);
} }
data::StampedValueCollection StampedValueCollection
TestConfigBackendDHCPv4::getModifiedGlobalParameters4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::getModifiedGlobalParameters4(const db::ServerSelector& /* server_selector */,
const boost::posix_time::ptime& /* modification_time */) const { const boost::posix_time::ptime& modification_time) const {
return (globals_); const auto& index = globals_.get<StampedValueModificationTimeIndexTag>();
StampedValueCollection globals;
auto lb = index.lower_bound(modification_time);
for (auto global = lb; global != index.end(); ++global) {
globals.insert(*global);
}
return (globals);
} }
void void
TestConfigBackendDHCPv4::createUpdateSubnet4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::createUpdateSubnet4(const db::ServerSelector& /* server_selector */,
const Subnet4Ptr& /* subnet */) { const Subnet4Ptr& subnet) {
auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
auto subnet_it = index.find(subnet->getID());
if (subnet_it != index.cend()) {
index.replace(subnet_it, subnet);
} else {
index.insert(subnet);
}
} }
void void
TestConfigBackendDHCPv4::createUpdateSharedNetwork4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::createUpdateSharedNetwork4(const db::ServerSelector& /* server_selector */,
const SharedNetwork4Ptr& /* shared_network */) { const SharedNetwork4Ptr& shared_network) {
auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
auto network_it = index.find(shared_network->getName());
if (network_it != index.cend()) {
index.replace(network_it, shared_network);
} else {
index.insert(shared_network);
}
} }
void void
TestConfigBackendDHCPv4::createUpdateOptionDef4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::createUpdateOptionDef4(const db::ServerSelector& /* server_selector */,
const OptionDefinitionPtr& /* option_def */) { const OptionDefinitionPtr& option_def) {
auto& index = option_defs_.get<1>();
auto option_def_it = index.find(option_def->getCode());
if (option_def_it != index.cend()) {
index.replace(option_def_it, option_def);
} else {
index.insert(option_def);
}
} }
void void
TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */, TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& /* server_selector */,
const OptionDescriptorPtr& /* option */) { const OptionDescriptorPtr& option) {
auto& index = options_.get<1>();
auto option_it = index.find(option->option_->getType());
if (option_it != index.end()) {
index.replace(option_it, *option);
} else {
index.insert(*option);
}
} }
void