blob: e59a7d8e85fcb1c0aed81d218a60b455512fcd6d [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
29 static std::shared_ptr<UserSubscription>
Ed Tanous0bdda662023-08-03 17:27:34 -070030 fromJson(const nlohmann::json::object_t& j,
31 const bool loadFromOldConfig = false)
JunLin Chen28afb492021-02-24 17:13:29 +080032 {
33 std::shared_ptr<UserSubscription> subvalue =
34 std::make_shared<UserSubscription>();
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 }
45 subvalue->id = *value;
46 }
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 }
61 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 }
71 subvalue->protocol = *value;
72 }
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 }
80 subvalue->verifyCertificate = *value;
81 }
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 }
90 subvalue->retryPolicy = *value;
91 }
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 }
100 subvalue->customText = *value;
101 }
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 }
110 subvalue->eventFormatType = *value;
111 }
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 }
120 subvalue->subscriptionType = *value;
121 }
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 }
138 subvalue->registryMsgIds.emplace_back(*value);
139 }
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 }
157 subvalue->registryPrefixes.emplace_back(*value);
158 }
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 }
176 subvalue->resourceTypes.emplace_back(*value);
177 }
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 Tanous0bdda662023-08-03 17:27:34 -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 }
216 subvalue->metricReportDefinitions.emplace_back(*value);
217 }
218 }
219 else
220 {
Ed Tanous62598e32023-07-17 17:06:25 -0700221 BMCWEB_LOG_ERROR(
222 "Got unexpected property reading persistent file: {}",
Ed Tanous0bdda662023-08-03 17:27:34 -0700223 element.first);
JunLin Chen28afb492021-02-24 17:13:29 +0800224 continue;
225 }
226 }
227
228 if ((subvalue->id.empty() && !loadFromOldConfig) ||
229 subvalue->destinationUrl.empty() || subvalue->protocol.empty() ||
Sunitha Harishe6a71652021-08-06 03:15:59 -0500230 subvalue->retryPolicy.empty() ||
JunLin Chen28afb492021-02-24 17:13:29 +0800231 subvalue->eventFormatType.empty() ||
Sunitha Harishe6a71652021-08-06 03:15:59 -0500232 subvalue->subscriptionType.empty())
JunLin Chen28afb492021-02-24 17:13:29 +0800233 {
Ed Tanous62598e32023-07-17 17:06:25 -0700234 BMCWEB_LOG_ERROR("Subscription missing required field "
235 "information, refusing to restore");
JunLin Chen28afb492021-02-24 17:13:29 +0800236 return nullptr;
237 }
238
239 return subvalue;
240 }
241};
242
243struct EventServiceConfig
244{
245 bool enabled = true;
246 uint32_t retryAttempts = 3;
247 uint32_t retryTimeoutInterval = 30;
248
Ed Tanous0bdda662023-08-03 17:27:34 -0700249 void fromJson(const nlohmann::json::object_t& j)
JunLin Chen28afb492021-02-24 17:13:29 +0800250 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700251 for (const auto& element : j)
JunLin Chen28afb492021-02-24 17:13:29 +0800252 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700253 if (element.first == "ServiceEnabled")
JunLin Chen28afb492021-02-24 17:13:29 +0800254 {
Ed Tanous0bdda662023-08-03 17:27:34 -0700255 const bool* value = element.second.get_ptr<const bool*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800256 if (value == nullptr)
257 {
258 continue;
259 }
260 enabled = *value;
261 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700262 else if (element.first == "DeliveryRetryAttempts")
JunLin Chen28afb492021-02-24 17:13:29 +0800263 {
264 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700265 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800266 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800267 (*value > std::numeric_limits<uint32_t>::max()))
268 {
269 continue;
270 }
271 retryAttempts = static_cast<uint32_t>(*value);
272 }
Ed Tanous0bdda662023-08-03 17:27:34 -0700273 else if (element.first == "DeliveryRetryIntervalSeconds")
JunLin Chen28afb492021-02-24 17:13:29 +0800274 {
275 const uint64_t* value =
Ed Tanous0bdda662023-08-03 17:27:34 -0700276 element.second.get_ptr<const uint64_t*>();
JunLin Chen28afb492021-02-24 17:13:29 +0800277 if ((value == nullptr) ||
JunLin Chen28afb492021-02-24 17:13:29 +0800278 (*value > std::numeric_limits<uint32_t>::max()))
279 {
280 continue;
281 }
282 retryTimeoutInterval = static_cast<uint32_t>(*value);
283 }
284 }
285 }
286};
287
288class EventServiceStore
289{
290 public:
291 boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
292 subscriptionsConfigMap;
293 EventServiceConfig eventServiceConfig;
294
295 static EventServiceStore& getInstance()
296 {
297 static EventServiceStore eventServiceStore;
298 return eventServiceStore;
299 }
300
301 EventServiceConfig& getEventServiceConfig()
302 {
303 return eventServiceConfig;
304 }
305};
306
307} // namespace persistent_data