blob: 7fec5814352a9f2a744e69dc116e799114b974ad [file] [log] [blame]
Matthew Barth3174e722020-09-15 15:13:40 -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#include "event.hpp"
17
Matthew Barth391ade02021-01-15 14:33:21 -060018#include "group.hpp"
Matthew Barth391ade02021-01-15 14:33:21 -060019
Matthew Barth3174e722020-09-15 15:13:40 -050020#include <nlohmann/json.hpp>
21#include <phosphor-logging/log.hpp>
22#include <sdbusplus/bus.hpp>
23
Matthew Barth12bae962021-01-15 16:18:11 -060024#include <optional>
25#include <tuple>
26
Matthew Barth3174e722020-09-15 15:13:40 -050027namespace phosphor::fan::control::json
28{
29
30using json = nlohmann::json;
31using namespace phosphor::logging;
32
Matthew Barth44ab7692021-03-26 11:40:10 -050033Event::Event(const json& jsonObj, sdbusplus::bus::bus& bus,
34 std::map<configKey, std::unique_ptr<Group>>& groups) :
35 ConfigBase(jsonObj),
36 _bus(bus)
Matthew Barth3174e722020-09-15 15:13:40 -050037{
Matthew Barth3174e722020-09-15 15:13:40 -050038 // Event could have a precondition
39 if (!jsonObj.contains("precondition"))
40 {
41 // Event groups are optional
42 if (jsonObj.contains("groups"))
43 {
Matthew Barth44ab7692021-03-26 11:40:10 -050044 setGroups(jsonObj, groups);
Matthew Barth3174e722020-09-15 15:13:40 -050045 }
46 setTriggers(jsonObj);
47 // Event actions are optional
48 if (jsonObj.contains("actions"))
49 {
50 setActions(jsonObj);
51 }
52 }
53 else
54 {
Matthew Barth44ab7692021-03-26 11:40:10 -050055 setPrecond(jsonObj, groups);
Matthew Barth3174e722020-09-15 15:13:40 -050056 }
57}
58
Matthew Barth44ab7692021-03-26 11:40:10 -050059void Event::setPrecond(const json& jsonObj,
60 std::map<configKey, std::unique_ptr<Group>>& groups)
Matthew Barth3174e722020-09-15 15:13:40 -050061{
62 const auto& precond = jsonObj["precondition"];
63 if (!precond.contains("name") || !precond.contains("groups") ||
64 !precond.contains("triggers") || !precond.contains("events"))
65 {
66 log<level::ERR>("Missing required event precondition attributes",
67 entry("JSON=%s", precond.dump().c_str()));
68 throw std::runtime_error(
69 "Missing required event precondition attributes");
70 }
Matthew Barth44ab7692021-03-26 11:40:10 -050071 setGroups(precond, groups);
Matthew Barth3174e722020-09-15 15:13:40 -050072 setTriggers(precond);
73}
74
Matthew Barth44ab7692021-03-26 11:40:10 -050075void Event::setGroups(const json& jsonObj,
76 std::map<configKey, std::unique_ptr<Group>>& groups)
Matthew Barth3174e722020-09-15 15:13:40 -050077{
78 for (const auto& group : jsonObj["groups"])
79 {
80 if (!group.contains("name") || !group.contains("interface") ||
Matthew Barth12bae962021-01-15 16:18:11 -060081 !group.contains("property") || !group["property"].contains("name"))
Matthew Barth3174e722020-09-15 15:13:40 -050082 {
83 log<level::ERR>("Missing required event group attributes",
84 entry("JSON=%s", group.dump().c_str()));
85 throw std::runtime_error("Missing required event group attributes");
86 }
Matthew Barth12bae962021-01-15 16:18:11 -060087
88 // Get the group memebers' data type
89 std::optional<std::string> type = std::nullopt;
90 if (group["property"].contains("type"))
91 {
92 type = group["property"]["type"].get<std::string>();
93 }
94
95 // Get the group memebers' expected value
96 std::optional<PropertyVariantType> value = std::nullopt;
97 if (group["property"].contains("value"))
98 {
99 value = getJsonValue(group["property"]["value"]);
100 }
101
102 // Groups with the same profiles as the event can be used
103 configKey key =
104 std::make_pair(group["name"].get<std::string>(), _profiles);
Matthew Barth44ab7692021-03-26 11:40:10 -0500105 auto grpEntry = groups.find(key);
106 if (grpEntry != groups.end())
Matthew Barth12bae962021-01-15 16:18:11 -0600107 {
108 eGroup grp;
109 for (const auto& member : grpEntry->second->getMembers())
110 {
111 grp.emplace_back(std::make_tuple(
112 member, group["interface"].get<std::string>(),
113 group["property"]["name"].get<std::string>(), type, value));
114 }
115 _groups.emplace_back(grp);
116 }
117 else
118 {
119 // Groups with no profiles specified can be used in any event
120 key = std::make_pair(group["name"].get<std::string>(),
121 std::vector<std::string>{});
Matthew Barth44ab7692021-03-26 11:40:10 -0500122 grpEntry = groups.find(key);
123 if (grpEntry != groups.end())
Matthew Barth12bae962021-01-15 16:18:11 -0600124 {
125 eGroup grp;
126 for (const auto& member : grpEntry->second->getMembers())
127 {
128 grp.emplace_back(std::make_tuple(
129 member, group["interface"].get<std::string>(),
130 group["property"]["name"].get<std::string>(), type,
131 value));
132 }
133 _groups.emplace_back(grp);
134 }
135 }
Matthew Barth3174e722020-09-15 15:13:40 -0500136 }
137}
138
139void Event::setTriggers(const json& jsonObj)
140{
141 if (!jsonObj.contains("triggers"))
142 {
143 log<level::ERR>("Missing required event triggers list",
144 entry("JSON=%s", jsonObj.dump().c_str()));
145 throw std::runtime_error("Missing required event triggers list");
146 }
147}
148
149void Event::setActions(const json& jsonObj)
150{
151 for (const auto& action : jsonObj["actions"])
152 {
153 if (!action.contains("name"))
154 {
155 log<level::ERR>("Missing required event action name",
156 entry("JSON=%s", action.dump().c_str()));
157 throw std::runtime_error("Missing required event action name");
158 }
159 }
160}
161
162} // namespace phosphor::fan::control::json