blob: c521c9f10ecb47005bee683bb05625e666335c44 [file] [log] [blame]
Matthew Barth554ba472020-08-18 14:48:38 -05001/**
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 <nlohmann/json.hpp>
Anwaar Hadi64b5ac22025-04-04 23:54:53 +000019#include <phosphor-logging/lg2.hpp>
Matthew Barth554ba472020-08-18 14:48:38 -050020
Matthew Bartha3a8cc52021-01-15 12:40:25 -060021#include <vector>
22
Matthew Barth554ba472020-08-18 14:48:38 -050023namespace phosphor::fan::control::json
24{
25
26using json = nlohmann::json;
Matthew Barth554ba472020-08-18 14:48:38 -050027
Matthew Barthb584d812021-03-11 15:55:04 -060028using PropertyVariantType =
29 std::variant<bool, int32_t, int64_t, double, std::string>;
30
Matthew Barth554ba472020-08-18 14:48:38 -050031/**
Matthew Barth44ab7692021-03-26 11:40:10 -050032 * Configuration object key to uniquely map to the configuration object
33 * Pair constructed of:
34 * std::string = Configuration object's name
35 * std::vector<std::string> = List of profiles the configuration object
36 * is included in
37 */
38using configKey = std::pair<std::string, std::vector<std::string>>;
39
40/**
Matthew Barth554ba472020-08-18 14:48:38 -050041 * @class ConfigBase - Base configuration object
42 *
43 * Base class for fan control's JSON configuration objects.
44 */
45class ConfigBase
46{
47 public:
48 ConfigBase() = delete;
Matthew Barth554ba472020-08-18 14:48:38 -050049 ConfigBase(ConfigBase&&) = delete;
50 ConfigBase& operator=(const ConfigBase&) = delete;
51 ConfigBase& operator=(ConfigBase&&) = delete;
Mike Cappsb2e9a4f2022-06-13 10:15:42 -040052
Matthew Barth554ba472020-08-18 14:48:38 -050053 virtual ~ConfigBase() = default;
54
55 explicit ConfigBase(const json& jsonObj)
56 {
57 // Set the name of this configuration object
58 setName(jsonObj);
Matthew Barthbfd7e1b2021-02-04 14:25:47 -060059 if (jsonObj.contains("profiles"))
60 {
61 for (const auto& profile : jsonObj["profiles"])
62 {
63 _profiles.emplace_back(profile.get<std::string>());
64 }
65 }
Matthew Barth554ba472020-08-18 14:48:38 -050066 }
67
68 /**
Matthew Barthe5578602021-03-30 12:53:24 -050069 * Copy Constructor
70 * Creates a config base from another config base's originally parsed JSON
71 * object data
72 *
73 * @param[in] origObj - Original ConfigBase object to be created from
74 */
75 ConfigBase(const ConfigBase& origObj)
76 {
77 _name = origObj._name;
78 _profiles = origObj._profiles;
79 }
80
81 /**
Matthew Barth554ba472020-08-18 14:48:38 -050082 * @brief Get the configuration object's name
83 *
84 * @return Name of the configuration object
85 */
86 inline const std::string& getName() const
87 {
88 return _name;
89 }
90
Matthew Barthce957262020-08-27 10:35:57 -050091 /**
92 * @brief Get the configuration object's list of profiles
93 *
94 * Gets the list of profiles this configuration object belongs to if any
95 * are configured, otherwise an empty list of profiles results in the
96 * object always being included in the configuration.
97 *
98 * @return List of profiles the configuration object belongs to
99 */
100 inline const auto& getProfiles() const
101 {
102 return _profiles;
103 }
104
Matthew Barth9167c4d2020-08-24 13:17:43 -0500105 /**
106 * @brief Determines the data type of a JSON configured parameter that is
107 * used as a variant within the fan control application and returns the
108 * value as that variant.
109 * @details Retrieves a JSON object by the first derived data type that
110 * is not null. Expected data types should appear in a logical order of
111 * conversion. i.e.) uint and int could both be uint
112 *
113 * @param[in] object - A single JSON object
114 *
115 * @return A `PropertyVariantType` variant containing the JSON object's
116 * value
117 */
118 static const PropertyVariantType getJsonValue(const json& object)
119 {
120 if (auto boolPtr = object.get_ptr<const bool*>())
121 {
122 return *boolPtr;
123 }
124 if (auto intPtr = object.get_ptr<const int64_t*>())
125 {
126 return *intPtr;
127 }
128 if (auto doublePtr = object.get_ptr<const double*>())
129 {
130 return *doublePtr;
131 }
132 if (auto stringPtr = object.get_ptr<const std::string*>())
133 {
134 return *stringPtr;
135 }
136
Anwaar Hadi64b5ac22025-04-04 23:54:53 +0000137 lg2::error(
138 "Unsupported data type for JSON object's value. Supported Types are 'bool, int, double, string'",
139 "JSON_ENTRY", object.dump());
Matthew Barth9167c4d2020-08-24 13:17:43 -0500140 throw std::runtime_error(
141 "Unsupported data type for JSON object's value");
142 }
143
Matt Spinlerc2727902022-02-02 11:13:09 -0600144 protected:
Matthew Bartha3a8cc52021-01-15 12:40:25 -0600145 /* Name of the configuration object */
146 std::string _name;
147
Matthew Barthce957262020-08-27 10:35:57 -0500148 /**
149 * Profiles this configuration object belongs to (OPTIONAL).
150 * Otherwise always include this object in the configuration
151 * when no profiles are given
152 */
153 std::vector<std::string> _profiles;
154
Matthew Barth554ba472020-08-18 14:48:38 -0500155 private:
Matthew Barth554ba472020-08-18 14:48:38 -0500156 /**
157 * @brief Sets the configuration object's name from the given JSON
158 *
159 * @param[in] jsonObj - JSON to get configuration object's name from
160 */
161 inline void setName(const json& jsonObj)
162 {
163 if (!jsonObj.contains("name"))
164 {
165 // Log error on missing configuration object's name
Anwaar Hadi64b5ac22025-04-04 23:54:53 +0000166 lg2::error("Missing required configuration object's name", "JSON",
167 jsonObj.dump());
Matthew Barth554ba472020-08-18 14:48:38 -0500168 throw std::runtime_error(
169 "Missing required configuration object's name");
170 }
171 _name = jsonObj["name"].get<std::string>();
172 }
173};
174
175} // namespace phosphor::fan::control::json