blob: b0a1d9703d1faae8e9cb80f5359d09cb5b5fcdfd [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
Myung Bae56ba3862024-10-10 17:09:37 -070010#include <memory>
11#include <string>
12#include <vector>
13
JunLin Chen28afb492021-02-24 17:13:29 +080014namespace persistent_data
15{
16
17struct UserSubscription
18{
Ed Tanous4b712a22023-08-02 12:56:52 -070019 // Represents a Redfish EventDestination instance
JunLin Chen28afb492021-02-24 17:13:29 +080020 std::string id;
Ed Tanousa716aa72023-08-01 11:35:53 -070021 boost::urls::url destinationUrl;
JunLin Chen28afb492021-02-24 17:13:29 +080022 std::string protocol;
Ed Tanous19bb3622024-07-05 10:07:40 -050023 bool verifyCertificate = true;
JunLin Chen28afb492021-02-24 17:13:29 +080024 std::string retryPolicy;
25 std::string customText;
26 std::string eventFormatType;
27 std::string subscriptionType;
28 std::vector<std::string> registryMsgIds;
29 std::vector<std::string> registryPrefixes;
30 std::vector<std::string> resourceTypes;
Ed Tanous601c71a2021-09-08 16:40:12 -070031 boost::beast::http::fields httpHeaders;
JunLin Chen28afb492021-02-24 17:13:29 +080032 std::vector<std::string> metricReportDefinitions;
Ed Tanousa14c9112024-09-04 10:46:47 -070033 std::vector<std::string> originResources;
JunLin Chen28afb492021-02-24 17:13:29 +080034
Ed Tanous4b712a22023-08-02 12:56:52 -070035 static std::optional<UserSubscription> fromJson(
Patrick Williamsbd79bce2024-08-16 15:22:20 -040036 const nlohmann::json::object_t& j, const bool loadFromOldConfig = false)
JunLin Chen28afb492021-02-24 17:13:29 +080037 {
Ed Tanous4b712a22023-08-02 12:56:52 -070038 UserSubscription subvalue;
Ed Tanous0bdda662023-08-03 17:27:34 -070039 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +080040 {
Ed Tanous0bdda662023-08-03 17:27:34 -070041 if (element.first == "Id")
JunLin Chen28afb492021-02-24 17:13:29 +080042 {
43 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070044 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080045 if (value == nullptr)
46 {
47 continue;
48 }
Ed Tanous4b712a22023-08-02 12:56:52 -070049 subvalue.id = *value;
JunLin Chen28afb492021-02-24 17:13:29 +080050 }
Ed Tanous0bdda662023-08-03 17:27:34 -070051 else if (element.first == "Destination")
JunLin Chen28afb492021-02-24 17:13:29 +080052 {
53 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070054 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080055 if (value == nullptr)
56 {
57 continue;
58 }
Ed Tanous6fd29552023-10-04 09:40:14 -070059 boost::system::result<boost::urls::url> url =
Ed Tanousa716aa72023-08-01 11:35:53 -070060 boost::urls::parse_absolute_uri(*value);
61 if (!url)
62 {
63 continue;
64 }
Ed Tanous4b712a22023-08-02 12:56:52 -070065 subvalue.destinationUrl = std::move(*url);
JunLin Chen28afb492021-02-24 17:13:29 +080066 }
Ed Tanous0bdda662023-08-03 17:27:34 -070067 else if (element.first == "Protocol")
JunLin Chen28afb492021-02-24 17:13:29 +080068 {
69 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070070 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080071 if (value == nullptr)
72 {
73 continue;
74 }
Ed Tanous4b712a22023-08-02 12:56:52 -070075 subvalue.protocol = *value;
JunLin Chen28afb492021-02-24 17:13:29 +080076 }
Ed Tanous19bb3622024-07-05 10:07:40 -050077 else if (element.first == "VerifyCertificate")
78 {
79 const bool* value = element.second.get_ptr<const bool*>();
80 if (value == nullptr)
81 {
82 continue;
83 }
Ed Tanous4b712a22023-08-02 12:56:52 -070084 subvalue.verifyCertificate = *value;
Ed Tanous19bb3622024-07-05 10:07:40 -050085 }
Ed Tanous0bdda662023-08-03 17:27:34 -070086 else if (element.first == "DeliveryRetryPolicy")
JunLin Chen28afb492021-02-24 17:13:29 +080087 {
88 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070089 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +080090 if (value == nullptr)
91 {
92 continue;
93 }
Ed Tanous4b712a22023-08-02 12:56:52 -070094 subvalue.retryPolicy = *value;
JunLin Chen28afb492021-02-24 17:13:29 +080095 }
Ed Tanous0bdda662023-08-03 17:27:34 -070096 else if (element.first == "Context")
JunLin Chen28afb492021-02-24 17:13:29 +080097 {
98 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -070099 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800100 if (value == nullptr)
101 {
102 continue;
103 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700104 subvalue.customText = *value;
JunLin Chen28afb492021-02-24 17:13:29 +0800105 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700106 else if (element.first == "EventFormatType")
JunLin Chen28afb492021-02-24 17:13:29 +0800107 {
108 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700109 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800110 if (value == nullptr)
111 {
112 continue;
113 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700114 subvalue.eventFormatType = *value;
JunLin Chen28afb492021-02-24 17:13:29 +0800115 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700116 else if (element.first == "SubscriptionType")
JunLin Chen28afb492021-02-24 17:13:29 +0800117 {
118 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700119 element.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800120 if (value == nullptr)
121 {
122 continue;
123 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700124 subvalue.subscriptionType = *value;
JunLin Chen28afb492021-02-24 17:13:29 +0800125 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700126 else if (element.first == "MessageIds")
JunLin Chen28afb492021-02-24 17:13:29 +0800127 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700128 const nlohmann::json::array_t* obj =
129 element.second.get_ptr<const nlohmann::json::array_t*>();
130 if (obj == nullptr)
131 {
132 continue;
133 }
134 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800135 {
136 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700137 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800138 if (value == nullptr)
139 {
140 continue;
141 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700142 subvalue.registryMsgIds.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800143 }
144 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700145 else if (element.first == "RegistryPrefixes")
JunLin Chen28afb492021-02-24 17:13:29 +0800146 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700147 const nlohmann::json::array_t* obj =
148 element.second.get_ptr<const nlohmann::json::array_t*>();
149 if (obj == nullptr)
150 {
151 continue;
152 }
153 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800154 {
155 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700156 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800157 if (value == nullptr)
158 {
159 continue;
160 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700161 subvalue.registryPrefixes.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800162 }
163 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700164 else if (element.first == "ResourceTypes")
JunLin Chen28afb492021-02-24 17:13:29 +0800165 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700166 const nlohmann::json::array_t* obj =
167 element.second.get_ptr<const nlohmann::json::array_t*>();
168 if (obj == nullptr)
169 {
170 continue;
171 }
172 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800173 {
174 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700175 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800176 if (value == nullptr)
177 {
178 continue;
179 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700180 subvalue.resourceTypes.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800181 }
182 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700183 else if (element.first == "HttpHeaders")
JunLin Chen28afb492021-02-24 17:13:29 +0800184 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700185 const nlohmann::json::object_t* obj =
186 element.second.get_ptr<const nlohmann::json::object_t*>();
187 if (obj == nullptr)
188 {
189 continue;
190 }
191 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800192 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700193 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700194 val.second.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800195 if (value == nullptr)
196 {
Ed Tanous62598e32023-07-17 17:06:25 -0700197 BMCWEB_LOG_ERROR("Failed to parse value for key{}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700198 val.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800199 continue;
200 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700201 subvalue.httpHeaders.set(val.first, *value);
JunLin Chen28afb492021-02-24 17:13:29 +0800202 }
203 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700204 else if (element.first == "MetricReportDefinitions")
JunLin Chen28afb492021-02-24 17:13:29 +0800205 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700206 const nlohmann::json::array_t* obj =
207 element.second.get_ptr<const nlohmann::json::array_t*>();
208 if (obj == nullptr)
209 {
210 continue;
211 }
212 for (const auto& val : *obj)
JunLin Chen28afb492021-02-24 17:13:29 +0800213 {
214 const std::string* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700215 val.get_ptr<const std::string*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800216 if (value == nullptr)
217 {
218 continue;
219 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700220 subvalue.metricReportDefinitions.emplace_back(*value);
JunLin Chen28afb492021-02-24 17:13:29 +0800221 }
222 }
Ed Tanousa14c9112024-09-04 10:46:47 -0700223 else if (element.first == "OriginResources")
224 {
225 const nlohmann::json::array_t* obj =
226 element.second.get_ptr<const nlohmann::json::array_t*>();
227 if (obj == nullptr)
228 {
229 continue;
230 }
231 for (const auto& val : *obj)
232 {
233 const std::string* value =
234 val.get_ptr<const std::string*>();
235 if (value == nullptr)
236 {
237 continue;
238 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700239 subvalue.originResources.emplace_back(*value);
Ed Tanousa14c9112024-09-04 10:46:47 -0700240 }
241 }
JunLin Chen28afb492021-02-24 17:13:29 +0800242 else
243 {
Ed Tanous62598e32023-07-17 17:06:25 -0700244 BMCWEB_LOG_ERROR(
245 "Got unexpected property reading persistent file: {}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700246 element.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800247 continue;
248 }
249 }
250
Ed Tanous4b712a22023-08-02 12:56:52 -0700251 if ((subvalue.id.empty() && !loadFromOldConfig) ||
252 subvalue.destinationUrl.empty() || subvalue.protocol.empty() ||
253 subvalue.retryPolicy.empty() || subvalue.eventFormatType.empty() ||
254 subvalue.subscriptionType.empty())
JunLin Chen28afb492021-02-24 17:13:29 +0800255 {
Ed Tanous62598e32023-07-17 17:06:25 -0700256 BMCWEB_LOG_ERROR("Subscription missing required field "
257 "information, refusing to restore");
Ed Tanous4b712a22023-08-02 12:56:52 -0700258 return std::nullopt;
JunLin Chen28afb492021-02-24 17:13:29 +0800259 }
260
261 return subvalue;
262 }
263};
264
265struct EventServiceConfig
266{
267 bool enabled = true;
268 uint32_t retryAttempts = 3;
269 uint32_t retryTimeoutInterval = 30;
270
Ed Tanous0bdda662023-08-03 17:27:34 -0700271 void fromJson(const nlohmann::json::object_t& j)
JunLin Chen28afb492021-02-24 17:13:29 +0800272 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700273 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +0800274 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700275 if (element.first == "ServiceEnabled")
JunLin Chen28afb492021-02-24 17:13:29 +0800276 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700277 const bool* value = element.second.get_ptr<const bool*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800278 if (value == nullptr)
279 {
280 continue;
281 }
282 enabled = *value;
283 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700284 else if (element.first == "DeliveryRetryAttempts")
JunLin Chen28afb492021-02-24 17:13:29 +0800285 {
286 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700287 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800288 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800289 (*value > std::numeric_limits<uint32_t>::max()))
290 {
291 continue;
292 }
293 retryAttempts = static_cast<uint32_t>(*value);
294 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700295 else if (element.first == "DeliveryRetryIntervalSeconds")
JunLin Chen28afb492021-02-24 17:13:29 +0800296 {
297 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700298 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800299 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800300 (*value > std::numeric_limits<uint32_t>::max()))
301 {
302 continue;
303 }
304 retryTimeoutInterval = static_cast<uint32_t>(*value);
305 }
306 }
307 }
308};
309
310class EventServiceStore
311{
312 public:
Myung Bae5fe4ef32024-10-19 09:56:02 -0400313 boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
JunLin Chen28afb492021-02-24 17:13:29 +0800314 subscriptionsConfigMap;
315 EventServiceConfig eventServiceConfig;
316
317 static EventServiceStore& getInstance()
318 {
319 static EventServiceStore eventServiceStore;
320 return eventServiceStore;
321 }
322
323 EventServiceConfig& getEventServiceConfig()
324 {
325 return eventServiceConfig;
326 }
JunLin Chen28afb492021-02-24 17:13:29 +0800327};
328
329} // namespace persistent_data