1 /** 2 * Copyright © 2020 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "types.hpp" 19 20 #include <nlohmann/json.hpp> 21 #include <phosphor-logging/log.hpp> 22 23 namespace phosphor::fan::control::json 24 { 25 26 using json = nlohmann::json; 27 using namespace phosphor::logging; 28 29 /** 30 * @class ConfigBase - Base configuration object 31 * 32 * Base class for fan control's JSON configuration objects. 33 */ 34 class ConfigBase 35 { 36 public: 37 ConfigBase() = delete; 38 ConfigBase(const ConfigBase&) = delete; 39 ConfigBase(ConfigBase&&) = delete; 40 ConfigBase& operator=(const ConfigBase&) = delete; 41 ConfigBase& operator=(ConfigBase&&) = delete; 42 virtual ~ConfigBase() = default; 43 44 explicit ConfigBase(const json& jsonObj) 45 { 46 // Set the name of this configuration object 47 setName(jsonObj); 48 } 49 50 /** 51 * @brief Get the configuration object's name 52 * 53 * @return Name of the configuration object 54 */ 55 inline const std::string& getName() const 56 { 57 return _name; 58 } 59 60 /** 61 * @brief Get the configuration object's list of profiles 62 * 63 * Gets the list of profiles this configuration object belongs to if any 64 * are configured, otherwise an empty list of profiles results in the 65 * object always being included in the configuration. 66 * 67 * @return List of profiles the configuration object belongs to 68 */ 69 inline const auto& getProfiles() const 70 { 71 return _profiles; 72 } 73 74 protected: 75 /** 76 * @brief Determines the data type of a JSON configured parameter that is 77 * used as a variant within the fan control application and returns the 78 * value as that variant. 79 * @details Retrieves a JSON object by the first derived data type that 80 * is not null. Expected data types should appear in a logical order of 81 * conversion. i.e.) uint and int could both be uint 82 * 83 * @param[in] object - A single JSON object 84 * 85 * @return A `PropertyVariantType` variant containing the JSON object's 86 * value 87 */ 88 static const PropertyVariantType getJsonValue(const json& object) 89 { 90 if (auto boolPtr = object.get_ptr<const bool*>()) 91 { 92 return *boolPtr; 93 } 94 if (auto intPtr = object.get_ptr<const int64_t*>()) 95 { 96 return *intPtr; 97 } 98 if (auto doublePtr = object.get_ptr<const double*>()) 99 { 100 return *doublePtr; 101 } 102 if (auto stringPtr = object.get_ptr<const std::string*>()) 103 { 104 return *stringPtr; 105 } 106 107 log<level::ERR>( 108 "Unsupported data type for JSON object's value", 109 entry("JSON_ENTRY=%s", object.dump().c_str()), 110 entry("SUPPORTED_TYPES=%s", "{bool, int, double, string}")); 111 throw std::runtime_error( 112 "Unsupported data type for JSON object's value"); 113 } 114 115 /** 116 * Profiles this configuration object belongs to (OPTIONAL). 117 * Otherwise always include this object in the configuration 118 * when no profiles are given 119 */ 120 std::vector<std::string> _profiles; 121 122 private: 123 /* Name of the configuration object */ 124 std::string _name; 125 126 /** 127 * @brief Sets the configuration object's name from the given JSON 128 * 129 * @param[in] jsonObj - JSON to get configuration object's name from 130 */ 131 inline void setName(const json& jsonObj) 132 { 133 if (!jsonObj.contains("name")) 134 { 135 // Log error on missing configuration object's name 136 log<level::ERR>("Missing required configuration object's name", 137 entry("JSON=%s", jsonObj.dump().c_str())); 138 throw std::runtime_error( 139 "Missing required configuration object's name"); 140 } 141 _name = jsonObj["name"].get<std::string>(); 142 } 143 }; 144 145 } // namespace phosphor::fan::control::json 146