| /** |
| * Copyright © 2020 IBM Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "event.hpp" |
| |
| #include "group.hpp" |
| #include "json_parser.hpp" |
| |
| #include <nlohmann/json.hpp> |
| #include <phosphor-logging/log.hpp> |
| #include <sdbusplus/bus.hpp> |
| |
| #include <optional> |
| #include <tuple> |
| |
| namespace phosphor::fan::control::json |
| { |
| |
| using json = nlohmann::json; |
| using namespace phosphor::logging; |
| |
| const std::map<configKey, std::unique_ptr<Group>> Event::_availGrps = |
| getConfig<Group>(true); |
| |
| Event::Event(sdbusplus::bus::bus& bus, const json& jsonObj) : |
| ConfigBase(jsonObj), _bus(bus) |
| { |
| if (jsonObj.contains("profiles")) |
| { |
| for (const auto& profile : jsonObj["profiles"]) |
| { |
| _profiles.emplace_back(profile.get<std::string>()); |
| } |
| } |
| |
| // Event could have a precondition |
| if (!jsonObj.contains("precondition")) |
| { |
| // Event groups are optional |
| if (jsonObj.contains("groups")) |
| { |
| setGroups(jsonObj); |
| } |
| setTriggers(jsonObj); |
| // Event actions are optional |
| if (jsonObj.contains("actions")) |
| { |
| setActions(jsonObj); |
| } |
| } |
| else |
| { |
| setPrecond(jsonObj); |
| } |
| } |
| |
| void Event::setPrecond(const json& jsonObj) |
| { |
| const auto& precond = jsonObj["precondition"]; |
| if (!precond.contains("name") || !precond.contains("groups") || |
| !precond.contains("triggers") || !precond.contains("events")) |
| { |
| log<level::ERR>("Missing required event precondition attributes", |
| entry("JSON=%s", precond.dump().c_str())); |
| throw std::runtime_error( |
| "Missing required event precondition attributes"); |
| } |
| setGroups(precond); |
| setTriggers(precond); |
| } |
| |
| void Event::setGroups(const json& jsonObj) |
| { |
| for (const auto& group : jsonObj["groups"]) |
| { |
| if (!group.contains("name") || !group.contains("interface") || |
| !group.contains("property") || !group["property"].contains("name")) |
| { |
| log<level::ERR>("Missing required event group attributes", |
| entry("JSON=%s", group.dump().c_str())); |
| throw std::runtime_error("Missing required event group attributes"); |
| } |
| |
| // Get the group memebers' data type |
| std::optional<std::string> type = std::nullopt; |
| if (group["property"].contains("type")) |
| { |
| type = group["property"]["type"].get<std::string>(); |
| } |
| |
| // Get the group memebers' expected value |
| std::optional<PropertyVariantType> value = std::nullopt; |
| if (group["property"].contains("value")) |
| { |
| value = getJsonValue(group["property"]["value"]); |
| } |
| |
| // Groups with the same profiles as the event can be used |
| configKey key = |
| std::make_pair(group["name"].get<std::string>(), _profiles); |
| auto grpEntry = _availGrps.find(key); |
| if (grpEntry != _availGrps.end()) |
| { |
| eGroup grp; |
| for (const auto& member : grpEntry->second->getMembers()) |
| { |
| grp.emplace_back(std::make_tuple( |
| member, group["interface"].get<std::string>(), |
| group["property"]["name"].get<std::string>(), type, value)); |
| } |
| _groups.emplace_back(grp); |
| } |
| else |
| { |
| // Groups with no profiles specified can be used in any event |
| key = std::make_pair(group["name"].get<std::string>(), |
| std::vector<std::string>{}); |
| grpEntry = _availGrps.find(key); |
| if (grpEntry != _availGrps.end()) |
| { |
| eGroup grp; |
| for (const auto& member : grpEntry->second->getMembers()) |
| { |
| grp.emplace_back(std::make_tuple( |
| member, group["interface"].get<std::string>(), |
| group["property"]["name"].get<std::string>(), type, |
| value)); |
| } |
| _groups.emplace_back(grp); |
| } |
| } |
| } |
| } |
| |
| void Event::setTriggers(const json& jsonObj) |
| { |
| if (!jsonObj.contains("triggers")) |
| { |
| log<level::ERR>("Missing required event triggers list", |
| entry("JSON=%s", jsonObj.dump().c_str())); |
| throw std::runtime_error("Missing required event triggers list"); |
| } |
| } |
| |
| void Event::setActions(const json& jsonObj) |
| { |
| for (const auto& action : jsonObj["actions"]) |
| { |
| if (!action.contains("name")) |
| { |
| log<level::ERR>("Missing required event action name", |
| entry("JSON=%s", action.dump().c_str())); |
| throw std::runtime_error("Missing required event action name"); |
| } |
| } |
| } |
| |
| } // namespace phosphor::fan::control::json |