1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "dispatch_rule_parser.h"
16 
17 #include <fstream>
18 #include "hiview_logger.h"
19 #include "sys_event.h"
20 
21 namespace OHOS {
22 namespace HiviewDFX {
23 namespace {
24 const std::map<std::string, uint8_t> EVENT_TYPE_MAP = {
25     {"FAULT", SysEventCreator::FAULT}, {"STATISTIC", SysEventCreator::STATISTIC},
26     {"SECURITY", SysEventCreator::SECURITY}, {"BEHAVIOR", SysEventCreator::BEHAVIOR}
27 };
28 }
29 DEFINE_LOG_TAG("DispatchRuleParser");
30 
DispatchRuleParser(const std::string & filePath)31 DispatchRuleParser::DispatchRuleParser(const std::string& filePath)
32 {
33     Json::Value root;
34     std::ifstream fin(filePath, std::ifstream::binary);
35 #ifdef JSONCPP_VERSION_STRING
36     Json::CharReaderBuilder jsonRBuilder;
37     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
38     JSONCPP_STRING errs;
39     if (!parseFromStream(jsonRBuilder, fin, &root, &errs)) {
40 #else
41     Json::Reader reader(Json::Features::strictMode());
42     if (!reader.parse(fin, root)) {
43 #endif
44         HIVIEW_LOGE("parse json file failed, please check the style of json file: %{public}s",
45             filePath.c_str());
46         return;
47     }
48     dispatchRule_ = std::make_shared<DispatchRule>();
49     ParseEventTypes(root);
50     ParseEvents(root);
51     ParseTagEvents(root);
52     ParseDomainRule(root);
53 }
54 
55 std::shared_ptr<DispatchRule> DispatchRuleParser::GetRule()
56 {
57     return dispatchRule_;
58 }
59 
60 void DispatchRuleParser::ParseEventTypes(const Json::Value& root)
61 {
62     if (dispatchRule_ == nullptr) {
63         return;
64     }
65     if (root.isNull() || !root.isMember("types") || !root["types"].isArray()) {
66         HIVIEW_LOGD("failed to parse the types");
67         return;
68     }
69     auto jsonTypeArray = root["types"];
70     int jsonSize = static_cast<int>(jsonTypeArray.size());
71     for (int i = 0; i < jsonSize; ++i) {
72         if (!jsonTypeArray[i].isString()) {
73             continue;
74         }
75         std::string key = jsonTypeArray[i].asString();
76         if (EVENT_TYPE_MAP.find(key) != EVENT_TYPE_MAP.end()) {
77             dispatchRule_->typeList.insert(EVENT_TYPE_MAP.at(key));
78         }
79     }
80 }
81 
82 void DispatchRuleParser::ParseTagEvents(const Json::Value& root)
83 {
84     if (dispatchRule_ == nullptr) {
85         return;
86     }
87     if (root.isNull() || !root.isMember("tags") || !root["tags"].isArray()) {
88         HIVIEW_LOGD("failed to parse the tags");
89         return;
90     }
91     auto jsonTagArray = root["tags"];
92     int jsonSize = static_cast<int>(jsonTagArray.size());
93     for (int i = 0; i < jsonSize; i++) {
94         if (!jsonTagArray[i].isString()) {
95             continue;
96         }
97         dispatchRule_->tagList.insert(jsonTagArray[i].asString());
98     }
99 }
100 
101 void DispatchRuleParser::ParseEvents(const Json::Value& root)
102 {
103     if (dispatchRule_ == nullptr) {
104         return;
105     }
106     if (root.isNull() || !root.isMember("events") || !root["events"].isArray()) {
107         HIVIEW_LOGD("failed to parse the events");
108         return;
109     }
110     auto jsonEventArray = root["events"];
111     int jsonSize = static_cast<int>(jsonEventArray.size());
112     for (int i = 0; i < jsonSize; i++) {
113         if (!jsonEventArray[i].isString()) {
114             continue;
115         }
116         dispatchRule_->eventList.insert(jsonEventArray[i].asString());
117     }
118 }
119 
120 void DispatchRuleParser::ParseDomainRule(const Json::Value& root)
121 {
122     if (dispatchRule_ == nullptr) {
123         return;
124     }
125     if (root.isNull() || !root.isMember("domains") || !root["domains"].isArray()) {
126         HIVIEW_LOGD("failed to parse the domains");
127         return;
128     }
129     auto jsonDomainArray = root["domains"];
130     int jsonSize = static_cast<int>(jsonDomainArray.size());
131     for (int i = 0; i < jsonSize; i++) {
132         if (jsonDomainArray[i].isNull() || !jsonDomainArray[i].isMember("domain")) {
133             continue;
134         }
135         if (!jsonDomainArray[i]["domain"].isString()) {
136             continue;
137         }
138         DomainRule domainRule;
139         std::string domainName = jsonDomainArray[i]["domain"].asString();
140         ParseDomains(jsonDomainArray[i], domainRule);
141         dispatchRule_->domainRuleMap[domainName] = domainRule;
142     }
143 }
144 
145 void DispatchRuleParser::ParseDomains(const Json::Value& json, DomainRule& domainRule)
146 {
147     Json::Value jsonArray;
148     if (json.isMember("include") && json["include"].isArray()) {
149         domainRule.filterType = DomainRule::INCLUDE;
150         jsonArray = json["include"];
151     } else if (json.isMember("exclude") && json["exclude"].isArray()) {
152         domainRule.filterType = DomainRule::EXCLUDE;
153         jsonArray = json["exclude"];
154     } else {
155         return;
156     }
157     int jsonSize = static_cast<int>(jsonArray.size());
158     for (int i = 0; i < jsonSize; i++) {
159         if (!jsonArray[i].isString()) {
160             continue;
161         }
162         domainRule.eventlist.insert(jsonArray[i].asString());
163     }
164 }
165 
166 bool DispatchRule::FindEvent(const std::string& domain, const std::string& eventName)
167 {
168     if (eventList.find(eventName) != eventList.end()) {
169         return true;
170     }
171     auto itDomainRule = domainRuleMap.find(domain);
172     if (itDomainRule != domainRuleMap.end()) {
173         return itDomainRule->second.FindEvent(eventName);
174     }
175     return false;
176 }
177 
178 bool DomainRule::FindEvent(const std::string& eventName) const
179 {
180     if (filterType == INCLUDE) {
181         return eventlist.find(eventName) != eventlist.end();
182     } else {
183         return eventlist.find(eventName) == eventlist.end();
184     }
185 }
186 } // namespace HiviewDFX
187 } // namespace OHOS