Commit bb8fe679 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

added isc::data::merge(element, element), that merges the values in the second...

added isc::data::merge(element, element), that merges the values in the second mapelement into the first (copies the pointers that are present in the second element, and removes from a the values that are empty pointers in the second)

the ElementPtr passed to the module's config handler now only contains the data that has actually changed (settings that are the same as before are removed from what is passed to the config handler)


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1041 e5f2f494-b856-4b98-b285-d166d9295462
parent 2f66bfbe
...@@ -128,10 +128,8 @@ AuthSrv::processMessage() { ...@@ -128,10 +128,8 @@ AuthSrv::processMessage() {
void void
AuthSrv::setDbFile(const std::string& db_file) AuthSrv::setDbFile(const std::string& db_file)
{ {
if (_db_file != db_file) { cout << "Change data source file, call our data source's function to now read " << db_file << endl;
cout << "Change data source file, call our data source's function to now read " << db_file << endl; _db_file = db_file;
_db_file = db_file;
}
} }
ElementPtr ElementPtr
...@@ -140,9 +138,7 @@ AuthSrv::updateConfig(isc::data::ElementPtr new_config) { ...@@ -140,9 +138,7 @@ AuthSrv::updateConfig(isc::data::ElementPtr new_config) {
// the ModuleCCSession has already checked if we have // the ModuleCCSession has already checked if we have
// the correct ElementPtr type as specified in our .spec file // the correct ElementPtr type as specified in our .spec file
if (new_config->contains("database_file")) { if (new_config->contains("database_file")) {
// Since we also get this value if it hasn't changed, // We only get this if the value has actually changed.
// but is non-default, setDbFile here should only really
// do anything if it has actually changed
setDbFile(new_config->get("database_file")->stringValue()); setDbFile(new_config->get("database_file")->stringValue());
} }
} }
......
...@@ -1005,21 +1005,40 @@ isc::data::isNull(ElementPtr p) ...@@ -1005,21 +1005,40 @@ isc::data::isNull(ElementPtr p)
void void
isc::data::removeIdentical(ElementPtr a, const ElementPtr b) isc::data::removeIdentical(ElementPtr a, const ElementPtr b)
{ {
if (!b) {
return;
}
if (a->getType() != Element::map || b->getType() != Element::map) { if (a->getType() != Element::map || b->getType() != Element::map) {
dns_throw(TypeError, "Non-map Elements passed to removeIdentical"); dns_throw(TypeError, "Non-map Elements passed to removeIdentical");
} }
std::cout<<"[XX] removeidentical from " << a << " and " << b << std::endl;
std::map<std::string, ElementPtr> m = a->mapValue(); std::map<std::string, ElementPtr> m = a->mapValue();
for (std::map<std::string, ElementPtr>::iterator it = m.begin() ; for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
it != m.end() ; ++it) { it != m.end() ; ++it) {
if (b->contains((*it).first)) { if (b->contains((*it).first)) {
if (a->get((*it).first)->equals(b->get((*it).first))) { if (a->get((*it).first)->equals(b->get((*it).first))) {
std::cout<<"[XX] remove " << (*it).first << std::endl;
a->remove((*it).first); a->remove((*it).first);
} }
} }
} }
std::cout<<"[XX] a now " << a << std::endl; }
void
isc::data::merge(ElementPtr element, const ElementPtr other)
{
if (element->getType() != Element::map ||
other->getType() != Element::map) {
dns_throw(TypeError, "merge arguments not MapElements");
}
std::map<std::string, ElementPtr> m = other->mapValue();
for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
it != m.end() ; ++it) {
if ((*it).second) {
element->set((*it).first, (*it).second);
} else if (element->contains((*it).first)) {
element->remove((*it).first);
}
}
} }
...@@ -455,13 +455,23 @@ bool isNull(ElementPtr p); ...@@ -455,13 +455,23 @@ bool isNull(ElementPtr p);
/// ///
/// \brief Remove all values from the first ElementPtr that are /// \brief Remove all values from the first ElementPtr that are
/// also present in the second. Both ElementPtrs MUST be MapElements /// equal in the second. Both ElementPtrs MUST be MapElements
/// The use for this function is to end up with a MapElement that /// The use for this function is to end up with a MapElement that
/// only contains new and changed values (for ModuleCCSession and /// only contains new and changed values (for ModuleCCSession and
/// configuration update handlers) /// configuration update handlers)
/// Raises a TypeError if a or b are not MapElements /// Raises a TypeError if a or b are not MapElements
void removeIdentical(ElementPtr a, const ElementPtr b); void removeIdentical(ElementPtr a, const ElementPtr b);
/// \brief Merges the data from other into element.
/// (on the first level). Both elements must be
/// MapElements.
/// Every string,value pair in other is copied into element
/// (the ElementPtr of value is copied, this is not a new object)
/// Unless the value is an empty ElementPtr, in which case the
/// whole key is removed from element.
/// Raises a TypeError if either ElementPtr is not a MapElement
void merge(ElementPtr element, const ElementPtr other);
} } } }
/// ///
......
...@@ -380,3 +380,35 @@ TEST(Element, removeIdentical) { ...@@ -380,3 +380,35 @@ TEST(Element, removeIdentical) {
removeIdentical(a, b); removeIdentical(a, b);
EXPECT_TRUE(a == c); EXPECT_TRUE(a == c);
} }
TEST(Element, merge)
{
ElementPtr a = Element::createFromString("{}");
ElementPtr b = Element::createFromString("{}");
ElementPtr c = Element::createFromString("{}");
merge(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("1");
b = Element::createFromString("{}");
EXPECT_THROW(merge(a, b), TypeError);
a = Element::createFromString("{}");
b = Element::createFromString("{ \"a\": 1 }");
c = Element::createFromString("{ \"a\": 1 }");
merge(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": 1 }");
b = Element::createFromString("{ \"a\": 2 }");
c = Element::createFromString("{ \"a\": 2 }");
merge(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
b = Element::createFromString("{ \"a\": { \"b\": \"d\" } }");
c = Element::createFromString("{ \"a\": { \"b\": \"d\" } }");
merge(a, b);
EXPECT_TRUE(a == c);
}
...@@ -189,7 +189,8 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name, ...@@ -189,7 +189,8 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name,
ElementPtr spec_msg = createCommand("module_spec", module_specification_.getFullSpec()); ElementPtr spec_msg = createCommand("module_spec", module_specification_.getFullSpec());
session_.group_sendmsg(spec_msg, "ConfigManager"); session_.group_sendmsg(spec_msg, "ConfigManager");
session_.group_recvmsg(env, answer, false); session_.group_recvmsg(env, answer, false);
config_ = Element::createFromString("{}");
// get any stored configuration from the manager // get any stored configuration from the manager
if (config_handler_) { if (config_handler_) {
ElementPtr cmd = Element::createFromString("{ \"command\": [\"get_config\", {\"module_name\":\"" + module_name_ + "\"} ] }"); ElementPtr cmd = Element::createFromString("{ \"command\": [\"get_config\", {\"module_name\":\"" + module_name_ + "\"} ] }");
...@@ -202,7 +203,7 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name, ...@@ -202,7 +203,7 @@ ModuleCCSession::ModuleCCSession(std::string spec_file_name,
} }
/// Validates the new config values, if they are correct, /// Validates the new config values, if they are correct,
/// call the config handler /// call the config handler with the values that have changed
/// If that results in success, store the new config /// If that results in success, store the new config
ElementPtr ElementPtr
ModuleCCSession::handleConfigUpdate(ElementPtr new_config) ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
...@@ -220,13 +221,15 @@ ModuleCCSession::handleConfigUpdate(ElementPtr new_config) ...@@ -220,13 +221,15 @@ ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
} }
answer = createAnswer(2, ss.str()); answer = createAnswer(2, ss.str());
} else { } else {
// remove the values that have not changed
isc::data::removeIdentical(new_config, getConfig());
// handle config update // handle config update
std::cout << "handleConfigUpdate " << new_config << std::endl; std::cout << "handleConfigUpdate " << new_config << std::endl;
answer = config_handler_(new_config); answer = config_handler_(new_config);
int rcode; int rcode;
parseAnswer(rcode, answer); parseAnswer(rcode, answer);
if (rcode == 0) { if (rcode == 0) {
config_ = new_config; isc::data::merge(config_, new_config);
} }
} }
std::cout << "end handleConfigUpdate " << new_config << std::endl; std::cout << "end handleConfigUpdate " << new_config << std::endl;
......
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