summaryrefslogtreecommitdiffstats
path: root/entity_map_json.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'entity_map_json.cpp')
-rw-r--r--entity_map_json.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/entity_map_json.cpp b/entity_map_json.cpp
new file mode 100644
index 0000000..7b4e0bf
--- /dev/null
+++ b/entity_map_json.cpp
@@ -0,0 +1,119 @@
+#include "entity_map_json.hpp"
+
+#include <exception>
+#include <fstream>
+#include <ipmid/types.hpp>
+#include <memory>
+#include <nlohmann/json.hpp>
+#include <string>
+#include <utility>
+
+namespace ipmi
+{
+namespace sensor
+{
+
+EntityInfoMapContainer* EntityInfoMapContainer::getContainer()
+{
+ static std::unique_ptr<EntityInfoMapContainer> instance;
+
+ if (!instance)
+ {
+ /* TODO: With multi-threading this would all need to be locked so
+ * the first thread to hit it would set it up.
+ */
+ EntityInfoMap builtEntityMap = buildEntityMapFromFile();
+ instance = std::unique_ptr<EntityInfoMapContainer>(
+ new EntityInfoMapContainer(builtEntityMap));
+ }
+
+ return instance.get();
+}
+
+const EntityInfoMap& EntityInfoMapContainer::getIpmiEntityRecords()
+{
+ return entityRecords;
+}
+
+EntityInfoMap buildEntityMapFromFile()
+{
+ const char* entityMapJsonFilename =
+ "/usr/share/ipmi-providers/entity-map.json";
+ EntityInfoMap builtMap;
+
+ std::ifstream mapFile(entityMapJsonFilename);
+ if (!mapFile.is_open())
+ {
+ return builtMap;
+ }
+
+ auto data = nlohmann::json::parse(mapFile, nullptr, false);
+ if (data.is_discarded())
+ {
+ return builtMap;
+ }
+
+ return buildJsonEntityMap(data);
+}
+
+EntityInfoMap buildJsonEntityMap(const nlohmann::json& data)
+{
+ EntityInfoMap builtMap;
+
+ if (data.type() != nlohmann::json::value_t::array)
+ {
+ return builtMap;
+ }
+
+ try
+ {
+ for (const auto& entry : data)
+ {
+ /* It's an array entry with the following fields: id,
+ * containerEntityId, containerEntityInstance, isList, isLinked,
+ * entities[4]
+ */
+ EntityInfo obj;
+ Id recordId = entry.at("id").get<Id>();
+ obj.containerEntityId =
+ entry.at("containerEntityId").get<uint8_t>();
+ obj.containerEntityInstance =
+ entry.at("containerEntityInstance").get<uint8_t>();
+ obj.isList = entry.at("isList").get<bool>();
+ obj.isLinked = entry.at("isLinked").get<bool>();
+
+ auto jsonEntities = entry.at("entities");
+
+ if (jsonEntities.type() != nlohmann::json::value_t::array)
+ {
+ throw std::runtime_error(
+ "Invalid type for entities entry, must be array");
+ }
+ if (jsonEntities.size() != obj.containedEntities.size())
+ {
+ throw std::runtime_error(
+ "Entities must be in pairs of " +
+ std::to_string(obj.containedEntities.size()));
+ }
+
+ for (std::size_t i = 0; i < obj.containedEntities.size(); i++)
+ {
+ obj.containedEntities[i] = std::make_pair(
+ jsonEntities[i].at("id").get<uint8_t>(),
+ jsonEntities[i].at("instance").get<uint8_t>());
+ }
+
+ builtMap.insert({recordId, obj});
+ }
+ }
+ catch (const std::exception& e)
+ {
+ /* If any entry is invalid, the entire file cannot be trusted. */
+ builtMap.clear();
+ }
+
+ return builtMap;
+}
+
+} // namespace sensor
+} // namespace ipmi
OpenPOWER on IntegriCloud