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