blob: 8501fff7d64777b6dc728d7c9d95ef4276706a98 [file] [log] [blame]
JunLin Chen28afb492021-02-24 17:13:29 +08001#pragma once
2#include "logging.hpp"
3
Ed Tanous601c71a2021-09-08 16:40:12 -07004#include <boost/beast/http/fields.hpp>
JunLin Chen28afb492021-02-24 17:13:29 +08005#include <boost/container/flat_map.hpp>
Ed Tanousa716aa72023-08-01 11:35:53 -07006#include <boost/url/parse.hpp>
Ed Tanous4a7fbef2024-04-06 16:03:49 -07007#include <boost/url/url.hpp>
JunLin Chen28afb492021-02-24 17:13:29 +08008#include <nlohmann/json.hpp>
9
10namespace persistent_data
11{
12
13struct UserSubscription
14{
15 std::string id;
Ed Tanousa716aa72023-08-01 11:35:53 -070016 boost::urls::url destinationUrl;
JunLin Chen28afb492021-02-24 17:13:29 +080017 std::string protocol;
Ed Tanous19bb3622024-07-05 10:07:40 -050018 bool verifyCertificate = true;
JunLin Chen28afb492021-02-24 17:13:29 +080019 std::string retryPolicy;
20 std::string customText;
21 std::string eventFormatType;
22 std::string subscriptionType;
23 std::vector<std::string> registryMsgIds;
24 std::vector<std::string> registryPrefixes;
25 std::vector<std::string> resourceTypes;
Ed Tanous601c71a2021-09-08 16:40:12 -070026 boost::beast::http::fields httpHeaders;
JunLin Chen28afb492021-02-24 17:13:29 +080027 std::vector<std::string> metricReportDefinitions;
28
Patrick Williamsbd79bce2024-08-16 15:22:20 -040029 static std::shared_ptr<UserSubscription> fromJson(
30 const nlohmann::json::object_t& j, const bool loadFromOldConfig = false)
JunLin Chen28afb492021-02-24 17:13:29 +080031 {
32 std::shared_ptr<UserSubscription> subvalue =
33 std::make_shared<UserSubscription>();
Ed Tanous0bdda662023-08-03 17:27:34 -070034 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +080035 {
Ed Tanous0bdda662023-08-03 17:27:34 -070036 if (element.first == "Id")
JunLin Chen28afb492021-02-24 17:13:29 +080037 {
38 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070039 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080040 if (value == nullptr)
41 {
42 continue;
43 }
44 subvalue->id = *value;
45 }
Ed Tanous0bdda662023-08-03 17:27:34 -070046 else if (element.first == "Destination")
JunLin Chen28afb492021-02-24 17:13:29 +080047 {
48 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070049 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080050 if (value == nullptr)
51 {
52 continue;
53 }
Ed Tanous6fd29552023-10-04 09:40:14 -070054 boost::system::result<boost::urls::url> url =
Ed Tanousa716aa72023-08-01 11:35:53 -070055 boost::urls::parse_absolute_uri(*value);
56 if (!url)
57 {
58 continue;
59 }
60 subvalue->destinationUrl = std::move(*url);
JunLin Chen28afb492021-02-24 17:13:29 +080061 }
Ed Tanous0bdda662023-08-03 17:27:34 -070062 else if (element.first == "Protocol")
JunLin Chen28afb492021-02-24 17:13:29 +080063 {
64 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070065 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080066 if (value == nullptr)
67 {
68 continue;
69 }
70 subvalue->protocol = *value;
71 }
Ed Tanous19bb3622024-07-05 10:07:40 -050072 else if (element.first == "VerifyCertificate")
73 {
74 const bool* value = element.second.get_ptr<const bool*>();
75 if (value == nullptr)
76 {
77 continue;
78 }
79 subvalue->verifyCertificate = *value;
80 }
Ed Tanous0bdda662023-08-03 17:27:34 -070081 else if (element.first == "DeliveryRetryPolicy")
JunLin Chen28afb492021-02-24 17:13:29 +080082 {
83 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070084 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080085 if (value == nullptr)
86 {
87 continue;
88 }
89 subvalue->retryPolicy = *value;
90 }
Ed Tanous0bdda662023-08-03 17:27:34 -070091 else if (element.first == "Context")
JunLin Chen28afb492021-02-24 17:13:29 +080092 {
93 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070094 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080095 if (value == nullptr)
96 {
97 continue;
98 }
99 subvalue->customText = *value;
100 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700101 else if (element.first == "EventFormatType")
JunLin Chen28afb492021-02-24 17:13:29 +0800102 {
103 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700104 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800105 if (value == nullptr)
106 {
107 continue;
108 }
109 subvalue->eventFormatType = *value;
110 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700111 else if (element.first == "SubscriptionType")
JunLin Chen28afb492021-02-24 17:13:29 +0800112 {
113 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700114 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800115 if (value == nullptr)
116 {
117 continue;
118 }
119 subvalue->subscriptionType = *value;
120 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700121 else if (element.first == "MessageIds")
JunLin Chen28afb492021-02-24 17:13:29 +0800122 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700123 const nlohmann::json::array_t* obj =
124 element.second.get_ptr<const nlohmann::json::array_t*>();
125 if (obj == nullptr)
126 {
127 continue;
128 }
129 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800130 {
131 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700132 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800133 if (value == nullptr)
134 {
135 continue;
136 }
137 subvalue->registryMsgIds.emplace_back(*value);
138 }
139 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700140 else if (element.first == "RegistryPrefixes")
JunLin Chen28afb492021-02-24 17:13:29 +0800141 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700142 const nlohmann::json::array_t* obj =
143 element.second.get_ptr<const nlohmann::json::array_t*>();
144 if (obj == nullptr)
145 {
146 continue;
147 }
148 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800149 {
150 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700151 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800152 if (value == nullptr)
153 {
154 continue;
155 }
156 subvalue->registryPrefixes.emplace_back(*value);
157 }
158 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700159 else if (element.first == "ResourceTypes")
JunLin Chen28afb492021-02-24 17:13:29 +0800160 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700161 const nlohmann::json::array_t* obj =
162 element.second.get_ptr<const nlohmann::json::array_t*>();
163 if (obj == nullptr)
164 {
165 continue;
166 }
167 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800168 {
169 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700170 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800171 if (value == nullptr)
172 {
173 continue;
174 }
175 subvalue->resourceTypes.emplace_back(*value);
176 }
177 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700178 else if (element.first == "HttpHeaders")
JunLin Chen28afb492021-02-24 17:13:29 +0800179 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700180 const nlohmann::json::object_t* obj =
181 element.second.get_ptr<const nlohmann::json::object_t*>();
182 if (obj == nullptr)
183 {
184 continue;
185 }
186 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800187 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700188 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700189 val.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800190 if (value == nullptr)
191 {
Ed Tanous62598e32023-07-17 17:06:25 -0700192 BMCWEB_LOG_ERROR("Failed to parse value for key{}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700193 val.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800194 continue;
195 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700196 subvalue->httpHeaders.set(val.first, *value);
JunLin Chen28afb492021-02-24 17:13:29 +0800197 }
198 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700199 else if (element.first == "MetricReportDefinitions")
JunLin Chen28afb492021-02-24 17:13:29 +0800200 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700201 const nlohmann::json::array_t* obj =
202 element.second.get_ptr<const nlohmann::json::array_t*>();
203 if (obj == nullptr)
204 {
205 continue;
206 }
207 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800208 {
209 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700210 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800211 if (value == nullptr)
212 {
213 continue;
214 }
215 subvalue->metricReportDefinitions.emplace_back(*value);
216 }
217 }
218 else
219 {
Ed Tanous62598e32023-07-17 17:06:25 -0700220 BMCWEB_LOG_ERROR(
221 "Got unexpected property reading persistent file: {}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700222 element.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800223 continue;
224 }
225 }
226
227 if ((subvalue->id.empty() && !loadFromOldConfig) ||
228 subvalue->destinationUrl.empty() || subvalue->protocol.empty() ||
Sunitha Harishe6a71652021-08-06 03:15:59 -0500229 subvalue->retryPolicy.empty() ||
JunLin Chen28afb492021-02-24 17:13:29 +0800230 subvalue->eventFormatType.empty() ||
Sunitha Harishe6a71652021-08-06 03:15:59 -0500231 subvalue->subscriptionType.empty())
JunLin Chen28afb492021-02-24 17:13:29 +0800232 {
Ed Tanous62598e32023-07-17 17:06:25 -0700233 BMCWEB_LOG_ERROR("Subscription missing required field "
234 "information, refusing to restore");
JunLin Chen28afb492021-02-24 17:13:29 +0800235 return nullptr;
236 }
237
238 return subvalue;
239 }
240};
241
242struct EventServiceConfig
243{
244 bool enabled = true;
245 uint32_t retryAttempts = 3;
246 uint32_t retryTimeoutInterval = 30;
247
Ed Tanous0bdda662023-08-03 17:27:34 -0700248 void fromJson(const nlohmann::json::object_t& j)
JunLin Chen28afb492021-02-24 17:13:29 +0800249 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700250 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +0800251 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700252 if (element.first == "ServiceEnabled")
JunLin Chen28afb492021-02-24 17:13:29 +0800253 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700254 const bool* value = element.second.get_ptr<const bool*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800255 if (value == nullptr)
256 {
257 continue;
258 }
259 enabled = *value;
260 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700261 else if (element.first == "DeliveryRetryAttempts")
JunLin Chen28afb492021-02-24 17:13:29 +0800262 {
263 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700264 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800265 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800266 (*value > std::numeric_limits<uint32_t>::max()))
267 {
268 continue;
269 }
270 retryAttempts = static_cast<uint32_t>(*value);
271 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700272 else if (element.first == "DeliveryRetryIntervalSeconds")
JunLin Chen28afb492021-02-24 17:13:29 +0800273 {
274 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700275 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800276 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800277 (*value > std::numeric_limits<uint32_t>::max()))
278 {
279 continue;
280 }
281 retryTimeoutInterval = static_cast<uint32_t>(*value);
282 }
283 }
284 }
285};
286
287class EventServiceStore
288{
289 public:
290 boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
291 subscriptionsConfigMap;
292 EventServiceConfig eventServiceConfig;
293
294 static EventServiceStore& getInstance()
295 {
296 static EventServiceStore eventServiceStore;
297 return eventServiceStore;
298 }
299
300 EventServiceConfig& getEventServiceConfig()
301 {
302 return eventServiceConfig;
303 }
304};
305
306} // namespace persistent_data