fw: UnsolicitedDataPolicy::getPolicyNames

refs #2181

Change-Id: Ie2abcd7503d1079734e6386fbab37cadd186e07c
diff --git a/daemon/fw/unsolicited-data-policy.cpp b/daemon/fw/unsolicited-data-policy.cpp
index dd68e38..8cf59d9 100644
--- a/daemon/fw/unsolicited-data-policy.cpp
+++ b/daemon/fw/unsolicited-data-policy.cpp
@@ -24,6 +24,8 @@
  */
 
 #include "unsolicited-data-policy.hpp"
+#include <boost/range/adaptor/map.hpp>
+#include <boost/range/algorithm/copy.hpp>
 
 namespace nfd {
 namespace fw {
@@ -48,14 +50,24 @@
 }
 
 unique_ptr<UnsolicitedDataPolicy>
-UnsolicitedDataPolicy::create(const std::string& key)
+UnsolicitedDataPolicy::create(const std::string& policyName)
 {
   Registry& registry = getRegistry();
-  auto i = registry.find(key);
+  auto i = registry.find(policyName);
   return i == registry.end() ? nullptr : i->second();
 }
 
-NFD_REGISTER_UNSOLICITED_DATA_POLICY(DropAllUnsolicitedDataPolicy, "drop-all");
+std::set<std::string>
+UnsolicitedDataPolicy::getPolicyNames()
+{
+  std::set<std::string> policyNames;
+  boost::copy(getRegistry() | boost::adaptors::map_keys,
+              std::inserter(policyNames, policyNames.end()));
+  return policyNames;
+}
+
+const std::string DropAllUnsolicitedDataPolicy::POLICY_NAME("drop-all");
+NFD_REGISTER_UNSOLICITED_DATA_POLICY(DropAllUnsolicitedDataPolicy);
 
 UnsolicitedDataDecision
 DropAllUnsolicitedDataPolicy::decide(const Face& inFace, const Data& data) const
@@ -63,7 +75,8 @@
   return UnsolicitedDataDecision::DROP;
 }
 
-NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitLocalUnsolicitedDataPolicy, "admit-local");
+const std::string AdmitLocalUnsolicitedDataPolicy::POLICY_NAME("admit-local");
+NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitLocalUnsolicitedDataPolicy);
 
 UnsolicitedDataDecision
 AdmitLocalUnsolicitedDataPolicy::decide(const Face& inFace, const Data& data) const
@@ -74,7 +87,8 @@
   return UnsolicitedDataDecision::DROP;
 }
 
-NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitNetworkUnsolicitedDataPolicy, "admit-network");
+const std::string AdmitNetworkUnsolicitedDataPolicy::POLICY_NAME("admit-network");
+NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitNetworkUnsolicitedDataPolicy);
 
 UnsolicitedDataDecision
 AdmitNetworkUnsolicitedDataPolicy::decide(const Face& inFace, const Data& data) const
@@ -85,7 +99,8 @@
   return UnsolicitedDataDecision::DROP;
 }
 
-NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitAllUnsolicitedDataPolicy, "admit-all");
+const std::string AdmitAllUnsolicitedDataPolicy::POLICY_NAME("admit-all");
+NFD_REGISTER_UNSOLICITED_DATA_POLICY(AdmitAllUnsolicitedDataPolicy);
 
 UnsolicitedDataDecision
 AdmitAllUnsolicitedDataPolicy::decide(const Face& inFace, const Data& data) const
diff --git a/daemon/fw/unsolicited-data-policy.hpp b/daemon/fw/unsolicited-data-policy.hpp
index 62b64dc..a5f24d9 100644
--- a/daemon/fw/unsolicited-data-policy.hpp
+++ b/daemon/fw/unsolicited-data-policy.hpp
@@ -50,30 +50,37 @@
 class UnsolicitedDataPolicy : noncopyable
 {
 public:
-  virtual ~UnsolicitedDataPolicy() = default;
+  virtual
+  ~UnsolicitedDataPolicy() = default;
 
   virtual UnsolicitedDataDecision
   decide(const Face& inFace, const Data& data) const = 0;
 
 public: // registry
+  typedef std::function<unique_ptr<UnsolicitedDataPolicy>()> CreateFunc;
+  typedef std::map<std::string, CreateFunc> Registry; // indexed by policy name
+
   template<typename P>
   static void
-  registerPolicy(const std::string& key)
+  registerPolicy(const std::string& policyName = P::POLICY_NAME)
   {
     Registry& registry = getRegistry();
-    BOOST_ASSERT(registry.count(key) == 0);
-    registry[key] = [] { return make_unique<P>(); };
+    BOOST_ASSERT(registry.count(policyName) == 0);
+    registry[policyName] = [] { return make_unique<P>(); };
   }
 
-  /** \return an UnsolicitedDataPolicy identified by \p key, or nullptr if \p key is unknown
+  /** \return an UnsolicitedDataPolicy identified by \p policyName,
+   *          or nullptr if \p policyName is unknown
    */
   static unique_ptr<UnsolicitedDataPolicy>
-  create(const std::string& key);
+  create(const std::string& policyName);
+
+  /** \return a list of available policy names
+   */
+  static std::set<std::string>
+  getPolicyNames();
 
 private:
-  typedef std::function<unique_ptr<UnsolicitedDataPolicy>()> CreateFunc;
-  typedef std::map<std::string, CreateFunc> Registry; // indexed by key
-
   static Registry&
   getRegistry();
 };
