blob: f87598622e9b3d80bc4074b19881ae285aa8b428 [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{
Ed Tanous4b712a22023-08-02 12:56:52 -070015 // Represents a Redfish EventDestination instance
JunLin Chen28afb492021-02-24 17:13:29 +080016 std::string id;
Ed Tanousa716aa72023-08-01 11:35:53 -070017 boost::urls::url destinationUrl;
JunLin Chen28afb492021-02-24 17:13:29 +080018 std::string protocol;
Ed Tanous19bb3622024-07-05 10:07:40 -050019 bool verifyCertificate = true;
JunLin Chen28afb492021-02-24 17:13:29 +080020 std::string retryPolicy;
21 std::string customText;
22 std::string eventFormatType;
23 std::string subscriptionType;
24 std::vector<std::string> registryMsgIds;
25 std::vector<std::string> registryPrefixes;
26 std::vector<std::string> resourceTypes;
Ed Tanous601c71a2021-09-08 16:40:12 -070027 boost::beast::http::fields httpHeaders;
JunLin Chen28afb492021-02-24 17:13:29 +080028 std::vector<std::string> metricReportDefinitions;
Ed Tanousa14c9112024-09-04 10:46:47 -070029 std::vector<std::string> originResources;
JunLin Chen28afb492021-02-24 17:13:29 +080030
Ed Tanous4b712a22023-08-02 12:56:52 -070031 static std::optional<UserSubscription> fromJson(
Patrick Williamsbd79bce2024-08-16 15:22:20 -040032 const nlohmann::json::object_t& j, const bool loadFromOldConfig = false)
JunLin Chen28afb492021-02-24 17:13:29 +080033 {
Ed Tanous4b712a22023-08-02 12:56:52 -070034 UserSubscription subvalue;
Ed Tanous0bdda662023-08-03 17:27:34 -070035 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +080036 {
Ed Tanous0bdda662023-08-03 17:27:34 -070037 if (element.first == "Id")
JunLin Chen28afb492021-02-24 17:13:29 +080038 {
39 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070040 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080041 if (value == nullptr)
42 {
43 continue;
44 }
Ed Tanous4b712a22023-08-02 12:56:52 -070045 subvalue.id = *value;
JunLin Chen28afb492021-02-24 17:13:29 +080046 }
Ed Tanous0bdda662023-08-03 17:27:34 -070047 else if (element.first == "Destination")
JunLin Chen28afb492021-02-24 17:13:29 +080048 {
49 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070050 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080051 if (value == nullptr)
52 {
53 continue;
54 }
Ed Tanous6fd29552023-10-04 09:40:14 -070055 boost::system::result<boost::urls::url> url =
Ed Tanousa716aa72023-08-01 11:35:53 -070056 boost::urls::parse_absolute_uri(*value);
57 if (!url)
58 {
59 continue;
60 }
Ed Tanous4b712a22023-08-02 12:56:52 -070061 subvalue.destinationUrl = std::move(*url);
JunLin Chen28afb492021-02-24 17:13:29 +080062 }
Ed Tanous0bdda662023-08-03 17:27:34 -070063 else if (element.first == "Protocol")
JunLin Chen28afb492021-02-24 17:13:29 +080064 {
65 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070066 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080067 if (value == nullptr)
68 {
69 continue;
70 }
Ed Tanous4b712a22023-08-02 12:56:52 -070071 subvalue.protocol = *value;
JunLin Chen28afb492021-02-24 17:13:29 +080072 }
Ed Tanous19bb3622024-07-05 10:07:40 -050073 else if (element.first == "VerifyCertificate")
74 {
75 const bool* value = element.second.get_ptr<const bool*>();
76 if (value == nullptr)
77 {
78 continue;
79 }
Ed Tanous4b712a22023-08-02 12:56:52 -070080 subvalue.verifyCertificate = *value;
Ed Tanous19bb3622024-07-05 10:07:40 -050081 }
Ed Tanous0bdda662023-08-03 17:27:34 -070082 else if (element.first == "DeliveryRetryPolicy")
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 }
Ed Tanous4b712a22023-08-02 12:56:52 -070090 subvalue.retryPolicy = *value;
JunLin Chen28afb492021-02-24 17:13:29 +080091 }
Ed Tanous0bdda662023-08-03 17:27:34 -070092 else if (element.first == "Context")
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 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700100 subvalue.customText = *value;
JunLin Chen28afb492021-02-24 17:13:29 +0800101 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700102 else if (element.first == "EventFormatType")
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 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700110 subvalue.eventFormatType = *value;
JunLin Chen28afb492021-02-24 17:13:29 +0800111 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700112 else if (element.first == "SubscriptionType")
JunLin Chen28afb492021-02-24 17:13:29 +0800113 {
114 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700115 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800116 if (value == nullptr)
117 {
118 continue;
119 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700120 subvalue.subscriptionType = *value;
JunLin Chen28afb492021-02-24 17:13:29 +0800121 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700122 else if (element.first == "MessageIds")
JunLin Chen28afb492021-02-24 17:13:29 +0800123 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700124 const nlohmann::json::array_t* obj =
125 element.second.get_ptr<const nlohmann::json::array_t*>();
126 if (obj == nullptr)
127 {
128 continue;
129 }
130 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800131 {
132 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700133 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800134 if (value == nullptr)
135 {
136 continue;
137 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700138 subvalue.registryMsgIds.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800139 }
140 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700141 else if (element.first == "RegistryPrefixes")
JunLin Chen28afb492021-02-24 17:13:29 +0800142 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700143 const nlohmann::json::array_t* obj =
144 element.second.get_ptr<const nlohmann::json::array_t*>();
145 if (obj == nullptr)
146 {
147 continue;
148 }
149 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800150 {
151 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700152 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800153 if (value == nullptr)
154 {
155 continue;
156 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700157 subvalue.registryPrefixes.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800158 }
159 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700160 else if (element.first == "ResourceTypes")
JunLin Chen28afb492021-02-24 17:13:29 +0800161 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700162 const nlohmann::json::array_t* obj =
163 element.second.get_ptr<const nlohmann::json::array_t*>();
164 if (obj == nullptr)
165 {
166 continue;
167 }
168 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800169 {
170 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700171 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800172 if (value == nullptr)
173 {
174 continue;
175 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700176 subvalue.resourceTypes.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800177 }
178 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700179 else if (element.first == "HttpHeaders")
JunLin Chen28afb492021-02-24 17:13:29 +0800180 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700181 const nlohmann::json::object_t* obj =
182 element.second.get_ptr<const nlohmann::json::object_t*>();
183 if (obj == nullptr)
184 {
185 continue;
186 }
187 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800188 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700189 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700190 val.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800191 if (value == nullptr)
192 {
Ed Tanous62598e32023-07-17 17:06:25 -0700193 BMCWEB_LOG_ERROR("Failed to parse value for key{}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700194 val.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800195 continue;
196 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700197 subvalue.httpHeaders.set(val.first, *value);
JunLin Chen28afb492021-02-24 17:13:29 +0800198 }
199 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700200 else if (element.first == "MetricReportDefinitions")
JunLin Chen28afb492021-02-24 17:13:29 +0800201 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700202 const nlohmann::json::array_t* obj =
203 element.second.get_ptr<const nlohmann::json::array_t*>();
204 if (obj == nullptr)
205 {
206 continue;
207 }
208 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800209 {
210 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700211 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800212 if (value == nullptr)
213 {
214 continue;
215 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700216 subvalue.metricReportDefinitions.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800217 }
218 }
Ed Tanousa14c9112024-09-04 10:46:47 -0700219 else if (element.first == "OriginResources")
220 {
221 const nlohmann::json::array_t* obj =
222 element.second.get_ptr<const nlohmann::json::array_t*>();
223 if (obj == nullptr)
224 {
225 continue;
226 }
227 for (const auto& val : *obj)
228 {
229 const std::string* value =
230 val.get_ptr<const std::string*>();
231 if (value == nullptr)
232 {
233 continue;
234 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700235 subvalue.originResources.emplace_back(*value);
Ed Tanousa14c9112024-09-04 10:46:47 -0700236 }
237 }
JunLin Chen28afb492021-02-24 17:13:29 +0800238 else
239 {
Ed Tanous62598e32023-07-17 17:06:25 -0700240 BMCWEB_LOG_ERROR(
241 "Got unexpected property reading persistent file: {}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700242 element.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800243 continue;
244 }
245 }
246
Ed Tanous4b712a22023-08-02 12:56:52 -0700247 if ((subvalue.id.empty() && !loadFromOldConfig) ||
248 subvalue.destinationUrl.empty() || subvalue.protocol.empty() ||
249 subvalue.retryPolicy.empty() || subvalue.eventFormatType.empty() ||
250 subvalue.subscriptionType.empty())
JunLin Chen28afb492021-02-24 17:13:29 +0800251 {
Ed Tanous62598e32023-07-17 17:06:25 -0700252 BMCWEB_LOG_ERROR("Subscription missing required field "
253 "information, refusing to restore");
Ed Tanous4b712a22023-08-02 12:56:52 -0700254 return std::nullopt;
JunLin Chen28afb492021-02-24 17:13:29 +0800255 }
256
257 return subvalue;
258 }
259};
260
261struct EventServiceConfig
262{
263 bool enabled = true;
264 uint32_t retryAttempts = 3;
265 uint32_t retryTimeoutInterval = 30;
266
Ed Tanous0bdda662023-08-03 17:27:34 -0700267 void fromJson(const nlohmann::json::object_t& j)
JunLin Chen28afb492021-02-24 17:13:29 +0800268 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700269 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +0800270 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700271 if (element.first == "ServiceEnabled")
JunLin Chen28afb492021-02-24 17:13:29 +0800272 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700273 const bool* value = element.second.get_ptr<const bool*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800274 if (value == nullptr)
275 {
276 continue;
277 }
278 enabled = *value;
279 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700280 else if (element.first == "DeliveryRetryAttempts")
JunLin Chen28afb492021-02-24 17:13:29 +0800281 {
282 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700283 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800284 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800285 (*value > std::numeric_limits<uint32_t>::max()))
286 {
287 continue;
288 }
289 retryAttempts = static_cast<uint32_t>(*value);
290 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700291 else if (element.first == "DeliveryRetryIntervalSeconds")
JunLin Chen28afb492021-02-24 17:13:29 +0800292 {
293 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700294 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800295 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800296 (*value > std::numeric_limits<uint32_t>::max()))
297 {
298 continue;
299 }
300 retryTimeoutInterval = static_cast<uint32_t>(*value);
301 }
302 }
303 }
304};
305
306class EventServiceStore
307{
308 public:
Ed Tanous4b712a22023-08-02 12:56:52 -0700309 boost::container::flat_map<std::string, UserSubscription>
JunLin Chen28afb492021-02-24 17:13:29 +0800310 subscriptionsConfigMap;
311 EventServiceConfig eventServiceConfig;
312
313 static EventServiceStore& getInstance()
314 {
315 static EventServiceStore eventServiceStore;
316 return eventServiceStore;
317 }
318
319 EventServiceConfig& getEventServiceConfig()
320 {
321 return eventServiceConfig;
322 }
323};
324
325} // namespace persistent_data