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