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