xref: /openbmc/ibm-logging/policy_table.cpp (revision 259e7277)
1 /**
2  * Copyright © 2018 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 <experimental/filesystem>
17 #include <fstream>
18 #include <nlohmann/json.hpp>
19 #include <phosphor-logging/log.hpp>
20 #include "policy_table.hpp"
21 
22 namespace ibm
23 {
24 namespace logging
25 {
26 namespace policy
27 {
28 
29 namespace fs = std::experimental::filesystem;
30 using namespace phosphor::logging;
31 
32 Table::Table(const std::string& jsonFile)
33 {
34     if (fs::exists(jsonFile))
35     {
36         load(jsonFile);
37     }
38     else
39     {
40         log<level::INFO>("Policy table JSON file does not exist",
41                          entry("FILE=%s", jsonFile.c_str()));
42     }
43 }
44 
45 void Table::load(const std::string& jsonFile)
46 {
47     try
48     {
49         std::ifstream file{jsonFile};
50 
51         auto json = nlohmann::json::parse(file, nullptr, true);
52 
53         for (const auto& policy : json)
54         {
55             DetailsList detailsList;
56 
57             for (const auto& details : policy["dtls"])
58             {
59                 Details d;
60                 d.modifier = details["mod"];
61                 d.msg = details["msg"];
62                 d.ceid = details["CEID"];
63                 detailsList.emplace_back(std::move(d));
64             }
65             policies.emplace(policy["err"], std::move(detailsList));
66         }
67 
68         loaded = true;
69     }
70     catch (std::exception& e)
71     {
72         log<level::ERR>("Failed loading policy table json file",
73                         entry("FILE=%s", jsonFile.c_str()),
74                         entry("ERROR=%s", e.what()));
75         loaded = false;
76     }
77 }
78 
79 optional_ns::optional<DetailsReference>
80     Table::find(const std::string& error, const std::string& modifier) const
81 {
82     // First find the entry based on the error, and then find which
83     // underlying details object it is with the help of the modifier.
84 
85     auto policy = policies.find(error);
86 
87     if (policy != policies.end())
88     {
89         // Not all policy entries have a modifier defined, so if it is
90         // empty that will return as a match.
91 
92         auto details = std::find_if(
93             policy->second.begin(), policy->second.end(),
94             [&modifier](const auto& d) {
95                 return d.modifier.empty() || (modifier == d.modifier);
96             });
97 
98         if (details != policy->second.end())
99         {
100             return DetailsReference(*details);
101         }
102     }
103 
104     return {};
105 }
106 }
107 }
108 }
109