blob: b27c6e061dc468230b95ac6db979a4405747b5ee [file] [log] [blame]
AppaRao Pulie5aaf042020-03-20 01:05:52 +05301/*
2// Copyright (c) 2020 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
AppaRao Pulib52664e2020-04-09 21:36:51 +053017#include "event_service_manager.hpp"
AppaRao Pulie5aaf042020-03-20 01:05:52 +053018
19namespace redfish
20{
21
AppaRao Puli156d6b02020-04-25 06:04:05 +053022static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
23 eventFormatType, metricReportFormatType};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053024static constexpr const std::array<const char*, 3> supportedRegPrefixes = {
25 "Base", "OpenBMC", "Task"};
26static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
27 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
28
29static constexpr const uint8_t maxNoOfSubscriptions = 20;
30
AppaRao Pulie5aaf042020-03-20 01:05:52 +053031class EventService : public Node
32{
33 public:
34 EventService(CrowApp& app) : Node(app, "/redfish/v1/EventService/")
35 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +053036 entityPrivileges = {
37 {boost::beast::http::verb::get, {{"Login"}}},
38 {boost::beast::http::verb::head, {{"Login"}}},
39 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
40 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
41 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
42 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
43 }
44
45 private:
46 void doGet(crow::Response& res, const crow::Request& req,
47 const std::vector<std::string>& params) override
48 {
49 auto asyncResp = std::make_shared<AsyncResp>(res);
50 res.jsonValue = {
51 {"@odata.type", "#EventService.v1_5_0.EventService"},
52 {"Id", "EventService"},
53 {"Name", "Event Service"},
54 {"ServerSentEventUri",
55 "/redfish/v1/EventService/Subscriptions/SSE"},
56 {"Subscriptions",
57 {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
AppaRao Puli0b4bdd92020-04-14 17:57:45 +053058 {"Actions",
59 {{"#EventService.SubmitTestEvent",
60 {{"target", "/redfish/v1/EventService/Actions/"
61 "EventService.SubmitTestEvent"}}}}},
AppaRao Pulie5aaf042020-03-20 01:05:52 +053062 {"@odata.id", "/redfish/v1/EventService"}};
63
AppaRao Puli7d1cc382020-05-16 02:42:22 +053064 const auto& [enabled, retryAttempts, retryTimeoutInterval] =
65 EventServiceManager::getInstance().getEventServiceConfig();
66
67 asyncResp->res.jsonValue["Status"]["State"] =
68 (enabled ? "Enabled" : "Disabled");
69 asyncResp->res.jsonValue["ServiceEnabled"] = enabled;
70 asyncResp->res.jsonValue["DeliveryRetryAttempts"] = retryAttempts;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053071 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
AppaRao Puli7d1cc382020-05-16 02:42:22 +053072 retryTimeoutInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053073 asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
74 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
Ayushi Smriti07941a82020-05-21 15:55:34 +053075
76 nlohmann::json supportedSSEFilters = {
77 {"EventFormatType", true}, {"MessageId", true},
78 {"MetricReportDefinition", true}, {"RegistryPrefix", true},
79 {"OriginResource", false}, {"ResourceType", false}};
80
81 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
82 supportedSSEFilters;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053083 }
84
85 void doPatch(crow::Response& res, const crow::Request& req,
86 const std::vector<std::string>& params) override
87 {
88 auto asyncResp = std::make_shared<AsyncResp>(res);
89
90 std::optional<bool> serviceEnabled;
91 std::optional<uint32_t> retryAttemps;
92 std::optional<uint32_t> retryInterval;
93
94 if (!json_util::readJson(req, res, "ServiceEnabled", serviceEnabled,
95 "DeliveryRetryAttempts", retryAttemps,
96 "DeliveryRetryIntervalSeconds", retryInterval))
97 {
98 return;
99 }
100
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530101 auto [enabled, retryCount, retryTimeoutInterval] =
102 EventServiceManager::getInstance().getEventServiceConfig();
103
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530104 if (serviceEnabled)
105 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530106 enabled = *serviceEnabled;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530107 }
108
109 if (retryAttemps)
110 {
111 // Supported range [1-3]
112 if ((*retryAttemps < 1) || (*retryAttemps > 3))
113 {
114 messages::queryParameterOutOfRange(
115 asyncResp->res, std::to_string(*retryAttemps),
116 "DeliveryRetryAttempts", "[1-3]");
117 }
118 else
119 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530120 retryCount = *retryAttemps;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530121 }
122 }
123
124 if (retryInterval)
125 {
126 // Supported range [30 - 180]
127 if ((*retryInterval < 30) || (*retryInterval > 180))
128 {
129 messages::queryParameterOutOfRange(
130 asyncResp->res, std::to_string(*retryInterval),
131 "DeliveryRetryIntervalSeconds", "[30-180]");
132 }
133 else
134 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530135 retryTimeoutInterval = *retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530136 }
137 }
138
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530139 EventServiceManager::getInstance().setEventServiceConfig(
140 std::make_tuple(enabled, retryCount, retryTimeoutInterval));
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530141 }
142};
143
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530144class SubmitTestEvent : public Node
145{
146 public:
147 SubmitTestEvent(CrowApp& app) :
148 Node(app,
149 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
150 {
151 entityPrivileges = {
152 {boost::beast::http::verb::get, {{"Login"}}},
153 {boost::beast::http::verb::head, {{"Login"}}},
154 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
155 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
156 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
157 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
158 }
159
160 private:
161 void doPost(crow::Response& res, const crow::Request& req,
162 const std::vector<std::string>& params) override
163 {
164 EventServiceManager::getInstance().sendTestEventLog();
165 res.result(boost::beast::http::status::no_content);
166 res.end();
167 }
168};
169
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530170class EventDestinationCollection : public Node
171{
172 public:
173 EventDestinationCollection(CrowApp& app) :
174 Node(app, "/redfish/v1/EventService/Subscriptions/")
175 {
176 entityPrivileges = {
177 {boost::beast::http::verb::get, {{"Login"}}},
178 {boost::beast::http::verb::head, {{"Login"}}},
179 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
180 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
181 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
182 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
183 }
184
185 private:
186 void doGet(crow::Response& res, const crow::Request& req,
187 const std::vector<std::string>& params) override
188 {
189 auto asyncResp = std::make_shared<AsyncResp>(res);
190
191 res.jsonValue = {
192 {"@odata.type",
193 "#EventDestinationCollection.EventDestinationCollection"},
194 {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
195 {"Name", "Event Destination Collections"}};
196
197 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530198
AppaRao Pulib52664e2020-04-09 21:36:51 +0530199 std::vector<std::string> subscripIds =
200 EventServiceManager::getInstance().getAllIDs();
201 memberArray = nlohmann::json::array();
202 asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
203
204 for (const std::string& id : subscripIds)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530205 {
206 memberArray.push_back(
207 {{"@odata.id",
AppaRao Pulib52664e2020-04-09 21:36:51 +0530208 "/redfish/v1/EventService/Subscriptions/" + id}});
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530209 }
210 }
211
212 void doPost(crow::Response& res, const crow::Request& req,
213 const std::vector<std::string>& params) override
214 {
215 auto asyncResp = std::make_shared<AsyncResp>(res);
216
AppaRao Pulib52664e2020-04-09 21:36:51 +0530217 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
218 maxNoOfSubscriptions)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530219 {
220 messages::eventSubscriptionLimitExceeded(asyncResp->res);
221 return;
222 }
223 std::string destUrl;
224 std::string protocol;
225 std::optional<std::string> context;
226 std::optional<std::string> subscriptionType;
227 std::optional<std::string> eventFormatType;
228 std::optional<std::string> retryPolicy;
229 std::optional<std::vector<std::string>> msgIds;
230 std::optional<std::vector<std::string>> regPrefixes;
231 std::optional<std::vector<nlohmann::json>> headers;
AppaRao Puli156d6b02020-04-25 06:04:05 +0530232 std::optional<std::vector<nlohmann::json>> metricReportDefinitions;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530233
234 if (!json_util::readJson(
235 req, res, "Destination", destUrl, "Context", context,
236 "Protocol", protocol, "SubscriptionType", subscriptionType,
237 "EventFormatType", eventFormatType, "HttpHeaders", headers,
238 "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
AppaRao Puli156d6b02020-04-25 06:04:05 +0530239 "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
240 metricReportDefinitions))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530241 {
242 return;
243 }
244
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530245 // Validate the URL using regex expression
AppaRao Pulib52664e2020-04-09 21:36:51 +0530246 // Format: <protocol>://<host>:<port>/<uri>
247 // protocol: http/https
248 // host: Exclude ' ', ':', '#', '?'
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500249 // port: Empty or numeric value with ':' separator.
AppaRao Pulib52664e2020-04-09 21:36:51 +0530250 // uri: Start with '/' and Exclude '#', ' '
251 // Can include query params(ex: '/event?test=1')
252 // TODO: Need to validate hostname extensively(as per rfc)
253 const std::regex urlRegex(
254 "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
255 "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
256 std::cmatch match;
257 if (!std::regex_match(destUrl.c_str(), match, urlRegex))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530258 {
259 messages::propertyValueFormatError(asyncResp->res, destUrl,
260 "Destination");
261 return;
262 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530263
264 std::string uriProto = std::string(match[1].first, match[1].second);
265 if (uriProto == "http")
266 {
267#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
268 messages::propertyValueFormatError(asyncResp->res, destUrl,
269 "Destination");
270 return;
271#endif
272 }
273
274 std::string host = std::string(match[2].first, match[2].second);
275 std::string port = std::string(match[3].first, match[3].second);
276 std::string path = std::string(match[4].first, match[4].second);
277 if (port.empty())
278 {
279 if (uriProto == "http")
280 {
281 port = "80";
282 }
283 else
284 {
285 port = "443";
286 }
287 }
288 if (path.empty())
289 {
290 path = "/";
291 }
292
293 std::shared_ptr<Subscription> subValue =
294 std::make_shared<Subscription>(host, port, path, uriProto);
295
296 subValue->destinationUrl = destUrl;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530297
298 if (subscriptionType)
299 {
300 if (*subscriptionType != "RedfishEvent")
301 {
302 messages::propertyValueNotInList(
303 asyncResp->res, *subscriptionType, "SubscriptionType");
304 return;
305 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530306 subValue->subscriptionType = *subscriptionType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530307 }
308 else
309 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530310 subValue->subscriptionType = "RedfishEvent"; // Default
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530311 }
312
313 if (protocol != "Redfish")
314 {
315 messages::propertyValueNotInList(asyncResp->res, protocol,
316 "Protocol");
317 return;
318 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530319 subValue->protocol = protocol;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530320
321 if (eventFormatType)
322 {
323 if (std::find(supportedEvtFormatTypes.begin(),
324 supportedEvtFormatTypes.end(),
325 *eventFormatType) == supportedEvtFormatTypes.end())
326 {
327 messages::propertyValueNotInList(
328 asyncResp->res, *eventFormatType, "EventFormatType");
329 return;
330 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530331 subValue->eventFormatType = *eventFormatType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530332 }
333 else
334 {
335 // If not specified, use default "Event"
AppaRao Pulib52664e2020-04-09 21:36:51 +0530336 subValue->eventFormatType.assign({"Event"});
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530337 }
338
339 if (context)
340 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530341 subValue->customText = *context;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530342 }
343
344 if (headers)
345 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530346 subValue->httpHeaders = *headers;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530347 }
348
349 if (regPrefixes)
350 {
351 for (const std::string& it : *regPrefixes)
352 {
353 if (std::find(supportedRegPrefixes.begin(),
354 supportedRegPrefixes.end(),
355 it) == supportedRegPrefixes.end())
356 {
357 messages::propertyValueNotInList(asyncResp->res, it,
358 "RegistryPrefixes");
359 return;
360 }
361 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530362 subValue->registryPrefixes = *regPrefixes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530363 }
364
365 if (msgIds)
366 {
367 // Do we need to loop-up MessageRegistry and validate
368 // data for authenticity??? Not mandate, i believe.
AppaRao Pulib52664e2020-04-09 21:36:51 +0530369 subValue->registryMsgIds = *msgIds;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530370 }
371
372 if (retryPolicy)
373 {
374 if (std::find(supportedRetryPolicies.begin(),
375 supportedRetryPolicies.end(),
376 *retryPolicy) == supportedRetryPolicies.end())
377 {
378 messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
379 "DeliveryRetryPolicy");
380 return;
381 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530382 subValue->retryPolicy = *retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530383 }
384 else
385 {
386 // Default "TerminateAfterRetries"
AppaRao Pulib52664e2020-04-09 21:36:51 +0530387 subValue->retryPolicy = "TerminateAfterRetries";
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530388 }
389
AppaRao Puli156d6b02020-04-25 06:04:05 +0530390 if (metricReportDefinitions)
391 {
392 subValue->metricReportDefinitions = *metricReportDefinitions;
393 }
394
AppaRao Pulib52664e2020-04-09 21:36:51 +0530395 std::string id =
396 EventServiceManager::getInstance().addSubscription(subValue);
397 if (id.empty())
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530398 {
399 messages::internalError(asyncResp->res);
400 return;
401 }
402
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530403 messages::created(asyncResp->res);
404 asyncResp->res.addHeader(
405 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
406 }
407};
408
AppaRao Puli4bbf2372020-05-15 21:09:54 +0530409class EventServiceSSE : public Node
410{
411 public:
412 EventServiceSSE(CrowApp& app) :
413 Node(app, "/redfish/v1/EventService/Subscriptions/SSE/")
414 {
415 entityPrivileges = {
416 {boost::beast::http::verb::get, {{"ConfigureManager"}}},
417 {boost::beast::http::verb::head, {{"ConfigureManager"}}},
418 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
419 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
420 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
421 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
422 }
423
424 private:
425 void doGet(crow::Response& res, const crow::Request& req,
426 const std::vector<std::string>& params) override
427 {
428 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
429 maxNoOfSubscriptions)
430 {
431 messages::eventSubscriptionLimitExceeded(res);
432 res.end();
433 return;
434 }
435
436 std::shared_ptr<crow::Request::Adaptor> sseConn =
437 std::make_shared<crow::Request::Adaptor>(std::move(req.socket()));
438 std::shared_ptr<Subscription> subValue =
439 std::make_shared<Subscription>(sseConn);
440
441 // GET on this URI means, Its SSE subscriptionType.
442 subValue->subscriptionType = "SSE";
Ayushi Smriti07941a82020-05-21 15:55:34 +0530443
444 // Default values
AppaRao Puli4bbf2372020-05-15 21:09:54 +0530445 subValue->protocol = "Redfish";
Ayushi Smriti07941a82020-05-21 15:55:34 +0530446 subValue->retryPolicy = "TerminateAfterRetries";
AppaRao Puli4bbf2372020-05-15 21:09:54 +0530447
448 char* filters = req.urlParams.get("$filter");
449 if (filters == nullptr)
450 {
451 subValue->eventFormatType = "Event";
AppaRao Puli4bbf2372020-05-15 21:09:54 +0530452 }
453 else
454 {
Ayushi Smriti07941a82020-05-21 15:55:34 +0530455 // Reading from query params.
456 bool status = readSSEQueryParams(
457 filters, subValue->eventFormatType, subValue->registryMsgIds,
458 subValue->registryPrefixes, subValue->metricReportDefinitions);
459
460 if (!status)
461 {
462 messages::invalidObject(res, filters);
463 return;
464 }
465
466 if (!subValue->eventFormatType.empty())
467 {
468 if (std::find(supportedEvtFormatTypes.begin(),
469 supportedEvtFormatTypes.end(),
470 subValue->eventFormatType) ==
471 supportedEvtFormatTypes.end())
472 {
473 messages::propertyValueNotInList(
474 res, subValue->eventFormatType, "EventFormatType");
475 return;
476 }
477 }
478 else
479 {
480 // If nothing specified, using default "Event"
481 subValue->eventFormatType.assign({"Event"});
482 }
483
484 if (!subValue->registryPrefixes.empty())
485 {
486 for (const std::string& it : subValue->registryPrefixes)
487 {
488 if (std::find(supportedRegPrefixes.begin(),
489 supportedRegPrefixes.end(),
490 it) == supportedRegPrefixes.end())
491 {
492 messages::propertyValueNotInList(res, it,
493 "RegistryPrefixes");
494 return;
495 }
496 }
497 }
AppaRao Puli4bbf2372020-05-15 21:09:54 +0530498 }
499
500 std::string id =
501 EventServiceManager::getInstance().addSubscription(subValue, false);
502 if (id.empty())
503 {
504 messages::internalError(res);
505 res.end();
506 return;
507 }
508 }
509};
510
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530511class EventDestination : public Node
512{
513 public:
514 EventDestination(CrowApp& app) :
515 Node(app, "/redfish/v1/EventService/Subscriptions/<str>/",
516 std::string())
517 {
518 entityPrivileges = {
519 {boost::beast::http::verb::get, {{"Login"}}},
520 {boost::beast::http::verb::head, {{"Login"}}},
521 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
522 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
523 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
524 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
525 }
526
527 private:
528 void doGet(crow::Response& res, const crow::Request& req,
529 const std::vector<std::string>& params) override
530 {
531 auto asyncResp = std::make_shared<AsyncResp>(res);
532 if (params.size() != 1)
533 {
534 messages::internalError(asyncResp->res);
535 return;
536 }
537
AppaRao Pulib52664e2020-04-09 21:36:51 +0530538 std::shared_ptr<Subscription> subValue =
539 EventServiceManager::getInstance().getSubscription(params[0]);
540 if (subValue == nullptr)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530541 {
542 res.result(boost::beast::http::status::not_found);
543 res.end();
544 return;
545 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530546 const std::string& id = params[0];
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530547
548 res.jsonValue = {
549 {"@odata.type", "#EventDestination.v1_7_0.EventDestination"},
550 {"Protocol", "Redfish"}};
551 asyncResp->res.jsonValue["@odata.id"] =
552 "/redfish/v1/EventService/Subscriptions/" + id;
553 asyncResp->res.jsonValue["Id"] = id;
554 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
AppaRao Pulib52664e2020-04-09 21:36:51 +0530555 asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
556 asyncResp->res.jsonValue["Context"] = subValue->customText;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530557 asyncResp->res.jsonValue["SubscriptionType"] =
AppaRao Pulib52664e2020-04-09 21:36:51 +0530558 subValue->subscriptionType;
559 asyncResp->res.jsonValue["HttpHeaders"] = subValue->httpHeaders;
560 asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530561 asyncResp->res.jsonValue["RegistryPrefixes"] =
AppaRao Pulib52664e2020-04-09 21:36:51 +0530562 subValue->registryPrefixes;
563 asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
564 asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
AppaRao Puli156d6b02020-04-25 06:04:05 +0530565 asyncResp->res.jsonValue["MetricReportDefinitions"] =
566 subValue->metricReportDefinitions;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530567 }
568
569 void doPatch(crow::Response& res, const crow::Request& req,
570 const std::vector<std::string>& params) override
571 {
572 auto asyncResp = std::make_shared<AsyncResp>(res);
573 if (params.size() != 1)
574 {
575 messages::internalError(asyncResp->res);
576 return;
577 }
578
AppaRao Pulib52664e2020-04-09 21:36:51 +0530579 std::shared_ptr<Subscription> subValue =
580 EventServiceManager::getInstance().getSubscription(params[0]);
581 if (subValue == nullptr)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530582 {
583 res.result(boost::beast::http::status::not_found);
584 res.end();
585 return;
586 }
587
588 std::optional<std::string> context;
589 std::optional<std::string> retryPolicy;
590 std::optional<std::vector<nlohmann::json>> headers;
591
592 if (!json_util::readJson(req, res, "Context", context,
593 "DeliveryRetryPolicy", retryPolicy,
594 "HttpHeaders", headers))
595 {
596 return;
597 }
598
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530599 if (context)
600 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530601 subValue->customText = *context;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530602 }
603
604 if (headers)
605 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530606 subValue->httpHeaders = *headers;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530607 }
608
609 if (retryPolicy)
610 {
611 if (std::find(supportedRetryPolicies.begin(),
612 supportedRetryPolicies.end(),
613 *retryPolicy) == supportedRetryPolicies.end())
614 {
615 messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
616 "DeliveryRetryPolicy");
617 return;
618 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530619 subValue->retryPolicy = *retryPolicy;
Ayushi Smritife44eb02020-05-15 15:24:45 +0530620 subValue->updateRetryPolicy();
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530621 }
622
AppaRao Pulib52664e2020-04-09 21:36:51 +0530623 EventServiceManager::getInstance().updateSubscriptionData();
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530624 }
625
626 void doDelete(crow::Response& res, const crow::Request& req,
627 const std::vector<std::string>& params) override
628 {
629 auto asyncResp = std::make_shared<AsyncResp>(res);
630
631 if (params.size() != 1)
632 {
633 messages::internalError(asyncResp->res);
634 return;
635 }
636
AppaRao Pulib52664e2020-04-09 21:36:51 +0530637 if (!EventServiceManager::getInstance().isSubscriptionExist(params[0]))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530638 {
639 res.result(boost::beast::http::status::not_found);
640 res.end();
641 return;
642 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530643 EventServiceManager::getInstance().deleteSubscription(params[0]);
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530644 }
645};
646
647} // namespace redfish