mgmt: Reinitialize multicast faces and partially reload config file on HUP signal

The following elements from the config file are reloaded:
- effective user/group
- log levels
- multicast faces (enable/disable)
- security

Change-Id: I6ddf124702b30610dd0404d8fbaa9a9d800f02bf
Refs: #1584
diff --git a/core/face-uri.hpp b/core/face-uri.hpp
index 94474c7..9173d8a 100644
--- a/core/face-uri.hpp
+++ b/core/face-uri.hpp
@@ -123,6 +123,15 @@
   std::string
   toString() const;
 
+public: // EqualityComparable concept
+  /// equality operator
+  bool
+  operator==(const FaceUri& rhs) const;
+
+  /// inequality operator
+  bool
+  operator!=(const FaceUri& rhs) const;
+
 private:
   std::string m_scheme;
   std::string m_host;
@@ -172,6 +181,22 @@
   return os.str();
 }
 
+inline bool
+FaceUri::operator==(const FaceUri& rhs) const
+{
+  return (m_scheme == rhs.m_scheme &&
+          m_host == rhs.m_host &&
+          m_isV6 == rhs.m_isV6 &&
+          m_port == rhs.m_port &&
+          m_path == rhs.m_path);
+}
+
+inline bool
+FaceUri::operator!=(const FaceUri& rhs) const
+{
+  return !(*this == rhs);
+}
+
 inline std::ostream&
 operator<<(std::ostream& os, const FaceUri& uri)
 {
diff --git a/core/logger-factory.cpp b/core/logger-factory.cpp
index 61ca866..b0ef3cd 100644
--- a/core/logger-factory.cpp
+++ b/core/logger-factory.cpp
@@ -87,6 +87,25 @@
                              level + "\"");
 }
 
+LogLevel
+LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
+{
+  std::string levelString;
+  try
+    {
+      levelString = item.get_value<std::string>();
+    }
+  catch (const boost::property_tree::ptree_error& error)
+    {
+    }
+
+  if (levelString.empty())
+    {
+      throw LoggerFactory::Error("No logging level found for option \"" + key + "\"");
+    }
+
+  return parseLevel(levelString);
+}
 
 void
 LoggerFactory::onConfig(const ConfigSection& section,
@@ -107,33 +126,29 @@
 //   Forwarder WARN
 // }
 
-  // std::cerr << "loading logging configuration" << std::endl;
+  if (!isDryRun)
+    {
+      ConfigSection::const_assoc_iterator item = section.find("default_level");
+      if (item != section.not_found())
+        {
+          LogLevel level = extractLevel(item->second, "default_level");
+          setDefaultLevel(level);
+        }
+      else
+        {
+          setDefaultLevel(LOG_INFO);
+        }
+    }
+
   for (ConfigSection::const_iterator item = section.begin();
        item != section.end();
        ++item)
     {
-      std::string levelString;
-      try
-        {
-          levelString = item->second.get_value<std::string>();
-        }
-      catch (const boost::property_tree::ptree_error& error)
-        {
-        }
-
-      if (levelString.empty())
-        {
-          throw LoggerFactory::Error("No logging level found for option \"" + item->first + "\"");
-        }
-
-      LogLevel level = parseLevel(levelString);
+      LogLevel level = extractLevel(item->second, item->first);
 
       if (item->first == "default_level")
         {
-          if (!isDryRun)
-            {
-              setDefaultLevel(level);
-            }
+          // do nothing
         }
       else
         {
diff --git a/core/logger-factory.hpp b/core/logger-factory.hpp
index b5aa31d..cbf7424 100644
--- a/core/logger-factory.hpp
+++ b/core/logger-factory.hpp
@@ -81,6 +81,9 @@
   LogLevel
   parseLevel(const std::string& level);
 
+  LogLevel
+  extractLevel(const ConfigSection& item, const std::string& key);
+
 private:
 
   typedef std::map<std::string, LogLevel> LevelMap;