presence: Policy generation framework
Add the framework necessary to construct the presence methods policy
specific to the type of policy to be applied against all methods. This
uses the policy type to index into a map of types-to-functions where the
function will return the pointer associated to the entry based on the
policy type.
Tested:
Supported redundancy policies produce no errors
Unsupported redundancy policies throw exception
Change-Id: I2805deb96a29828564b76bd66eb52032fdcf72f7
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/presence/json_config.cpp b/presence/json_config.cpp
index c758669..44a3075 100644
--- a/presence/json_config.cpp
+++ b/presence/json_config.cpp
@@ -22,6 +22,8 @@
#include "json_config.hpp"
#include "tach.hpp"
#include "gpio.hpp"
+#include "anyof.hpp"
+#include "fallback.hpp"
namespace phosphor
{
@@ -40,6 +42,11 @@
{"tach", method::getTach},
{"gpio", method::getGpio}
};
+const std::map<std::string, rpolicyHandler> JsonConfig::_rpolicies =
+{
+ {"anyof", rpolicy::getAnyof},
+ {"fallback", rpolicy::getFallback}
+};
JsonConfig::JsonConfig(const std::string& jsonFile)
{
@@ -79,21 +86,25 @@
void JsonConfig::process(const json& jsonConf)
{
+ // Set the expected number of fan entries
+ // to be size of the list of fan json config entries
+ // (Must be done to eliminate vector reallocation of fan references)
+ _fans.reserve(jsonConf.size());
for (auto& member : jsonConf)
{
if (!member.contains("name") || !member.contains("path") ||
- !member.contains("methods"))
+ !member.contains("methods") || !member.contains("rpolicy"))
{
log<level::ERR>(
"Missing required fan presence properties",
- entry("REQUIRED_PROPERTIES=%s", "{name, path, methods}"));
+ entry("REQUIRED_PROPERTIES=%s",
+ "{name, path, methods, rpolicy}"));
throw std::runtime_error(
"Missing required fan presence properties");
}
- // Create a fan object
- _fans.emplace_back(std::make_tuple(member["name"], member["path"]));
// Loop thru the configured methods of presence detection
+ std::vector<std::unique_ptr<PresenceSensor>> sensors;
for (auto& method : member["methods"].items())
{
if (!method.value().contains("type"))
@@ -113,10 +124,10 @@
if (func != _methods.end())
{
// Call function for method type
- auto sensor = func->second((_fans.size() - 1), method.value());
+ auto sensor = func->second(_fans.size(), method.value());
if (sensor)
{
- _sensors.emplace_back(std::move(sensor));
+ sensors.emplace_back(std::move(sensor));
}
}
else
@@ -128,6 +139,48 @@
throw std::runtime_error("Invalid fan presence method type");
}
}
+ auto fan = std::make_tuple(member["name"], member["path"]);
+ // Create a fan object
+ _fans.emplace_back(std::make_tuple(fan, std::move(sensors)));
+
+ // Add fan presence policy
+ addPolicy(member["rpolicy"]);
+ }
+}
+
+void JsonConfig::addPolicy(const json& rpolicy)
+{
+ if (!rpolicy.contains("type"))
+ {
+ log<level::ERR>("Missing required fan presence policy type",
+ entry("FAN_NAME=%s",
+ std::get<fanPolicyFanPos>(
+ std::get<Fan>(_fans.back())).c_str()),
+ entry("REQUIRED_PROPERTIES=%s", "{type}"));
+ throw std::runtime_error("Missing required fan presence policy type");
+ }
+
+ // The redundancy policy type for fan presence detection
+ // (Must have a supported function within the rpolicy namespace)
+ auto type = rpolicy["type"].get<std::string>();
+ std::transform(type.begin(), type.end(), type.begin(), tolower);
+ auto func = _rpolicies.find(type);
+ if (func != _rpolicies.end())
+ {
+ // Call function for redundancy policy type
+ auto policy = func->second(_fans.back());
+ if (policy)
+ {
+ _policies.emplace_back(std::move(policy));
+ }
+ }
+ else
+ {
+ log<level::ERR>("Invalid fan presence policy type",
+ entry("FAN_NAME=%s",
+ std::get<fanPolicyFanPos>(std::get<Fan>(_fans.back())).c_str()),
+ entry("RPOLICY_TYPE=%s", type.c_str()));
+ throw std::runtime_error("Invalid fan presence methods policy type");
}
}
@@ -183,6 +236,25 @@
} // namespace method
+/**
+ * Redundancy policies for fan presence detection function definitions
+ */
+namespace rpolicy
+{
+ // Get an `Anyof` redundancy policy for the fan
+ std::unique_ptr<RedundancyPolicy> getAnyof(const fanPolicy& fan)
+ {
+ return nullptr;
+ }
+
+ // Get a `Fallback` redundancy policy for the fan
+ std::unique_ptr<RedundancyPolicy> getFallback(const fanPolicy& fan)
+ {
+ return nullptr;
+ }
+
+} // namespace policy
+
} // namespace presence
} // namespace fan
} // namespace phosphor
diff --git a/presence/json_config.hpp b/presence/json_config.hpp
index c41b8d5..b027dba 100644
--- a/presence/json_config.hpp
+++ b/presence/json_config.hpp
@@ -19,9 +19,17 @@
using json = nlohmann::json;
using policies = std::vector<std::unique_ptr<RedundancyPolicy>>;
+
+constexpr auto fanPolicyFanPos = 0;
+constexpr auto fanPolicySensorListPos = 1;
+using fanPolicy = std::tuple<Fan, std::vector<std::unique_ptr<PresenceSensor>>>;
+
// Presence method handler function
using methodHandler = std::function<
std::unique_ptr<PresenceSensor>(size_t, const json&)>;
+// Presence redundancy policy handler function
+using rpolicyHandler = std::function<
+ std::unique_ptr<RedundancyPolicy>(const fanPolicy&)>;
class JsonConfig
{
@@ -55,13 +63,16 @@
static policies _policies;
/* List of Fan objects to have presence policies */
- std::vector<Fan> _fans;
+ std::vector<fanPolicy> _fans;
/* Presence methods mapping to their associated handler function */
static const std::map<std::string, methodHandler> _methods;
- /* List of fan presence sensors */
- std::vector<std::unique_ptr<PresenceSensor>> _sensors;
+ /**
+ * Presence redundancy policy mapping to their associated handler
+ * function
+ */
+ static const std::map<std::string, rpolicyHandler> _rpolicies;
/**
* @brief Process the json config to extract the defined fan presence
@@ -70,6 +81,13 @@
* @param[in] jsonConf - parsed json configuration data
*/
void process(const json& jsonConf);
+
+ /**
+ * @brief Add to the list of policies of presence detection
+ *
+ * @param[in] rpolicy - policy to add
+ */
+ void addPolicy(const json& rpolicy);
};
/**
@@ -101,6 +119,33 @@
} // namespace method
+/**
+ * Redundancy policies for fan presence detection function declarations
+ */
+namespace rpolicy
+{
+ /**
+ * @brief Create an `Anyof` redundancy policy on the created presence
+ * sensors for a fan
+ *
+ * @param[in] fan - fan policy object with the presence sensors for the fan
+ *
+ * @return - An `Anyof` redundancy policy
+ */
+ std::unique_ptr<RedundancyPolicy> getAnyof(const fanPolicy& fan);
+
+ /**
+ * @brief Create a `Fallback` redundancy policy on the created presence
+ * sensors for a fan
+ *
+ * @param[in] fan - fan policy object with the presence sensors for the fan
+ *
+ * @return - A `Fallback` redundancy policy
+ */
+ std::unique_ptr<RedundancyPolicy> getFallback(const fanPolicy& fan);
+
+} // namespace policy
+
} // namespace presence
} // namespace fan
} // namespace phosphor