blob: ad567ef135141db429eac69a58e0afa5611e5a11 [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:
zhanghch058d1b46d2021-04-01 11:18:24 +080054 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
55 const crow::Request&, const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +053056 {
zhanghch058d1b46d2021-04-01 11:18:24 +080057
58 asyncResp->res.jsonValue = {
AppaRao Pulie5aaf042020-03-20 01:05:52 +053059 {"@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
zhanghch058d1b46d2021-04-01 11:18:24 +080092 void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
93 const crow::Request& req,
Ed Tanouscb13a392020-07-25 19:02:03 +000094 const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +053095 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +053096
97 std::optional<bool> serviceEnabled;
98 std::optional<uint32_t> retryAttemps;
99 std::optional<uint32_t> retryInterval;
100
zhanghch058d1b46d2021-04-01 11:18:24 +0800101 if (!json_util::readJson(req, asyncResp->res, "ServiceEnabled",
102 serviceEnabled, "DeliveryRetryAttempts",
103 retryAttemps, "DeliveryRetryIntervalSeconds",
104 retryInterval))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530105 {
106 return;
107 }
108
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530109 auto [enabled, retryCount, retryTimeoutInterval] =
110 EventServiceManager::getInstance().getEventServiceConfig();
111
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530112 if (serviceEnabled)
113 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530114 enabled = *serviceEnabled;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530115 }
116
117 if (retryAttemps)
118 {
119 // Supported range [1-3]
120 if ((*retryAttemps < 1) || (*retryAttemps > 3))
121 {
122 messages::queryParameterOutOfRange(
123 asyncResp->res, std::to_string(*retryAttemps),
124 "DeliveryRetryAttempts", "[1-3]");
125 }
126 else
127 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530128 retryCount = *retryAttemps;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530129 }
130 }
131
132 if (retryInterval)
133 {
134 // Supported range [30 - 180]
135 if ((*retryInterval < 30) || (*retryInterval > 180))
136 {
137 messages::queryParameterOutOfRange(
138 asyncResp->res, std::to_string(*retryInterval),
139 "DeliveryRetryIntervalSeconds", "[30-180]");
140 }
141 else
142 {
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530143 retryTimeoutInterval = *retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530144 }
145 }
146
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530147 EventServiceManager::getInstance().setEventServiceConfig(
148 std::make_tuple(enabled, retryCount, retryTimeoutInterval));
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530149 }
150};
151
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530152class SubmitTestEvent : public Node
153{
154 public:
Ed Tanous52cc1122020-07-18 13:51:21 -0700155 SubmitTestEvent(App& app) :
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530156 Node(app,
157 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
158 {
159 entityPrivileges = {
160 {boost::beast::http::verb::get, {{"Login"}}},
161 {boost::beast::http::verb::head, {{"Login"}}},
162 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
163 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
164 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
165 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
166 }
167
168 private:
zhanghch058d1b46d2021-04-01 11:18:24 +0800169 void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
170 const crow::Request&, const std::vector<std::string>&) override
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530171 {
172 EventServiceManager::getInstance().sendTestEventLog();
zhanghch058d1b46d2021-04-01 11:18:24 +0800173 asyncResp->res.result(boost::beast::http::status::no_content);
AppaRao Puli0b4bdd92020-04-14 17:57:45 +0530174 }
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:
zhanghch058d1b46d2021-04-01 11:18:24 +0800193 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
194 const crow::Request&, const std::vector<std::string>&) override
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530195 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530196
zhanghch058d1b46d2021-04-01 11:18:24 +0800197 asyncResp->res.jsonValue = {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530198 {"@odata.type",
199 "#EventDestinationCollection.EventDestinationCollection"},
200 {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
201 {"Name", "Event Destination Collections"}};
202
203 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530204
AppaRao Pulib52664e2020-04-09 21:36:51 +0530205 std::vector<std::string> subscripIds =
206 EventServiceManager::getInstance().getAllIDs();
207 memberArray = nlohmann::json::array();
208 asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
209
210 for (const std::string& id : subscripIds)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530211 {
212 memberArray.push_back(
213 {{"@odata.id",
AppaRao Pulib52664e2020-04-09 21:36:51 +0530214 "/redfish/v1/EventService/Subscriptions/" + id}});
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530215 }
216 }
217
zhanghch058d1b46d2021-04-01 11:18:24 +0800218 void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
219 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 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530222
AppaRao Pulib52664e2020-04-09 21:36:51 +0530223 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
224 maxNoOfSubscriptions)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530225 {
226 messages::eventSubscriptionLimitExceeded(asyncResp->res);
227 return;
228 }
229 std::string destUrl;
230 std::string protocol;
231 std::optional<std::string> context;
232 std::optional<std::string> subscriptionType;
Ed Tanous23a21a12020-07-25 04:45:05 +0000233 std::optional<std::string> eventFormatType2;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530234 std::optional<std::string> retryPolicy;
235 std::optional<std::vector<std::string>> msgIds;
236 std::optional<std::vector<std::string>> regPrefixes;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500237 std::optional<std::vector<std::string>> resTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530238 std::optional<std::vector<nlohmann::json>> headers;
AppaRao Puli144b6312020-08-03 22:23:12 +0530239 std::optional<std::vector<nlohmann::json>> mrdJsonArray;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530240
241 if (!json_util::readJson(
zhanghch058d1b46d2021-04-01 11:18:24 +0800242 req, asyncResp->res, "Destination", destUrl, "Context", context,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530243 "Protocol", protocol, "SubscriptionType", subscriptionType,
Ed Tanous23a21a12020-07-25 04:45:05 +0000244 "EventFormatType", eventFormatType2, "HttpHeaders", headers,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530245 "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
AppaRao Puli156d6b02020-04-25 06:04:05 +0530246 "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
AppaRao Puli144b6312020-08-03 22:23:12 +0530247 mrdJsonArray, "ResourceTypes", resTypes))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530248 {
249 return;
250 }
251
AppaRao Pulidd28ba82020-09-08 01:53:21 +0530252 if (regPrefixes && msgIds)
253 {
254 if (regPrefixes->size() && msgIds->size())
255 {
256 messages::mutualExclusiveProperties(
257 asyncResp->res, "RegistryPrefixes", "MessageIds");
258 return;
259 }
260 }
261
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530262 // Validate the URL using regex expression
AppaRao Pulib52664e2020-04-09 21:36:51 +0530263 // Format: <protocol>://<host>:<port>/<uri>
264 // protocol: http/https
265 // host: Exclude ' ', ':', '#', '?'
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500266 // port: Empty or numeric value with ':' separator.
AppaRao Pulib52664e2020-04-09 21:36:51 +0530267 // uri: Start with '/' and Exclude '#', ' '
268 // Can include query params(ex: '/event?test=1')
269 // TODO: Need to validate hostname extensively(as per rfc)
270 const std::regex urlRegex(
271 "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
272 "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
273 std::cmatch match;
274 if (!std::regex_match(destUrl.c_str(), match, urlRegex))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530275 {
276 messages::propertyValueFormatError(asyncResp->res, destUrl,
277 "Destination");
278 return;
279 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530280
281 std::string uriProto = std::string(match[1].first, match[1].second);
282 if (uriProto == "http")
283 {
284#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
285 messages::propertyValueFormatError(asyncResp->res, destUrl,
286 "Destination");
287 return;
288#endif
289 }
290
291 std::string host = std::string(match[2].first, match[2].second);
292 std::string port = std::string(match[3].first, match[3].second);
293 std::string path = std::string(match[4].first, match[4].second);
294 if (port.empty())
295 {
296 if (uriProto == "http")
297 {
298 port = "80";
299 }
300 else
301 {
302 port = "443";
303 }
304 }
305 if (path.empty())
306 {
307 path = "/";
308 }
309
310 std::shared_ptr<Subscription> subValue =
311 std::make_shared<Subscription>(host, port, path, uriProto);
312
313 subValue->destinationUrl = destUrl;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530314
315 if (subscriptionType)
316 {
317 if (*subscriptionType != "RedfishEvent")
318 {
319 messages::propertyValueNotInList(
320 asyncResp->res, *subscriptionType, "SubscriptionType");
321 return;
322 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530323 subValue->subscriptionType = *subscriptionType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530324 }
325 else
326 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530327 subValue->subscriptionType = "RedfishEvent"; // Default
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530328 }
329
330 if (protocol != "Redfish")
331 {
332 messages::propertyValueNotInList(asyncResp->res, protocol,
333 "Protocol");
334 return;
335 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530336 subValue->protocol = protocol;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530337
Ed Tanous23a21a12020-07-25 04:45:05 +0000338 if (eventFormatType2)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530339 {
340 if (std::find(supportedEvtFormatTypes.begin(),
341 supportedEvtFormatTypes.end(),
Ed Tanous23a21a12020-07-25 04:45:05 +0000342 *eventFormatType2) == supportedEvtFormatTypes.end())
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530343 {
344 messages::propertyValueNotInList(
Ed Tanous23a21a12020-07-25 04:45:05 +0000345 asyncResp->res, *eventFormatType2, "EventFormatType");
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530346 return;
347 }
Ed Tanous23a21a12020-07-25 04:45:05 +0000348 subValue->eventFormatType = *eventFormatType2;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530349 }
350 else
351 {
352 // If not specified, use default "Event"
Ed Tanous23a21a12020-07-25 04:45:05 +0000353 subValue->eventFormatType = "Event";
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530354 }
355
356 if (context)
357 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530358 subValue->customText = *context;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530359 }
360
361 if (headers)
362 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530363 subValue->httpHeaders = *headers;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530364 }
365
366 if (regPrefixes)
367 {
368 for (const std::string& it : *regPrefixes)
369 {
370 if (std::find(supportedRegPrefixes.begin(),
371 supportedRegPrefixes.end(),
372 it) == supportedRegPrefixes.end())
373 {
374 messages::propertyValueNotInList(asyncResp->res, it,
375 "RegistryPrefixes");
376 return;
377 }
378 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530379 subValue->registryPrefixes = *regPrefixes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530380 }
381
Sunitha Harishe56f2542020-07-22 02:38:59 -0500382 if (resTypes)
383 {
384 for (const std::string& it : *resTypes)
385 {
386 if (std::find(supportedResourceTypes.begin(),
387 supportedResourceTypes.end(),
388 it) == supportedResourceTypes.end())
389 {
390 messages::propertyValueNotInList(asyncResp->res, it,
391 "ResourceTypes");
392 return;
393 }
394 }
395 subValue->resourceTypes = *resTypes;
396 }
397
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530398 if (msgIds)
399 {
400 // Do we need to loop-up MessageRegistry and validate
401 // data for authenticity??? Not mandate, i believe.
AppaRao Pulib52664e2020-04-09 21:36:51 +0530402 subValue->registryMsgIds = *msgIds;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530403 }
404
405 if (retryPolicy)
406 {
407 if (std::find(supportedRetryPolicies.begin(),
408 supportedRetryPolicies.end(),
409 *retryPolicy) == supportedRetryPolicies.end())
410 {
411 messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
412 "DeliveryRetryPolicy");
413 return;
414 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530415 subValue->retryPolicy = *retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530416 }
417 else
418 {
419 // Default "TerminateAfterRetries"
AppaRao Pulib52664e2020-04-09 21:36:51 +0530420 subValue->retryPolicy = "TerminateAfterRetries";
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530421 }
422
AppaRao Puli144b6312020-08-03 22:23:12 +0530423 if (mrdJsonArray)
AppaRao Puli156d6b02020-04-25 06:04:05 +0530424 {
AppaRao Puli144b6312020-08-03 22:23:12 +0530425 for (nlohmann::json& mrdObj : *mrdJsonArray)
426 {
427 std::string mrdUri;
428 if (json_util::getValueFromJsonObject(mrdObj, "@odata.id",
429 mrdUri))
430 {
431 subValue->metricReportDefinitions.emplace_back(mrdUri);
432 }
433 else
434 {
435 messages::propertyValueFormatError(
Ed Tanous71f52d92021-02-19 08:51:17 -0800436 asyncResp->res,
437 mrdObj.dump(2, ' ', true,
438 nlohmann::json::error_handler_t::replace),
AppaRao Puli144b6312020-08-03 22:23:12 +0530439 "MetricReportDefinitions");
440 return;
441 }
442 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530443 }
444
AppaRao Pulib52664e2020-04-09 21:36:51 +0530445 std::string id =
446 EventServiceManager::getInstance().addSubscription(subValue);
447 if (id.empty())
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530448 {
449 messages::internalError(asyncResp->res);
450 return;
451 }
452
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530453 messages::created(asyncResp->res);
454 asyncResp->res.addHeader(
455 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
456 }
457};
458
459class EventDestination : public Node
460{
461 public:
Ed Tanous52cc1122020-07-18 13:51:21 -0700462 EventDestination(App& app) :
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530463 Node(app, "/redfish/v1/EventService/Subscriptions/<str>/",
464 std::string())
465 {
466 entityPrivileges = {
467 {boost::beast::http::verb::get, {{"Login"}}},
468 {boost::beast::http::verb::head, {{"Login"}}},
469 {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
470 {boost::beast::http::verb::put, {{"ConfigureManager"}}},
471 {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
472 {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
473 }
474
475 private:
zhanghch058d1b46d2021-04-01 11:18:24 +0800476 void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
477 const crow::Request&,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530478 const std::vector<std::string>& params) override
479 {
zhanghch058d1b46d2021-04-01 11:18:24 +0800480
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530481 if (params.size() != 1)
482 {
483 messages::internalError(asyncResp->res);
484 return;
485 }
486
AppaRao Pulib52664e2020-04-09 21:36:51 +0530487 std::shared_ptr<Subscription> subValue =
488 EventServiceManager::getInstance().getSubscription(params[0]);
489 if (subValue == nullptr)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530490 {
zhanghch058d1b46d2021-04-01 11:18:24 +0800491 asyncResp->res.result(boost::beast::http::status::not_found);
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530492 return;
493 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530494 const std::string& id = params[0];
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530495
zhanghch058d1b46d2021-04-01 11:18:24 +0800496 asyncResp->res.jsonValue = {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530497 {"@odata.type", "#EventDestination.v1_7_0.EventDestination"},
498 {"Protocol", "Redfish"}};
499 asyncResp->res.jsonValue["@odata.id"] =
500 "/redfish/v1/EventService/Subscriptions/" + id;
501 asyncResp->res.jsonValue["Id"] = id;
502 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
AppaRao Pulib52664e2020-04-09 21:36:51 +0530503 asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
504 asyncResp->res.jsonValue["Context"] = subValue->customText;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530505 asyncResp->res.jsonValue["SubscriptionType"] =
AppaRao Pulib52664e2020-04-09 21:36:51 +0530506 subValue->subscriptionType;
507 asyncResp->res.jsonValue["HttpHeaders"] = subValue->httpHeaders;
508 asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530509 asyncResp->res.jsonValue["RegistryPrefixes"] =
AppaRao Pulib52664e2020-04-09 21:36:51 +0530510 subValue->registryPrefixes;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500511 asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes;
512
AppaRao Pulib52664e2020-04-09 21:36:51 +0530513 asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
514 asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
AppaRao Puli144b6312020-08-03 22:23:12 +0530515
516 std::vector<nlohmann::json> mrdJsonArray;
517 for (const auto& mdrUri : subValue->metricReportDefinitions)
518 {
519 mrdJsonArray.push_back({{"@odata.id", mdrUri}});
520 }
521 asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530522 }
523
zhanghch058d1b46d2021-04-01 11:18:24 +0800524 void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
525 const crow::Request& req,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530526 const std::vector<std::string>& params) override
527 {
zhanghch058d1b46d2021-04-01 11:18:24 +0800528
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530529 if (params.size() != 1)
530 {
531 messages::internalError(asyncResp->res);
532 return;
533 }
534
AppaRao Pulib52664e2020-04-09 21:36:51 +0530535 std::shared_ptr<Subscription> subValue =
536 EventServiceManager::getInstance().getSubscription(params[0]);
537 if (subValue == nullptr)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530538 {
zhanghch058d1b46d2021-04-01 11:18:24 +0800539 asyncResp->res.result(boost::beast::http::status::not_found);
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530540 return;
541 }
542
543 std::optional<std::string> context;
544 std::optional<std::string> retryPolicy;
545 std::optional<std::vector<nlohmann::json>> headers;
546
zhanghch058d1b46d2021-04-01 11:18:24 +0800547 if (!json_util::readJson(req, asyncResp->res, "Context", context,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530548 "DeliveryRetryPolicy", retryPolicy,
549 "HttpHeaders", headers))
550 {
551 return;
552 }
553
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530554 if (context)
555 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530556 subValue->customText = *context;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530557 }
558
559 if (headers)
560 {
AppaRao Pulib52664e2020-04-09 21:36:51 +0530561 subValue->httpHeaders = *headers;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530562 }
563
564 if (retryPolicy)
565 {
566 if (std::find(supportedRetryPolicies.begin(),
567 supportedRetryPolicies.end(),
568 *retryPolicy) == supportedRetryPolicies.end())
569 {
570 messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
571 "DeliveryRetryPolicy");
572 return;
573 }
AppaRao Pulib52664e2020-04-09 21:36:51 +0530574 subValue->retryPolicy = *retryPolicy;
Ayushi Smritife44eb02020-05-15 15:24:45 +0530575 subValue->updateRetryPolicy();
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530576 }
577
AppaRao Pulib52664e2020-04-09 21:36:51 +0530578 EventServiceManager::getInstance().updateSubscriptionData();
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530579 }
580
zhanghch058d1b46d2021-04-01 11:18:24 +0800581 void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
582 const crow::Request&,
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530583 const std::vector<std::string>& params) override
584 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530585
586 if (params.size() != 1)
587 {
588 messages::internalError(asyncResp->res);
589 return;
590 }
591
AppaRao Pulib52664e2020-04-09 21:36:51 +0530592 if (!EventServiceManager::getInstance().isSubscriptionExist(params[0]))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530593 {
zhanghch058d1b46d2021-04-01 11:18:24 +0800594 asyncResp->res.result(boost::beast::http::status::not_found);
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530595 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