Patrick Venture | 02e3237 | 2019-08-16 10:50:18 -0700 | [diff] [blame] | 1 | #include "entity_map_json.hpp" |
| 2 | |
| 3 | #include <exception> |
Patrick Venture | c2b7fc1 | 2019-08-19 11:53:22 -0700 | [diff] [blame^] | 4 | #include <fstream> |
Patrick Venture | 02e3237 | 2019-08-16 10:50:18 -0700 | [diff] [blame] | 5 | #include <ipmid/types.hpp> |
| 6 | #include <nlohmann/json.hpp> |
| 7 | #include <string> |
| 8 | #include <utility> |
| 9 | |
| 10 | namespace ipmi |
| 11 | { |
| 12 | namespace sensor |
| 13 | { |
| 14 | |
Patrick Venture | c2b7fc1 | 2019-08-19 11:53:22 -0700 | [diff] [blame^] | 15 | EntityInfoMap buildEntityMapFromFile() |
| 16 | { |
| 17 | const char* entityMapJsonFilename = |
| 18 | "/usr/share/ipmi-providers/entity-map.json"; |
| 19 | EntityInfoMap builtMap; |
| 20 | |
| 21 | std::ifstream mapFile(entityMapJsonFilename); |
| 22 | if (!mapFile.is_open()) |
| 23 | { |
| 24 | return builtMap; |
| 25 | } |
| 26 | |
| 27 | auto data = nlohmann::json::parse(mapFile, nullptr, false); |
| 28 | if (data.is_discarded()) |
| 29 | { |
| 30 | return builtMap; |
| 31 | } |
| 32 | |
| 33 | return buildJsonEntityMap(data); |
| 34 | } |
| 35 | |
Patrick Venture | 02e3237 | 2019-08-16 10:50:18 -0700 | [diff] [blame] | 36 | EntityInfoMap buildJsonEntityMap(const nlohmann::json& data) |
| 37 | { |
| 38 | EntityInfoMap builtMap; |
| 39 | |
| 40 | if (data.type() != nlohmann::json::value_t::array) |
| 41 | { |
| 42 | return builtMap; |
| 43 | } |
| 44 | |
| 45 | try |
| 46 | { |
| 47 | for (const auto& entry : data) |
| 48 | { |
| 49 | /* It's an array entry with the following fields: id, |
| 50 | * containerEntityId, containerEntityInstance, isList, isLinked, |
| 51 | * entities[4] |
| 52 | */ |
| 53 | EntityInfo obj; |
| 54 | Id recordId = entry.at("id").get<Id>(); |
| 55 | obj.containerEntityId = |
| 56 | entry.at("containerEntityId").get<uint8_t>(); |
| 57 | obj.containerEntityInstance = |
| 58 | entry.at("containerEntityInstance").get<uint8_t>(); |
| 59 | obj.isList = entry.at("isList").get<bool>(); |
| 60 | obj.isLinked = entry.at("isLinked").get<bool>(); |
| 61 | |
| 62 | auto jsonEntities = entry.at("entities"); |
| 63 | |
| 64 | if (jsonEntities.type() != nlohmann::json::value_t::array) |
| 65 | { |
| 66 | throw std::runtime_error( |
| 67 | "Invalid type for entities entry, must be array"); |
| 68 | } |
| 69 | if (jsonEntities.size() != obj.containedEntities.size()) |
| 70 | { |
| 71 | throw std::runtime_error( |
| 72 | "Entities must be in pairs of " + |
| 73 | std::to_string(obj.containedEntities.size())); |
| 74 | } |
| 75 | |
| 76 | for (std::size_t i = 0; i < obj.containedEntities.size(); i++) |
| 77 | { |
| 78 | obj.containedEntities[i] = std::make_pair( |
| 79 | jsonEntities[i].at("id").get<uint8_t>(), |
| 80 | jsonEntities[i].at("instance").get<uint8_t>()); |
| 81 | } |
| 82 | |
| 83 | builtMap.insert({recordId, obj}); |
| 84 | } |
| 85 | } |
| 86 | catch (const std::exception& e) |
| 87 | { |
| 88 | /* If any entry is invalid, the entire file cannot be trusted. */ |
| 89 | builtMap.clear(); |
| 90 | } |
| 91 | |
| 92 | return builtMap; |
| 93 | } |
| 94 | |
| 95 | } // namespace sensor |
| 96 | } // namespace ipmi |