blob: f7f03ab5c40cf173cf8c3079984b2fea6c3f115d [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;
18 std::string retryPolicy;
19 std::string customText;
20 std::string eventFormatType;
21 std::string subscriptionType;
22 std::vector<std::string> registryMsgIds;
23 std::vector<std::string> registryPrefixes;
24 std::vector<std::string> resourceTypes;
Ed Tanous601c71a2021-09-08 16:40:12 -070025 boost::beast::http::fields httpHeaders;
JunLin Chen28afb492021-02-24 17:13:29 +080026 std::vector<std::string> metricReportDefinitions;
27
28 static std::shared_ptr<UserSubscription>
Ed Tanous0bdda662023-08-03 17:27:34 -070029 fromJson(const nlohmann::json::object_t& j,
30 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 Tanous0bdda662023-08-03 17:27:34 -070072 else if (element.first == "DeliveryRetryPolicy")
JunLin Chen28afb492021-02-24 17:13:29 +080073 {
74 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070075 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080076 if (value == nullptr)
77 {
78 continue;
79 }
80 subvalue->retryPolicy = *value;
81 }
Ed Tanous0bdda662023-08-03 17:27:34 -070082 else if (element.first == "Context")
JunLin Chen28afb492021-02-24 17:13:29 +080083 {
84 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070085 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080086 if (value == nullptr)
87 {
88 continue;
89 }
90 subvalue->customText = *value;
91 }
Ed Tanous0bdda662023-08-03 17:27:34 -070092 else if (element.first == "EventFormatType")
JunLin Chen28afb492021-02-24 17:13:29 +080093 {
94 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070095 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080096 if (value == nullptr)
97 {
98 continue;
99 }
100 subvalue->eventFormatType = *value;
101 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700102 else if (element.first == "SubscriptionType")
JunLin Chen28afb492021-02-24 17:13:29 +0800103 {
104 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700105 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800106 if (value == nullptr)
107 {
108 continue;
109 }
110 subvalue->subscriptionType = *value;
111 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700112 else if (element.first == "MessageIds")
JunLin Chen28afb492021-02-24 17:13:29 +0800113 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700114 const nlohmann::json::array_t* obj =
115 element.second.get_ptr<const nlohmann::json::array_t*>();
116 if (obj == nullptr)
117 {
118 continue;
119 }
120 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800121 {
122 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700123 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800124 if (value == nullptr)
125 {
126 continue;
127 }
128 subvalue->registryMsgIds.emplace_back(*value);
129 }
130 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700131 else if (element.first == "RegistryPrefixes")
JunLin Chen28afb492021-02-24 17:13:29 +0800132 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700133 const nlohmann::json::array_t* obj =
134 element.second.get_ptr<const nlohmann::json::array_t*>();
135 if (obj == nullptr)
136 {
137 continue;
138 }
139 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800140 {
141 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700142 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800143 if (value == nullptr)
144 {
145 continue;
146 }
147 subvalue->registryPrefixes.emplace_back(*value);
148 }
149 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700150 else if (element.first == "ResourceTypes")
JunLin Chen28afb492021-02-24 17:13:29 +0800151 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700152 const nlohmann::json::array_t* obj =
153 element.second.get_ptr<const nlohmann::json::array_t*>();
154 if (obj == nullptr)
155 {
156 continue;
157 }
158 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800159 {
160 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700161 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800162 if (value == nullptr)
163 {
164 continue;
165 }
166 subvalue->resourceTypes.emplace_back(*value);
167 }
168 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700169 else if (element.first == "HttpHeaders")
JunLin Chen28afb492021-02-24 17:13:29 +0800170 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700171 const nlohmann::json::object_t* obj =
172 element.second.get_ptr<const nlohmann::json::object_t*>();
173 if (obj == nullptr)
174 {
175 continue;
176 }
177 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800178 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700179 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700180 val.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800181 if (value == nullptr)
182 {
Ed Tanous62598e32023-07-17 17:06:25 -0700183 BMCWEB_LOG_ERROR("Failed to parse value for key{}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700184 val.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800185 continue;
186 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700187 subvalue->httpHeaders.set(val.first, *value);
JunLin Chen28afb492021-02-24 17:13:29 +0800188 }
189 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700190 else if (element.first == "MetricReportDefinitions")
JunLin Chen28afb492021-02-24 17:13:29 +0800191 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700192 const nlohmann::json::array_t* obj =
193 element.second.get_ptr<const nlohmann::json::array_t*>();
194 if (obj == nullptr)
195 {
196 continue;
197 }
198 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800199 {
200 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700201 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800202 if (value == nullptr)
203 {
204 continue;
205 }
206 subvalue->metricReportDefinitions.emplace_back(*value);
207 }
208 }
209 else
210 {
Ed Tanous62598e32023-07-17 17:06:25 -0700211 BMCWEB_LOG_ERROR(
212 "Got unexpected property reading persistent file: {}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700213 element.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800214 continue;
215 }
216 }
217
218 if ((subvalue->id.empty() && !loadFromOldConfig) ||
219 subvalue->destinationUrl.empty() || subvalue->protocol.empty() ||
Sunitha Harishe6a71652021-08-06 03:15:59 -0500220 subvalue->retryPolicy.empty() ||
JunLin Chen28afb492021-02-24 17:13:29 +0800221 subvalue->eventFormatType.empty() ||
Sunitha Harishe6a71652021-08-06 03:15:59 -0500222 subvalue->subscriptionType.empty())
JunLin Chen28afb492021-02-24 17:13:29 +0800223 {
Ed Tanous62598e32023-07-17 17:06:25 -0700224 BMCWEB_LOG_ERROR("Subscription missing required field "
225 "information, refusing to restore");
JunLin Chen28afb492021-02-24 17:13:29 +0800226 return nullptr;
227 }
228
229 return subvalue;
230 }
231};
232
233struct EventServiceConfig
234{
235 bool enabled = true;
236 uint32_t retryAttempts = 3;
237 uint32_t retryTimeoutInterval = 30;
238
Ed Tanous0bdda662023-08-03 17:27:34 -0700239 void fromJson(const nlohmann::json::object_t& j)
JunLin Chen28afb492021-02-24 17:13:29 +0800240 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700241 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +0800242 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700243 if (element.first == "ServiceEnabled")
JunLin Chen28afb492021-02-24 17:13:29 +0800244 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700245 const bool* value = element.second.get_ptr<const bool*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800246 if (value == nullptr)
247 {
248 continue;
249 }
250 enabled = *value;
251 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700252 else if (element.first == "DeliveryRetryAttempts")
JunLin Chen28afb492021-02-24 17:13:29 +0800253 {
254 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700255 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800256 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800257 (*value > std::numeric_limits<uint32_t>::max()))
258 {
259 continue;
260 }
261 retryAttempts = static_cast<uint32_t>(*value);
262 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700263 else if (element.first == "DeliveryRetryIntervalSeconds")
JunLin Chen28afb492021-02-24 17:13:29 +0800264 {
265 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700266 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800267 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800268 (*value > std::numeric_limits<uint32_t>::max()))
269 {
270 continue;
271 }
272 retryTimeoutInterval = static_cast<uint32_t>(*value);
273 }
274 }
275 }
276};
277
278class EventServiceStore
279{
280 public:
281 boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
282 subscriptionsConfigMap;
283 EventServiceConfig eventServiceConfig;
284
285 static EventServiceStore& getInstance()
286 {
287 static EventServiceStore eventServiceStore;
288 return eventServiceStore;
289 }
290
291 EventServiceConfig& getEventServiceConfig()
292 {
293 return eventServiceConfig;
294 }
295};
296
297} // namespace persistent_data