@@ -83,8 +90,11 @@
 class DropAllUnsolicitedDataPolicy : public UnsolicitedDataPolicy
 {
 public:
-  virtual UnsolicitedDataDecision
+  UnsolicitedDataDecision
   decide(const Face& inFace, const Data& data) const final;
+
+public:
+  static const std::string POLICY_NAME;
 };
 
 /** \brief admits unsolicited Data from local faces
@@ -92,8 +102,11 @@
 class AdmitLocalUnsolicitedDataPolicy : public UnsolicitedDataPolicy
 {
 public:
-  virtual UnsolicitedDataDecision
+  UnsolicitedDataDecision
   decide(const Face& inFace, const Data& data) const final;
+
+public:
+  static const std::string POLICY_NAME;
 };
 
 /** \brief admits unsolicited Data from non-local faces
@@ -101,8 +114,11 @@
 class AdmitNetworkUnsolicitedDataPolicy : public UnsolicitedDataPolicy
 {
 public:
-  virtual UnsolicitedDataDecision
+  UnsolicitedDataDecision
   decide(const Face& inFace, const Data& data) const final;
+
+public:
+  static const std::string POLICY_NAME;
 };
 
 /** \brief admits all unsolicited Data
@@ -110,8 +126,11 @@
 class AdmitAllUnsolicitedDataPolicy : public UnsolicitedDataPolicy
 {
 public:
-  virtual UnsolicitedDataDecision
+  UnsolicitedDataDecision
   decide(const Face& inFace, const Data& data) const final;
+
+public:
+  static const std::string POLICY_NAME;
 };
 
 /** \brief the default UnsolicitedDataPolicy
@@ -122,16 +141,16 @@
 } // namespace nfd
 
 /** \brief registers an unsolicited data policy
- *  \param P a subclass of nfd::fw::UnsolicitedDataPolicy
- *  \param key the policy keyword, which is available for selection in NFD config file
+ *  \param P a subclass of nfd::fw::UnsolicitedDataPolicy;
+ *           P::POLICY_NAME must be a string that contains policy name
  */
-#define NFD_REGISTER_UNSOLICITED_DATA_POLICY(P, key)                \
+#define NFD_REGISTER_UNSOLICITED_DATA_POLICY(P)                     \
 static class NfdAuto ## P ## UnsolicitedDataPolicyRegistrationClass \
 {                                                                   \
 public:                                                             \
   NfdAuto ## P ## UnsolicitedDataPolicyRegistrationClass()          \
   {                                                                 \
-    ::nfd::fw::UnsolicitedDataPolicy::registerPolicy<P>(key);       \
+    ::nfd::fw::UnsolicitedDataPolicy::registerPolicy<P>();          \
   }                                                                 \
 } g_nfdAuto ## P ## UnsolicitedDataPolicyRegistrationVariable
 
diff --git a/tests/daemon/fw/unsolicited-data-policy.t.cpp b/tests/daemon/fw/unsolicited-data-policy.t.cpp
index fd6b020..71f19b2 100644
--- a/tests/daemon/fw/unsolicited-data-policy.t.cpp
+++ b/tests/daemon/fw/unsolicited-data-policy.t.cpp
@@ -84,6 +84,15 @@
 BOOST_AUTO_TEST_SUITE(Fw)
 BOOST_FIXTURE_TEST_SUITE(TestUnsolicitedDataPolicy, UnsolicitedDataPolicyFixture)
 
+BOOST_AUTO_TEST_CASE(GetPolicyNames)
+{
+  std::set<std::string> policyNames = UnsolicitedDataPolicy::getPolicyNames();
+  BOOST_CHECK_EQUAL(policyNames.count("drop-all"), 1);
+  BOOST_CHECK_EQUAL(policyNames.count("admit-local"), 1);
+  BOOST_CHECK_EQUAL(policyNames.count("admit-network"), 1);
+  BOOST_CHECK_EQUAL(policyNames.count("admit-all"), 1);
+}
+
 template<typename Policy, bool shouldAdmitLocal, bool shouldAdmitNonLocal>
 struct FaceScopePolicyTest
 {