blob: f7b76d1b2258dc6f44776f0fbcae72c7624a29f3 [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
Sunitha Harishe56f2542020-07-22 02:38:59 -050029#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
30static constexpr const std::array<const char*, 2> supportedResourceTypes = {
31 "IBMConfigFile", "Task"};
32#else
33static constexpr const std::array<const char*, 1> supportedResourceTypes = {
34 "Task"};
35#endif
36
AppaRao Pulie5aaf042020-03-20 01:05:52 +053037static constexpr const uint8_t maxNoOfSubscriptions = 20;
38
AppaRao Pulie5aaf042020-03-20 01:05:52 +053039class EventService : public Node
40{
41 public:
Ed Tanous52cc1122020-07-18 13:51:21 -070042 EventService(App& app) : Node(app, "/redfish/v1/EventService/")
AppaRao Pulie5aaf042020-03-20 01:05:52 +053043 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +053044 entityPrivileges = {
45 {boost::beast::http::verb::get, {{"Login"}}},
46 {boost::beast::http::verb::head, {{"Login"}}},
47 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
48 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
49 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
50 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
51 }
52
53 private:
Ed Tanouscb13a392020-07-25 19:02:03 +000054 void doGet(crow::Response& res, const crow::Request&,
55 const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +053056 {
57 auto asyncResp = std::make_shared<AsyncResp>(res);
58 res.jsonValue = {
59 {"@odata.type", "#EventService.v1_5_0.EventService"},
60 {"Id", "EventService"},
61 {"Name", "Event Service"},
AppaRao Pulie5aaf042020-03-20 01:05:52 +053062 {"Subscriptions",
63 {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
AppaRao Puli0b4bdd92020-04-14 17:57:45 +053064 {"Actions",
65 {{"#EventService.SubmitTestEvent",
66 {{"target", "/redfish/v1/EventService/Actions/"
67 "EventService.SubmitTestEvent"}}}}},
AppaRao Pulie5aaf042020-03-20 01:05:52 +053068 {"@odata.id", "/redfish/v1/EventService"}};
69
AppaRao Puli7d1cc382020-05-16 02:42:22 +053070 const auto& [enabled, retryAttempts, retryTimeoutInterval] =
71 EventServiceManager::getInstance().getEventServiceConfig();
72
73 asyncResp->res.jsonValue["Status"]["State"] =
74 (enabled ? "Enabled" : "Disabled");
75 asyncResp->res.jsonValue["ServiceEnabled"] = enabled;
76 asyncResp->res.jsonValue["DeliveryRetryAttempts"] = retryAttempts;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053077 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
AppaRao Puli7d1cc382020-05-16 02:42:22 +053078 retryTimeoutInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053079 asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
80 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
Sunitha Harishe56f2542020-07-22 02:38:59 -050081 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
Ayushi Smriti07941a82020-05-21 15:55:34 +053082
83 nlohmann::json supportedSSEFilters = {
84 {"EventFormatType", true}, {"MessageId", true},
85 {"MetricReportDefinition", true}, {"RegistryPrefix", true},
86 {"OriginResource", false}, {"ResourceType", false}};
87
88 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
89 supportedSSEFilters;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053090 }
91
92 void doPatch(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +000093 const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +053094 {
95 auto asyncResp = std::make_shared<AsyncResp>(res);
96
97 std::optional<bool> serviceEnabled;
98 std::optional<uint32_t> retryAttemps;
99 std::optional<uint32_t> retryInterval;
100
101 if (!json_util::readJson(req, res, "ServiceEnabled", serviceEnabled,
102 "DeliveryRetryAttempts", retryAttemps,
103 "DeliveryRetryIntervalSeconds", retryInterval))
104 {
105 return;
106 }
107
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530108 auto [enabled, retryCount, retryTimeoutInterval] =
109 EventServiceManager::getInstance().getEventServiceConfig();
110
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530111 if (serviceEnabled)
112 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530113 enabled = *serviceEnabled;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530114 }
115
116 if (retryAttemps)
117 {
118 // Supported range [1-3]
119 if ((*retryAttemps < 1) || (*retryAttemps > 3))
120 {
121 messages::queryParameterOutOfRange(
122 asyncResp->res, std::to_string(*retryAttemps),
123 "DeliveryRetryAttempts", "[1-3]");
124 }
125 else
126 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530127 retryCount = *retryAttemps;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530128 }
129 }
130
131 if (retryInterval)
132 {
133 // Supported range [30 - 180]
134 if ((*retryInterval < 30) || (*retryInterval > 180))
135 {
136 messages::queryParameterOutOfRange(
137 asyncResp->res, std::to_string(*retryInterval),
138 "DeliveryRetryIntervalSeconds", "[30-180]");
139 }
140 else
141 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530142 retryTimeoutInterval = *retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530143 }
144 }
145
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530146 EventServiceManager::getInstance().setEventServiceConfig(
147 std::make_tuple(enabled, retryCount, retryTimeoutInterval));
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530148 }
149};
150
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530151class SubmitTestEvent : public Node
152{
153 public:
Ed Tanous52cc1122020-07-18 13:51:21 -0700154 SubmitTestEvent(App& app) :
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530155 Node(app,
156 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
157 {
158 entityPrivileges = {
159 {boost::beast::http::verb::get, {{"Login"}}},
160 {boost::beast::http::verb::head, {{"Login"}}},
161 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
162 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
163 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
164 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
165 }
166
167 private:
Ed Tanouscb13a392020-07-25 19:02:03 +0000168 void doPost(crow::Response& res, const crow::Request&,
169 const std::vector<std::string>&) override
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530170 {
171 EventServiceManager::getInstance().sendTestEventLog();
172 res.result(boost::beast::http::status::no_content);
173 res.end();
174 }
175};
176
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530177class EventDestinationCollection : public Node
178{
179 public:
Ed Tanous52cc1122020-07-18 13:51:21 -0700180 EventDestinationCollection(App& app) :
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530181 Node(app, "/redfish/v1/EventService/Subscriptions/")
182 {
183 entityPrivileges = {
184 {boost::beast::http::verb::get, {{"Login"}}},
185 {boost::beast::http::verb::head, {{"Login"}}},
186 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
187 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
188 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
189 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
190 }
191
192 private:
Ed Tanouscb13a392020-07-25 19:02:03 +0000193 void doGet(crow::Response& res, const crow::Request&,
194 const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530195 {
196 auto asyncResp = std::make_shared<AsyncResp>(res);
197
198 res.jsonValue = {
199 {"@odata.type",
200 "#EventDestinationCollection.EventDestinationCollection"},
201 {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
202 {"Name", "Event Destination Collections"}};
203
204 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530205
AppaRao Pulib52664e2020-04-09 21:36:51 +0530206 std::vector<std::string> subscripIds =
207 EventServiceManager::getInstance().getAllIDs();
208 memberArray = nlohmann::json::array();
209 asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
210
211 for (const std::string& id : subscripIds)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530212 {
213 memberArray.push_back(
214 {{"@odata.id",
AppaRao Pulib52664e2020-04-09 21:36:51 +0530215 "/redfish/v1/EventService/Subscriptions/" + id}});
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530216 }
217 }
218
219 void doPost(crow::Response& res, const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +0000220 const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530221 {
222 auto asyncResp = std::make_shared<AsyncResp>(res);
223
AppaRao Pulib52664e2020-04-09 21:36:51 +0530224 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
225 maxNoOfSubscriptions)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530226 {
227 messages::eventSubscriptionLimitExceeded(asyncResp->res);
228 return;
229 }
230 std::string destUrl;
231 std::string protocol;
232 std::optional<std::string> context;
233 std::optional<std::string> subscriptionType;
Ed Tanous23a21a12020-07-25 04:45:05 +0000234 std::optional<std::string> eventFormatType2;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530235 std::optional<std::string> retryPolicy;
236 std::optional<std::vector<std::string>> msgIds;
237 std::optional<std::vector<std::string>> regPrefixes;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500238 std::optional<std::vector<std::string>> resTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530239 std::optional<std::vector<nlohmann::json>> headers;
AppaRao Puli144b6312020-08-03 22:23:12 +0530240 std::optional<std::vector<nlohmann::json>> mrdJsonArray;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530241
242 if (!json_util::readJson(
243 req, res, "Destination", destUrl, "Context", context,
244 "Protocol", protocol, "SubscriptionType", subscriptionType,
Ed Tanous23a21a12020-07-25 04:45:05 +0000245 "EventFormatType", eventFormatType2, "HttpHeaders", headers,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530246 "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
AppaRao Puli156d6b02020-04-25 06:04:05 +0530247 "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
AppaRao Puli144b6312020-08-03 22:23:12 +0530248 mrdJsonArray, "ResourceTypes", resTypes))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530249 {
250 return;
251 }
252
AppaRao Pulidd28ba82020-09-08 01:53:21 +0530253 if (regPrefixes && msgIds)
254 {
255 if (regPrefixes->size() && msgIds->size())
256 {
257 messages::mutualExclusiveProperties(
258 asyncResp->res, "RegistryPrefixes", "MessageIds");
259 return;
260 }
261 }
262
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530263 // Validate the URL using regex expression
AppaRao Pulib52664e2020-04-09 21:36:51 +0530264 // Format: <protocol>://<host>:<port>/<uri>
265 // protocol: http/https
266 // host: Exclude ' ', ':', '#', '?'
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500267 // port: Empty or numeric value with ':' separator.
AppaRao Pulib52664e2020-04-09 21:36:51 +0530268 // uri: Start with '/' and Exclude '#', ' '
269 // Can include query params(ex: '/event?test=1')
270 // TODO: Need to validate hostname extensively(as per rfc)
271 const std::regex urlRegex(
272 "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
273 "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
274 std::cmatch match;
275 if (!std::regex_match(destUrl.c_str(), match, urlRegex))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530276 {
277 messages::propertyValueFormatError(asyncResp->res, destUrl,
278 "Destination");
279 return;
280 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530281
282 std::string uriProto = std::string(match[1].first, match[1].second);
283 if (uriProto == "http")
284 {
285#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
286 messages::propertyValueFormatError(asyncResp->res, destUrl,
287 "Destination");
288 return;
289#endif
290 }
291
292 std::string host = std::string(match[2].first, match[2].second);
293 std::string port = std::string(match[3].first, match[3].second);
294 std::string path = std::string(match[4].first, match[4].second);
295 if (port.empty())
296 {
297 if (uriProto == "http")
298 {
299 port = "80";
300 }
301 else
302 {
303 port = "443";
304 }
305 }
306 if (path.empty())
307 {
308 path = "/";
309 }
310
311 std::shared_ptr<Subscription> subValue =
312 std::make_shared<Subscription>(host, port, path, uriProto);
313
314 subValue->destinationUrl = destUrl;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530315
316 if (subscriptionType)
317 {
318 if (*subscriptionType != "RedfishEvent")
319 {
320 messages::propertyValueNotInList(
321 asyncResp->res, *subscriptionType, "SubscriptionType");
322 return;
323 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530324 subValue->subscriptionType = *subscriptionType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530325 }
326 else
327 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530328 subValue->subscriptionType = "RedfishEvent"; // Default
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530329 }
330
331 if (protocol != "Redfish")
332 {
333 messages::propertyValueNotInList(asyncResp->res, protocol,
334 "Protocol");
335 return;
336 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530337 subValue->protocol = protocol;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530338
Ed Tanous23a21a12020-07-25 04:45:05 +0000339 if (eventFormatType2)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530340 {
341 if (std::find(supportedEvtFormatTypes.begin(),
342 supportedEvtFormatTypes.end(),
Ed Tanous23a21a12020-07-25 04:45:05 +0000343 *eventFormatType2) == supportedEvtFormatTypes.end())
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530344 {
345 messages::propertyValueNotInList(
Ed Tanous23a21a12020-07-25 04:45:05 +0000346 asyncResp->res, *eventFormatType2, "EventFormatType");
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530347 return;
348 }
Ed Tanous23a21a12020-07-25 04:45:05 +0000349 subValue->eventFormatType = *eventFormatType2;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530350 }
351 else
352 {
353 // If not specified, use default "Event"
Ed Tanous23a21a12020-07-25 04:45:05 +0000354 subValue->eventFormatType = "Event";
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530355 }
356
357 if (context)
358 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530359 subValue->customText = *context;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530360 }
361
362 if (headers)
363 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530364 subValue->httpHeaders = *headers;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530365 }
366
367 if (regPrefixes)
368 {
369 for (const std::string& it : *regPrefixes)
370 {
371 if (std::find(supportedRegPrefixes.begin(),
372 supportedRegPrefixes.end(),
373 it) == supportedRegPrefixes.end())
374 {
375 messages::propertyValueNotInList(asyncResp->res, it,
376 "RegistryPrefixes");
377 return;
378 }
379 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530380 subValue->registryPrefixes = *regPrefixes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530381 }
382
Sunitha Harishe56f2542020-07-22 02:38:59 -0500383 if (resTypes)
384 {
385 for (const std::string& it : *resTypes)
386 {
387 if (std::find(supportedResourceTypes.begin(),
388 supportedResourceTypes.end(),
389 it) == supportedResourceTypes.end())
390 {
391 messages::propertyValueNotInList(asyncResp->res, it,
392 "ResourceTypes");
393 return;
394 }
395 }
396 subValue->resourceTypes = *resTypes;
397 }
398
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530399 if (msgIds)
400 {
401 // Do we need to loop-up MessageRegistry and validate
402 // data for authenticity??? Not mandate, i believe.
AppaRao Pulib52664e2020-04-09 21:36:51 +0530403 subValue->registryMsgIds = *msgIds;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530404 }
405
406 if (retryPolicy)
407 {
408 if (std::find(supportedRetryPolicies.begin(),
409 supportedRetryPolicies.end(),
410 *retryPolicy) == supportedRetryPolicies.end())
411 {
412 messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
413 "DeliveryRetryPolicy");
414 return;
415 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530416 subValue->retryPolicy = *retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530417 }
418 else
419 {
420 // Default "TerminateAfterRetries"
AppaRao Pulib52664e2020-04-09 21:36:51 +0530421 subValue->retryPolicy = "TerminateAfterRetries";
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530422 }
423
AppaRao Puli144b6312020-08-03 22:23:12 +0530424 if (mrdJsonArray)
AppaRao Puli156d6b02020-04-25 06:04:05 +0530425 {
AppaRao Puli144b6312020-08-03 22:23:12 +0530426 for (nlohmann::json& mrdObj : *mrdJsonArray)
427 {
428 std::string mrdUri;
429 if (json_util::getValueFromJsonObject(mrdObj, "@odata.id",
430 mrdUri))
431 {
432 subValue->metricReportDefinitions.emplace_back(mrdUri);
433 }
434 else
435 {
436 messages::propertyValueFormatError(
437 asyncResp->res, mrdObj.dump(),
438 "MetricReportDefinitions");
439 return;
440 }
441 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530442 }
443
AppaRao Pulib52664e2020-04-09 21:36:51 +0530444 std::string id =
445 EventServiceManager::getInstance().addSubscription(subValue);
446 if (id.empty())
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530447 {
448 messages::internalError(asyncResp->res);
449 return;
450 }
451
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530452 messages::created(asyncResp->res);
453 asyncResp->res.addHeader(
454 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
455 }
456};
457
458class EventDestination : public Node
459{
460 public:
Ed Tanous52cc1122020-07-18 13:51:21 -0700461 EventDestination(App& app) :
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530462 Node(app, "/redfish/v1/EventService/Subscriptions/<str>/",
463 std::string())
464 {
465 entityPrivileges = {
466 {boost::beast::http::verb::get, {{"Login"}}},
467 {boost::beast::http::verb::head, {{"Login"}}},
468 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
469 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
470 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
471 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
472 }
473
474 private:
Ed Tanouscb13a392020-07-25 19:02:03 +0000475 void doGet(crow::Response& res, const crow::Request&,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530476 const std::vector<std::string>& params) override
477 {
478 auto asyncResp = std::make_shared<AsyncResp>(res);
479 if (params.size() != 1)
480 {
481 messages::internalError(asyncResp->res);
482 return;
483 }
484
AppaRao Pulib52664e2020-04-09 21:36:51 +0530485 std::shared_ptr<Subscription> subValue =
486 EventServiceManager::getInstance().getSubscription(params[0]);
487 if (subValue == nullptr)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530488 {
489 res.result(boost::beast::http::status::not_found);
490 res.end();
491 return;
492 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530493 const std::string& id = params[0];
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530494
495 res.jsonValue = {
496 {"@odata.type", "#EventDestination.v1_7_0.EventDestination"},
497 {"Protocol", "Redfish"}};
498 asyncResp->res.jsonValue["@odata.id"] =
499 "/redfish/v1/EventService/Subscriptions/" + id;
500 asyncResp->res.jsonValue["Id"] = id;
501 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
AppaRao Pulib52664e2020-04-09 21:36:51 +0530502 asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
503 asyncResp->res.jsonValue["Context"] = subValue->customText;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530504 asyncResp->res.jsonValue["SubscriptionType"] =
AppaRao Pulib52664e2020-04-09 21:36:51 +0530505 subValue->subscriptionType;
506 asyncResp->res.jsonValue["HttpHeaders"] = subValue->httpHeaders;
507 asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530508 asyncResp->res.jsonValue["RegistryPrefixes"] =
AppaRao Pulib52664e2020-04-09 21:36:51 +0530509 subValue->registryPrefixes;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500510 asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes;
511
AppaRao Pulib52664e2020-04-09 21:36:51 +0530512 asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
513 asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
AppaRao Puli144b6312020-08-03 22:23:12 +0530514
515 std::vector<nlohmann::json> mrdJsonArray;
516 for (const auto& mdrUri : subValue->metricReportDefinitions)
517 {
518 mrdJsonArray.push_back({{"@odata.id", mdrUri}});
519 }
520 asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530521 }
522
523 void doPatch(crow::Response& res, const crow::Request& req,
524 const std::vector<std::string>& params) override
525 {
526 auto asyncResp = std::make_shared<AsyncResp>(res);
527 if (params.size() != 1)
528 {
529 messages::internalError(asyncResp->res);
530 return;
531 }
532
AppaRao Pulib52664e2020-04-09 21:36:51 +0530533 std::shared_ptr<Subscription> subValue =
534 EventServiceManager::getInstance().getSubscription(params[0]);
535 if (subValue == nullptr)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530536 {
537 res.result(boost::beast::http::status::not_found);
538 res.end();
539 return;
540 }
541
542 std::optional<std::string> context;
543 std::optional<std::string> retryPolicy;
544 std::optional<std::vector<nlohmann::json>> headers;
545
546 if (!json_util::readJson(req, res, "Context", context,
547 "DeliveryRetryPolicy", retryPolicy,
548 "HttpHeaders", headers))
549 {
550 return;
551 }
552
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530553 if (context)
554 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530555 subValue->customText = *context;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530556 }
557
558 if (headers)
559 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530560 subValue->httpHeaders = *headers;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530561 }
562
563 if (retryPolicy)
564 {
565 if (std::find(supportedRetryPolicies.begin(),
566 supportedRetryPolicies.end(),
567 *retryPolicy) == supportedRetryPolicies.end())
568 {
569 messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
570 "DeliveryRetryPolicy");
571 return;
572 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530573 subValue->retryPolicy = *retryPolicy;
Ayushi Smritife44eb02020-05-15 15:24:45 +0530574 subValue->updateRetryPolicy();
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530575 }
576
AppaRao Pulib52664e2020-04-09 21:36:51 +0530577 EventServiceManager::getInstance().updateSubscriptionData();
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530578 }
579
Ed Tanouscb13a392020-07-25 19:02:03 +0000580 void doDelete(crow::Response& res, const crow::Request&,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530581 const std::vector<std::string>& params) override
582 {
583 auto asyncResp = std::make_shared<AsyncResp>(res);
584
585 if (params.size() != 1)
586 {
587 messages::internalError(asyncResp->res);
588 return;
589 }
590
AppaRao Pulib52664e2020-04-09 21:36:51 +0530591 if (!EventServiceManager::getInstance().isSubscriptionExist(params[0]))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530592 {
593 res.result(boost::beast::http::status::not_found);
594 res.end();
595 return;
596 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530597 EventServiceManager::getInstance().deleteSubscription(params[0]);
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530598 }
599};
600
601} // namespace redfish