add assignment or operator for multiple name suggestions
includes tests and config update
Change-Id: I4facf792d89c5ce34bc09f5495c45d0a3bab458a
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 5bad3bb..1386d13 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -23,6 +23,7 @@
#include <ndn-cxx/util/io.hpp>
#include <boost/filesystem.hpp>
#include <name-assignments/assignment-funcs.hpp>
+#include <name-assignments/assignment-or.hpp>
namespace ndn {
namespace ndncert {
@@ -152,7 +153,7 @@
m_nameAssignmentFunc = nullptr;
auto nameAssignmentItems = configJson.get_child_optional(CONFIG_NAME_ASSIGNMENT);
if (nameAssignmentItems) {
- std::vector<NameAssignmentFunc> funcs;
+ std::list<NameAssignmentFunc> funcs;
for (const auto item : *nameAssignmentItems) {
auto factory = NameAssignmentFuncFactory::createNameAssignmentFuncFactory(item.first);
if (!factory) {
@@ -167,10 +168,10 @@
if (funcs.size() < 1) {
BOOST_THROW_EXCEPTION(std::runtime_error("Empty assignment body supplied"));
} else if (funcs.size() == 1) {
- m_nameAssignmentFunc = funcs[0];
+ m_nameAssignmentFunc = *funcs.begin();
} else {
- //TODO "or" all the name function together as all suggestions
- m_nameAssignmentFunc = funcs[0];
+ AssignmentOr orFunction;
+ m_nameAssignmentFunc = orFunction.getFunction(funcs);
}
}
}
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
diff --git a/tests/unit-tests/config-files/config-ca-5 b/tests/unit-tests/config-files/config-ca-5
index 0d1e6b3..f867534 100644
--- a/tests/unit-tests/config-files/config-ca-5
+++ b/tests/unit-tests/config-files/config-ca-5
@@ -24,6 +24,8 @@
],
"name-assignment":
{
- "param": "/group/email"
+ "param": "/group/email",
+ "param": "/group/name",
+ "random": ""
}
}
\ No newline at end of file
diff --git a/tests/unit-tests/configuration.t.cpp b/tests/unit-tests/configuration.t.cpp
index 6ad1577..87de3f2 100644
--- a/tests/unit-tests/configuration.t.cpp
+++ b/tests/unit-tests/configuration.t.cpp
@@ -58,8 +58,10 @@
std::vector<std::tuple<std::string, std::string>> params;
params.emplace_back("email", "1@1.edu");
params.emplace_back("group", "irl");
- BOOST_CHECK_EQUAL(config.m_nameAssignmentFunc(params).size(), 1);
+ params.emplace_back("name", "ndncert");
+ BOOST_CHECK_EQUAL(config.m_nameAssignmentFunc(params).size(), 3);
BOOST_CHECK_EQUAL(config.m_nameAssignmentFunc(params)[0], Name("/irl/1@1.edu"));
+ BOOST_CHECK_EQUAL(config.m_nameAssignmentFunc(params)[1], Name("/irl/ndncert"));
}
BOOST_AUTO_TEST_CASE(CAConfigFileWithErrors)
diff --git a/tests/unit-tests/name-assignment.t.cpp b/tests/unit-tests/name-assignment.t.cpp
index 1fc7f6a..1e7dd0e 100644
--- a/tests/unit-tests/name-assignment.t.cpp
+++ b/tests/unit-tests/name-assignment.t.cpp
@@ -21,6 +21,7 @@
#include <name-assignments/assignment-random.hpp>
#include <name-assignments/assignment-param.hpp>
#include <name-assignments/assignment-hash.hpp>
+#include <name-assignments/assignment-or.hpp>
#include "test-common.hpp"
namespace ndn {
@@ -71,6 +72,40 @@
BOOST_CHECK_EQUAL(func(requirements).begin()->size(), 1);
}
+BOOST_AUTO_TEST_CASE(NameAssignmentOr)
+{
+ AssignmentParam paramAssignment;
+ AssignmentOr orAssignment;
+ std::list<NameAssignmentFunc> func2Subfuncs;
+ auto func1 = orAssignment.getFunction(func2Subfuncs);
+ BOOST_CHECK_EQUAL(func1(std::vector<std::tuple<std::string, std::string>>()).size(), 0);
+
+ auto funcUnit = paramAssignment.getFunction("/abc/xyz/");
+ func2Subfuncs.push_back(funcUnit);
+ func2Subfuncs.push_back(funcUnit);
+ auto func2 = orAssignment.getFunction(func2Subfuncs);
+ std::list<NameAssignmentFunc> func3Subfuncs;
+ func3Subfuncs.push_back(func2);
+ func3Subfuncs.push_back(funcUnit);
+ auto func3 = orAssignment.getFunction(func3Subfuncs);
+ std::vector<std::tuple<std::string, std::string>> requirements;
+ requirements.emplace_back("abc", "123");
+ BOOST_CHECK_EQUAL(func3(requirements).size(), 0);
+ requirements.emplace_back("xyz", "789");
+ BOOST_CHECK_EQUAL(func3(requirements).size(), 3);
+}
+
+BOOST_AUTO_TEST_CASE(NameAssignmentOrOperatorString)
+{
+ AssignmentOr orAssignment;
+ auto func = orAssignment.getFunction(R"({"param": "/abc/xyz/", "param": "/abc/xyz"})");
+ std::vector<std::tuple<std::string, std::string>> requirements;
+ requirements.emplace_back("abc", "123");
+ BOOST_CHECK_EQUAL(func(requirements).size(), 0);
+ requirements.emplace_back("xyz", "789");
+ BOOST_CHECK_EQUAL(func(requirements).size(), 2);
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests