1554ba472SMatthew Barth /** 2554ba472SMatthew Barth * Copyright © 2020 IBM Corporation 3554ba472SMatthew Barth * 4554ba472SMatthew Barth * Licensed under the Apache License, Version 2.0 (the "License"); 5554ba472SMatthew Barth * you may not use this file except in compliance with the License. 6554ba472SMatthew Barth * You may obtain a copy of the License at 7554ba472SMatthew Barth * 8554ba472SMatthew Barth * http://www.apache.org/licenses/LICENSE-2.0 9554ba472SMatthew Barth * 10554ba472SMatthew Barth * Unless required by applicable law or agreed to in writing, software 11554ba472SMatthew Barth * distributed under the License is distributed on an "AS IS" BASIS, 12554ba472SMatthew Barth * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13554ba472SMatthew Barth * See the License for the specific language governing permissions and 14554ba472SMatthew Barth * limitations under the License. 15554ba472SMatthew Barth */ 16554ba472SMatthew Barth #pragma once 17554ba472SMatthew Barth 18554ba472SMatthew Barth #include <nlohmann/json.hpp> 19554ba472SMatthew Barth #include <phosphor-logging/log.hpp> 20554ba472SMatthew Barth 21a3a8cc57SMatthew Barth #include <vector> 22a3a8cc57SMatthew Barth 23554ba472SMatthew Barth namespace phosphor::fan::control::json 24554ba472SMatthew Barth { 25554ba472SMatthew Barth 26554ba472SMatthew Barth using json = nlohmann::json; 27554ba472SMatthew Barth using namespace phosphor::logging; 28554ba472SMatthew Barth 29b584d818SMatthew Barth using PropertyVariantType = 30b584d818SMatthew Barth std::variant<bool, int32_t, int64_t, double, std::string>; 31b584d818SMatthew Barth 32554ba472SMatthew Barth /** 3344ab7693SMatthew Barth * Configuration object key to uniquely map to the configuration object 3444ab7693SMatthew Barth * Pair constructed of: 3544ab7693SMatthew Barth * std::string = Configuration object's name 3644ab7693SMatthew Barth * std::vector<std::string> = List of profiles the configuration object 3744ab7693SMatthew Barth * is included in 3844ab7693SMatthew Barth */ 3944ab7693SMatthew Barth using configKey = std::pair<std::string, std::vector<std::string>>; 4044ab7693SMatthew Barth 4144ab7693SMatthew Barth /** 42554ba472SMatthew Barth * @class ConfigBase - Base configuration object 43554ba472SMatthew Barth * 44554ba472SMatthew Barth * Base class for fan control's JSON configuration objects. 45554ba472SMatthew Barth */ 46554ba472SMatthew Barth class ConfigBase 47554ba472SMatthew Barth { 48554ba472SMatthew Barth public: 49554ba472SMatthew Barth ConfigBase() = delete; 50554ba472SMatthew Barth ConfigBase(ConfigBase&&) = delete; 51554ba472SMatthew Barth ConfigBase& operator=(const ConfigBase&) = delete; 52554ba472SMatthew Barth ConfigBase& operator=(ConfigBase&&) = delete; 53*b2e9a4fcSMike Capps 54554ba472SMatthew Barth virtual ~ConfigBase() = default; 55554ba472SMatthew Barth ConfigBase(const json & jsonObj)56554ba472SMatthew Barth explicit ConfigBase(const json& jsonObj) 57554ba472SMatthew Barth { 58554ba472SMatthew Barth // Set the name of this configuration object 59554ba472SMatthew Barth setName(jsonObj); 60bfd7e1b7SMatthew Barth if (jsonObj.contains("profiles")) 61bfd7e1b7SMatthew Barth { 62bfd7e1b7SMatthew Barth for (const auto& profile : jsonObj["profiles"]) 63bfd7e1b7SMatthew Barth { 64bfd7e1b7SMatthew Barth _profiles.emplace_back(profile.get<std::string>()); 65bfd7e1b7SMatthew Barth } 66bfd7e1b7SMatthew Barth } 67554ba472SMatthew Barth } 68554ba472SMatthew Barth 69554ba472SMatthew Barth /** 70e5578602SMatthew Barth * Copy Constructor 71e5578602SMatthew Barth * Creates a config base from another config base's originally parsed JSON 72e5578602SMatthew Barth * object data 73e5578602SMatthew Barth * 74e5578602SMatthew Barth * @param[in] origObj - Original ConfigBase object to be created from 75e5578602SMatthew Barth */ ConfigBase(const ConfigBase & origObj)76e5578602SMatthew Barth ConfigBase(const ConfigBase& origObj) 77e5578602SMatthew Barth { 78e5578602SMatthew Barth _name = origObj._name; 79e5578602SMatthew Barth _profiles = origObj._profiles; 80e5578602SMatthew Barth } 81e5578602SMatthew Barth 82e5578602SMatthew Barth /** 83554ba472SMatthew Barth * @brief Get the configuration object's name 84554ba472SMatthew Barth * 85554ba472SMatthew Barth * @return Name of the configuration object 86554ba472SMatthew Barth */ getName() const87554ba472SMatthew Barth inline const std::string& getName() const 88554ba472SMatthew Barth { 89554ba472SMatthew Barth return _name; 90554ba472SMatthew Barth } 91554ba472SMatthew Barth 92ce957268SMatthew Barth /** 93ce957268SMatthew Barth * @brief Get the configuration object's list of profiles 94ce957268SMatthew Barth * 95ce957268SMatthew Barth * Gets the list of profiles this configuration object belongs to if any 96ce957268SMatthew Barth * are configured, otherwise an empty list of profiles results in the 97ce957268SMatthew Barth * object always being included in the configuration. 98ce957268SMatthew Barth * 99ce957268SMatthew Barth * @return List of profiles the configuration object belongs to 100ce957268SMatthew Barth */ getProfiles() const101ce957268SMatthew Barth inline const auto& getProfiles() const 102ce957268SMatthew Barth { 103ce957268SMatthew Barth return _profiles; 104ce957268SMatthew Barth } 105ce957268SMatthew Barth 1069167c4d5SMatthew Barth /** 1079167c4d5SMatthew Barth * @brief Determines the data type of a JSON configured parameter that is 1089167c4d5SMatthew Barth * used as a variant within the fan control application and returns the 1099167c4d5SMatthew Barth * value as that variant. 1109167c4d5SMatthew Barth * @details Retrieves a JSON object by the first derived data type that 1119167c4d5SMatthew Barth * is not null. Expected data types should appear in a logical order of 1129167c4d5SMatthew Barth * conversion. i.e.) uint and int could both be uint 1139167c4d5SMatthew Barth * 1149167c4d5SMatthew Barth * @param[in] object - A single JSON object 1159167c4d5SMatthew Barth * 1169167c4d5SMatthew Barth * @return A `PropertyVariantType` variant containing the JSON object's 1179167c4d5SMatthew Barth * value 1189167c4d5SMatthew Barth */ getJsonValue(const json & object)1199167c4d5SMatthew Barth static const PropertyVariantType getJsonValue(const json& object) 1209167c4d5SMatthew Barth { 1219167c4d5SMatthew Barth if (auto boolPtr = object.get_ptr<const bool*>()) 1229167c4d5SMatthew Barth { 1239167c4d5SMatthew Barth return *boolPtr; 1249167c4d5SMatthew Barth } 1259167c4d5SMatthew Barth if (auto intPtr = object.get_ptr<const int64_t*>()) 1269167c4d5SMatthew Barth { 1279167c4d5SMatthew Barth return *intPtr; 1289167c4d5SMatthew Barth } 1299167c4d5SMatthew Barth if (auto doublePtr = object.get_ptr<const double*>()) 1309167c4d5SMatthew Barth { 1319167c4d5SMatthew Barth return *doublePtr; 1329167c4d5SMatthew Barth } 1339167c4d5SMatthew Barth if (auto stringPtr = object.get_ptr<const std::string*>()) 1349167c4d5SMatthew Barth { 1359167c4d5SMatthew Barth return *stringPtr; 1369167c4d5SMatthew Barth } 1379167c4d5SMatthew Barth 1389167c4d5SMatthew Barth log<level::ERR>( 1399167c4d5SMatthew Barth "Unsupported data type for JSON object's value", 1409167c4d5SMatthew Barth entry("JSON_ENTRY=%s", object.dump().c_str()), 1419167c4d5SMatthew Barth entry("SUPPORTED_TYPES=%s", "{bool, int, double, string}")); 1429167c4d5SMatthew Barth throw std::runtime_error( 1439167c4d5SMatthew Barth "Unsupported data type for JSON object's value"); 1449167c4d5SMatthew Barth } 1459167c4d5SMatthew Barth 146c272790aSMatt Spinler protected: 147a3a8cc57SMatthew Barth /* Name of the configuration object */ 148a3a8cc57SMatthew Barth std::string _name; 149a3a8cc57SMatthew Barth 150ce957268SMatthew Barth /** 151ce957268SMatthew Barth * Profiles this configuration object belongs to (OPTIONAL). 152ce957268SMatthew Barth * Otherwise always include this object in the configuration 153ce957268SMatthew Barth * when no profiles are given 154ce957268SMatthew Barth */ 155ce957268SMatthew Barth std::vector<std::string> _profiles; 156ce957268SMatthew Barth 157554ba472SMatthew Barth private: 158554ba472SMatthew Barth /** 159554ba472SMatthew Barth * @brief Sets the configuration object's name from the given JSON 160554ba472SMatthew Barth * 161554ba472SMatthew Barth * @param[in] jsonObj - JSON to get configuration object's name from 162554ba472SMatthew Barth */ setName(const json & jsonObj)163554ba472SMatthew Barth inline void setName(const json& jsonObj) 164554ba472SMatthew Barth { 165554ba472SMatthew Barth if (!jsonObj.contains("name")) 166554ba472SMatthew Barth { 167554ba472SMatthew Barth // Log error on missing configuration object's name 168554ba472SMatthew Barth log<level::ERR>("Missing required configuration object's name", 169554ba472SMatthew Barth entry("JSON=%s", jsonObj.dump().c_str())); 170554ba472SMatthew Barth throw std::runtime_error( 171554ba472SMatthew Barth "Missing required configuration object's name"); 172554ba472SMatthew Barth } 173554ba472SMatthew Barth _name = jsonObj["name"].get<std::string>(); 174554ba472SMatthew Barth } 175554ba472SMatthew Barth }; 176554ba472SMatthew Barth 177554ba472SMatthew Barth } // namespace phosphor::fan::control::json 178