add assignment or operator for multiple name suggestions
includes tests and config update

Change-Id: I4facf792d89c5ce34bc09f5495c45d0a3bab458a
diff --git a/src/name-assignments/assignment-or.cpp b/src/name-assignments/assignment-or.cpp
new file mode 100644
index 0000000..cd1f306
--- /dev/null
+++ b/src/name-assignments/assignment-or.cpp
@@ -0,0 +1,73 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#include <iosfwd>
+#include "assignment-or.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+_LOG_INIT(ndncert.assignment.or);
+
+NDNCERT_REGISTER_FUNCFACTORY(AssignmentOr, "or");
+
+AssignmentOr::AssignmentOr()
+    : NameAssignmentFuncFactory("or")
+{
+}
+
+NameAssignmentFunc
+AssignmentOr::getFunction(std::list<NameAssignmentFunc> funcs){
+    if (funcs.size() == 1) return *funcs.begin();
+    return OrAssignmentFunc(funcs);
+}
+
+NameAssignmentFunc
+AssignmentOr::getFunction(const std::string &factoryParam) {
+    std::list<NameAssignmentFunc> paramList;
+    std::stringstream ss;
+    ss << factoryParam;
+    JsonSection section;
+    try {
+        boost::property_tree::read_json(ss, section);
+    }
+    catch (const std::exception& error) {
+        BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Failed to parse configuration for name assignment function or, ") + error.what()));
+    }
+    if (section.begin() == section.end()) {
+        BOOST_THROW_EXCEPTION(std::runtime_error("No JSON configuration found for name assignment function"));
+    }
+    for (const auto& item: section) {
+        auto factory = NameAssignmentFuncFactory::createNameAssignmentFuncFactory(item.first);
+        if (!factory) {
+            BOOST_THROW_EXCEPTION(std::runtime_error("Invalid assignment factory type"));
+        }
+        try {
+            paramList.push_back(factory->getFunction(item.second.data()));
+        } catch (const std::exception& e) {
+            BOOST_THROW_EXCEPTION(std::runtime_error("Error on creating function"));
+        }
+    }
+
+    return getFunction(paramList);
+}
+
+AssignmentOr::OrAssignmentFunc::OrAssignmentFunc(std::list<NameAssignmentFunc> funcList)
+    : m_funcList(std::move(funcList))
+{}
+
+std::vector<PartialName>
+AssignmentOr::OrAssignmentFunc::operator() (const std::vector<std::tuple<std::string, std::string>> params)
+{
+  std::vector<PartialName> nameList;
+  for (const auto& func : m_funcList) {
+      auto result = func(params);
+      nameList.insert(nameList.end(), result.begin(), result.end());
+  }
+
+  return nameList;
+}
+
+}
+}
diff --git a/src/name-assignments/assignment-or.hpp b/src/name-assignments/assignment-or.hpp
new file mode 100644
index 0000000..68ffd66
--- /dev/null
+++ b/src/name-assignments/assignment-or.hpp
@@ -0,0 +1,40 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#ifndef NDNCERT_ASSIGNMENT_OR_HPP
+#define NDNCERT_ASSIGNMENT_OR_HPP
+
+#include "assignment-funcs.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+/**
+ * assign names base on client probe parameter
+ */
+class AssignmentOr: public NameAssignmentFuncFactory{
+public:
+  AssignmentOr();
+
+  NameAssignmentFunc getFunction(std::list<NameAssignmentFunc> funcs);
+
+  NameAssignmentFunc getFunction(const std::string &factoryParam) override;
+
+  class OrAssignmentFunc {
+  public:
+    OrAssignmentFunc(std::list<NameAssignmentFunc> funcList);
+
+    std::vector<PartialName>
+    operator() (const std::vector<std::tuple<std::string, std::string>> params);
+  private:
+    std::list<NameAssignmentFunc> m_funcList;
+  };
+
+};
+}
+}
+
+
+
+#endif //NDNCERT_ASSIGNMENT_OR_HPP