blob: d51adad5727803bb21ecb48744d6f791426b9ea8 [file] [log] [blame]
JunLin Chen28afb492021-02-24 17:13:29 +08001#pragma once
2#include "logging.hpp"
3
4#include <boost/container/flat_map.hpp>
5#include <nlohmann/json.hpp>
6
7namespace persistent_data
8{
9
10struct UserSubscription
11{
12 std::string id;
13 std::string destinationUrl;
14 std::string protocol;
15 std::string retryPolicy;
16 std::string customText;
17 std::string eventFormatType;
18 std::string subscriptionType;
19 std::vector<std::string> registryMsgIds;
20 std::vector<std::string> registryPrefixes;
21 std::vector<std::string> resourceTypes;
22 std::vector<nlohmann::json> httpHeaders; // key-value pair
23 std::vector<std::string> metricReportDefinitions;
24
25 static std::shared_ptr<UserSubscription>
26 fromJson(const nlohmann::json& j, const bool loadFromOldConfig = false)
27 {
28 std::shared_ptr<UserSubscription> subvalue =
29 std::make_shared<UserSubscription>();
30 for (const auto& element : j.items())
31 {
32 if (element.key() == "Id")
33 {
34 const std::string* value =
35 element.value().get_ptr<const std::string*>();
36 if (value == nullptr)
37 {
38 continue;
39 }
40 subvalue->id = *value;
41 }
42 else if (element.key() == "Destination")
43 {
44 const std::string* value =
45 element.value().get_ptr<const std::string*>();
46 if (value == nullptr)
47 {
48 continue;
49 }
50 subvalue->destinationUrl = *value;
51 }
52 else if (element.key() == "Protocol")
53 {
54 const std::string* value =
55 element.value().get_ptr<const std::string*>();
56 if (value == nullptr)
57 {
58 continue;
59 }
60 subvalue->protocol = *value;
61 }
62 else if (element.key() == "DeliveryRetryPolicy")
63 {
64 const std::string* value =
65 element.value().get_ptr<const std::string*>();
66 if (value == nullptr)
67 {
68 continue;
69 }
70 subvalue->retryPolicy = *value;
71 }
72 else if (element.key() == "Context")
73 {
74 const std::string* value =
75 element.value().get_ptr<const std::string*>();
76 if (value == nullptr)
77 {
78 continue;
79 }
80 subvalue->customText = *value;
81 }
82 else if (element.key() == "EventFormatType")
83 {
84 const std::string* value =
85 element.value().get_ptr<const std::string*>();
86 if (value == nullptr)
87 {
88 continue;
89 }
90 subvalue->eventFormatType = *value;
91 }
92 else if (element.key() == "SubscriptionType")
93 {
94 const std::string* value =
95 element.value().get_ptr<const std::string*>();
96 if (value == nullptr)
97 {
98 continue;
99 }
100 subvalue->subscriptionType = *value;
101 }
102 else if (element.key() == "MessageIds")
103 {
104 const auto& obj = element.value();
105 for (const auto& val : obj.items())
106 {
107 const std::string* value =
108 val.value().get_ptr<const std::string*>();
109 if (value == nullptr)
110 {
111 continue;
112 }
113 subvalue->registryMsgIds.emplace_back(*value);
114 }
115 }
116 else if (element.key() == "RegistryPrefixes")
117 {
118 const auto& obj = element.value();
119 for (const auto& val : obj.items())
120 {
121 const std::string* value =
122 val.value().get_ptr<const std::string*>();
123 if (value == nullptr)
124 {
125 continue;
126 }
127 subvalue->registryPrefixes.emplace_back(*value);
128 }
129 }
130 else if (element.key() == "ResourceTypes")
131 {
132 const auto& obj = element.value();
133 for (const auto& val : obj.items())
134 {
135 const std::string* value =
136 val.value().get_ptr<const std::string*>();
137 if (value == nullptr)
138 {
139 continue;
140 }
141 subvalue->resourceTypes.emplace_back(*value);
142 }
143 }
144 else if (element.key() == "HttpHeaders")
145 {
146 const auto& obj = element.value();
147 for (const auto& val : obj.items())
148 {
149 const auto value =
150 val.value().get_ptr<const nlohmann::json::object_t*>();
151 if (value == nullptr)
152 {
153 continue;
154 }
155 subvalue->httpHeaders.emplace_back(*value);
156 }
157 }
158 else if (element.key() == "MetricReportDefinitions")
159 {
160 const auto& obj = element.value();
161 for (const auto& val : obj.items())
162 {
163 const std::string* value =
164 val.value().get_ptr<const std::string*>();
165 if (value == nullptr)
166 {
167 continue;
168 }
169 subvalue->metricReportDefinitions.emplace_back(*value);
170 }
171 }
172 else
173 {
174 BMCWEB_LOG_ERROR
175 << "Got unexpected property reading persistent file: "
176 << element.key();
177 continue;
178 }
179 }
180
181 if ((subvalue->id.empty() && !loadFromOldConfig) ||
182 subvalue->destinationUrl.empty() || subvalue->protocol.empty() ||
183 subvalue->retryPolicy.empty() || subvalue->customText.empty() ||
184 subvalue->eventFormatType.empty() ||
185 subvalue->subscriptionType.empty() ||
186 (subvalue->registryPrefixes.empty() &&
187 subvalue->registryMsgIds.empty()))
188 {
189 BMCWEB_LOG_ERROR << "Subscription missing required field "
190 "information, refusing to restore";
191 return nullptr;
192 }
193
194 return subvalue;
195 }
196};
197
198struct EventServiceConfig
199{
200 bool enabled = true;
201 uint32_t retryAttempts = 3;
202 uint32_t retryTimeoutInterval = 30;
203
204 void fromJson(const nlohmann::json& j)
205 {
206 for (const auto& element : j.items())
207 {
208 if (element.key() == "ServiceEnabled")
209 {
210 const bool* value = element.value().get_ptr<const bool*>();
211 if (value == nullptr)
212 {
213 continue;
214 }
215 enabled = *value;
216 }
217 else if (element.key() == "DeliveryRetryAttempts")
218 {
219 const uint64_t* value =
220 element.value().get_ptr<const uint64_t*>();
221 if ((value == nullptr) ||
222 (*value < std::numeric_limits<uint32_t>::lowest()) ||
223 (*value > std::numeric_limits<uint32_t>::max()))
224 {
225 continue;
226 }
227 retryAttempts = static_cast<uint32_t>(*value);
228 }
229 else if (element.key() == "DeliveryRetryIntervalSeconds")
230 {
231 const uint64_t* value =
232 element.value().get_ptr<const uint64_t*>();
233 if ((value == nullptr) ||
234 (*value < std::numeric_limits<uint32_t>::lowest()) ||
235 (*value > std::numeric_limits<uint32_t>::max()))
236 {
237 continue;
238 }
239 retryTimeoutInterval = static_cast<uint32_t>(*value);
240 }
241 }
242 }
243};
244
245class EventServiceStore
246{
247 public:
248 boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
249 subscriptionsConfigMap;
250 EventServiceConfig eventServiceConfig;
251
252 static EventServiceStore& getInstance()
253 {
254 static EventServiceStore eventServiceStore;
255 return eventServiceStore;
256 }
257
258 EventServiceConfig& getEventServiceConfig()
259 {
260 return eventServiceConfig;
261 }
262};
263
264} // namespace persistent_data