| /** |
| * Copyright © 2018 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 "policy_table.hpp" |
| |
| #include <experimental/filesystem> |
| #include <fstream> |
| #include <nlohmann/json.hpp> |
| #include <phosphor-logging/log.hpp> |
| |
| namespace ibm |
| { |
| namespace logging |
| { |
| namespace policy |
| { |
| |
| namespace fs = std::experimental::filesystem; |
| using namespace phosphor::logging; |
| |
| Table::Table(const std::string& jsonFile) |
| { |
| if (fs::exists(jsonFile)) |
| { |
| load(jsonFile); |
| } |
| else |
| { |
| log<level::INFO>("Policy table JSON file does not exist", |
| entry("FILE=%s", jsonFile.c_str())); |
| } |
| } |
| |
| void Table::load(const std::string& jsonFile) |
| { |
| try |
| { |
| std::ifstream file{jsonFile}; |
| |
| auto json = nlohmann::json::parse(file, nullptr, true); |
| |
| for (const auto& policy : json) |
| { |
| DetailsList detailsList; |
| |
| for (const auto& details : policy["dtls"]) |
| { |
| Details d; |
| d.modifier = details["mod"]; |
| d.msg = details["msg"]; |
| d.ceid = details["CEID"]; |
| detailsList.emplace_back(std::move(d)); |
| } |
| policies.emplace(policy["err"], std::move(detailsList)); |
| } |
| |
| loaded = true; |
| } |
| catch (std::exception& e) |
| { |
| log<level::ERR>("Failed loading policy table json file", |
| entry("FILE=%s", jsonFile.c_str()), |
| entry("ERROR=%s", e.what())); |
| loaded = false; |
| } |
| } |
| |
| optional_ns::optional<DetailsReference> |
| Table::find(const std::string& error, const std::string& modifier) const |
| { |
| // First find the entry based on the error, and then find which |
| // underlying details object it is with the help of the modifier. |
| |
| auto policy = policies.find(error); |
| |
| if (policy != policies.end()) |
| { |
| // If there is no exact modifier match, then look for an entry with |
| // an empty modifier - it is the catch-all for that error. |
| auto details = std::find_if( |
| policy->second.begin(), policy->second.end(), |
| [&modifier](const auto& d) { return modifier == d.modifier; }); |
| |
| if ((details == policy->second.end()) && !modifier.empty()) |
| { |
| details = |
| std::find_if(policy->second.begin(), policy->second.end(), |
| [](const auto& d) { return d.modifier.empty(); }); |
| } |
| |
| if (details != policy->second.end()) |
| { |
| return DetailsReference(*details); |
| } |
| } |
| |
| return {}; |
| } |
| } // namespace policy |
| } // namespace logging |
| } // namespace ibm |