xref: /openbmc/ibm-logging/policy_table.cpp (revision 6a2b8956487404dd2f7e4aa06055c24a2b7271e1)
18c0a63f9SMatt Spinler /**
28c0a63f9SMatt Spinler  * Copyright © 2018 IBM Corporation
38c0a63f9SMatt Spinler  *
48c0a63f9SMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
58c0a63f9SMatt Spinler  * you may not use this file except in compliance with the License.
68c0a63f9SMatt Spinler  * You may obtain a copy of the License at
78c0a63f9SMatt Spinler  *
88c0a63f9SMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
98c0a63f9SMatt Spinler  *
108c0a63f9SMatt Spinler  * Unless required by applicable law or agreed to in writing, software
118c0a63f9SMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
128c0a63f9SMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138c0a63f9SMatt Spinler  * See the License for the specific language governing permissions and
148c0a63f9SMatt Spinler  * limitations under the License.
158c0a63f9SMatt Spinler  */
1666e07073SMatt Spinler #include "policy_table.hpp"
1766e07073SMatt Spinler 
188c0a63f9SMatt Spinler #include <nlohmann/json.hpp>
198c0a63f9SMatt Spinler #include <phosphor-logging/log.hpp>
208c0a63f9SMatt Spinler 
21*6a2b8956SPatrick Williams #include <experimental/filesystem>
22*6a2b8956SPatrick Williams #include <fstream>
23*6a2b8956SPatrick Williams 
248c0a63f9SMatt Spinler namespace ibm
258c0a63f9SMatt Spinler {
268c0a63f9SMatt Spinler namespace logging
278c0a63f9SMatt Spinler {
288c0a63f9SMatt Spinler namespace policy
298c0a63f9SMatt Spinler {
308c0a63f9SMatt Spinler 
318c0a63f9SMatt Spinler namespace fs = std::experimental::filesystem;
328c0a63f9SMatt Spinler using namespace phosphor::logging;
338c0a63f9SMatt Spinler 
Table(const std::string & jsonFile)348c0a63f9SMatt Spinler Table::Table(const std::string& jsonFile)
358c0a63f9SMatt Spinler {
368c0a63f9SMatt Spinler     if (fs::exists(jsonFile))
378c0a63f9SMatt Spinler     {
388c0a63f9SMatt Spinler         load(jsonFile);
398c0a63f9SMatt Spinler     }
408c0a63f9SMatt Spinler     else
418c0a63f9SMatt Spinler     {
428c0a63f9SMatt Spinler         log<level::INFO>("Policy table JSON file does not exist",
438c0a63f9SMatt Spinler                          entry("FILE=%s", jsonFile.c_str()));
448c0a63f9SMatt Spinler     }
458c0a63f9SMatt Spinler }
468c0a63f9SMatt Spinler 
load(const std::string & jsonFile)478c0a63f9SMatt Spinler void Table::load(const std::string& jsonFile)
488c0a63f9SMatt Spinler {
498c0a63f9SMatt Spinler     try
508c0a63f9SMatt Spinler     {
518c0a63f9SMatt Spinler         std::ifstream file{jsonFile};
528c0a63f9SMatt Spinler 
538c0a63f9SMatt Spinler         auto json = nlohmann::json::parse(file, nullptr, true);
548c0a63f9SMatt Spinler 
558c0a63f9SMatt Spinler         for (const auto& policy : json)
568c0a63f9SMatt Spinler         {
578c0a63f9SMatt Spinler             DetailsList detailsList;
588c0a63f9SMatt Spinler 
598c0a63f9SMatt Spinler             for (const auto& details : policy["dtls"])
608c0a63f9SMatt Spinler             {
618c0a63f9SMatt Spinler                 Details d;
628c0a63f9SMatt Spinler                 d.modifier = details["mod"];
638c0a63f9SMatt Spinler                 d.msg = details["msg"];
648c0a63f9SMatt Spinler                 d.ceid = details["CEID"];
658c0a63f9SMatt Spinler                 detailsList.emplace_back(std::move(d));
668c0a63f9SMatt Spinler             }
678c0a63f9SMatt Spinler             policies.emplace(policy["err"], std::move(detailsList));
688c0a63f9SMatt Spinler         }
698c0a63f9SMatt Spinler 
708c0a63f9SMatt Spinler         loaded = true;
718c0a63f9SMatt Spinler     }
72bf9ea8adSPatrick Williams     catch (const std::exception& e)
738c0a63f9SMatt Spinler     {
748c0a63f9SMatt Spinler         log<level::ERR>("Failed loading policy table json file",
758c0a63f9SMatt Spinler                         entry("FILE=%s", jsonFile.c_str()),
768c0a63f9SMatt Spinler                         entry("ERROR=%s", e.what()));
778c0a63f9SMatt Spinler         loaded = false;
788c0a63f9SMatt Spinler     }
798c0a63f9SMatt Spinler }
808c0a63f9SMatt Spinler 
find(const std::string & error,const std::string & modifier) const81c57aa4b9SMatt Spinler FindResult Table::find(const std::string& error,
82c57aa4b9SMatt Spinler                        const std::string& modifier) const
833c9e3016SMatt Spinler {
843c9e3016SMatt Spinler     // First find the entry based on the error, and then find which
853c9e3016SMatt Spinler     // underlying details object it is with the help of the modifier.
863c9e3016SMatt Spinler 
873c9e3016SMatt Spinler     auto policy = policies.find(error);
883c9e3016SMatt Spinler 
893c9e3016SMatt Spinler     if (policy != policies.end())
903c9e3016SMatt Spinler     {
91200ead29SMatt Spinler         // If there is no exact modifier match, then look for an entry with
92200ead29SMatt Spinler         // an empty modifier - it is the catch-all for that error.
933c9e3016SMatt Spinler         auto details = std::find_if(
94259e7277SMatt Spinler             policy->second.begin(), policy->second.end(),
95200ead29SMatt Spinler             [&modifier](const auto& d) { return modifier == d.modifier; });
96200ead29SMatt Spinler 
97200ead29SMatt Spinler         if ((details == policy->second.end()) && !modifier.empty())
98200ead29SMatt Spinler         {
99200ead29SMatt Spinler             details =
100200ead29SMatt Spinler                 std::find_if(policy->second.begin(), policy->second.end(),
101200ead29SMatt Spinler                              [](const auto& d) { return d.modifier.empty(); });
102200ead29SMatt Spinler         }
1033c9e3016SMatt Spinler 
1043c9e3016SMatt Spinler         if (details != policy->second.end())
1053c9e3016SMatt Spinler         {
1063c9e3016SMatt Spinler             return DetailsReference(*details);
1073c9e3016SMatt Spinler         }
1083c9e3016SMatt Spinler     }
1093c9e3016SMatt Spinler 
1103c9e3016SMatt Spinler     return {};
1113c9e3016SMatt Spinler }
11266e07073SMatt Spinler } // namespace policy
11366e07073SMatt Spinler } // namespace logging
11466e07073SMatt Spinler } // namespace ibm
115