blob: 51c999f087e37fcf6fe88f1d5f9e46c55d7faa3b [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
John Edward Broadbent7e860f12021-04-08 15:57:16 -070019#include <app.hpp>
Ed Tanous601c71a2021-09-08 16:40:12 -070020#include <boost/beast/http/fields.hpp>
Ed Tanouseb1c47d2022-02-09 11:47:27 -080021#include <http/utility.hpp>
22#include <logging.hpp>
Ed Tanous45ca1b82022-03-25 13:07:27 -070023#include <query.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070024#include <registries/privilege_registry.hpp>
25
Patrick Williams1e270c52021-12-04 06:06:56 -060026#include <span>
27
AppaRao Pulie5aaf042020-03-20 01:05:52 +053028namespace redfish
29{
30
AppaRao Puli156d6b02020-04-25 06:04:05 +053031static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
32 eventFormatType, metricReportFormatType};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053033static constexpr const std::array<const char*, 3> supportedRegPrefixes = {
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +053034 "Base", "OpenBMC", "TaskEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053035static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
36 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
37
Sunitha Harishe56f2542020-07-22 02:38:59 -050038#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
39static constexpr const std::array<const char*, 2> supportedResourceTypes = {
40 "IBMConfigFile", "Task"};
41#else
42static constexpr const std::array<const char*, 1> supportedResourceTypes = {
43 "Task"};
44#endif
45
AppaRao Pulie5aaf042020-03-20 01:05:52 +053046static constexpr const uint8_t maxNoOfSubscriptions = 20;
47
John Edward Broadbent7e860f12021-04-08 15:57:16 -070048inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053049{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070050 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070051 .privileges(redfish::privileges::getEventService)
Ed Tanous45ca1b82022-03-25 13:07:27 -070052 .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
53 const std::shared_ptr<
54 bmcweb::AsyncResp>&
55 asyncResp) {
56 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
57 {
58 return;
59 }
Ed Tanous14766872022-03-15 10:44:42 -070060
61 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
62 asyncResp->res.jsonValue["@odata.type"] =
63 "#EventService.v1_5_0.EventService";
64 asyncResp->res.jsonValue["Id"] = "EventService";
65 asyncResp->res.jsonValue["Name"] = "Event Service";
66 asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
67 "/redfish/v1/EventService/Subscriptions";
68 asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
69 ["target"] =
70 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
AppaRao Pulie5aaf042020-03-20 01:05:52 +053071
George Liu0fda0f12021-11-16 10:06:17 +080072 const persistent_data::EventServiceConfig eventServiceConfig =
73 persistent_data::EventServiceStore::getInstance()
74 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080075
George Liu0fda0f12021-11-16 10:06:17 +080076 asyncResp->res.jsonValue["Status"]["State"] =
77 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
78 asyncResp->res.jsonValue["ServiceEnabled"] =
79 eventServiceConfig.enabled;
80 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
81 eventServiceConfig.retryAttempts;
82 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
83 eventServiceConfig.retryTimeoutInterval;
84 asyncResp->res.jsonValue["EventFormatTypes"] =
85 supportedEvtFormatTypes;
86 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
87 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +053088
George Liu0fda0f12021-11-16 10:06:17 +080089 nlohmann::json supportedSSEFilters = {
90 {"EventFormatType", true}, {"MessageId", true},
91 {"MetricReportDefinition", true}, {"RegistryPrefix", true},
92 {"OriginResource", false}, {"ResourceType", false}};
AppaRao Puli7d1cc382020-05-16 02:42:22 +053093
George Liu0fda0f12021-11-16 10:06:17 +080094 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
95 supportedSSEFilters;
96 });
Ayushi Smriti07941a82020-05-21 15:55:34 +053097
John Edward Broadbent7e860f12021-04-08 15:57:16 -070098 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070099 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700100 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700101 [&app](const crow::Request& req,
102 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
103 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
104 {
105 return;
106 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700107 std::optional<bool> serviceEnabled;
108 std::optional<uint32_t> retryAttemps;
109 std::optional<uint32_t> retryInterval;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530110
Willy Tu15ed6782021-12-14 11:03:16 -0800111 if (!json_util::readJsonPatch(
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700112 req, asyncResp->res, "ServiceEnabled", serviceEnabled,
113 "DeliveryRetryAttempts", retryAttemps,
114 "DeliveryRetryIntervalSeconds", retryInterval))
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530115 {
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530116 return;
117 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530118
JunLin Chen28afb492021-02-24 17:13:29 +0800119 persistent_data::EventServiceConfig eventServiceConfig =
120 persistent_data::EventServiceStore::getInstance()
121 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700122
123 if (serviceEnabled)
Sunitha Harishe56f2542020-07-22 02:38:59 -0500124 {
JunLin Chen28afb492021-02-24 17:13:29 +0800125 eventServiceConfig.enabled = *serviceEnabled;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500126 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500127
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700128 if (retryAttemps)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530129 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700130 // Supported range [1-3]
131 if ((*retryAttemps < 1) || (*retryAttemps > 3))
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530132 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700133 messages::queryParameterOutOfRange(
134 asyncResp->res, std::to_string(*retryAttemps),
135 "DeliveryRetryAttempts", "[1-3]");
136 }
137 else
138 {
JunLin Chen28afb492021-02-24 17:13:29 +0800139 eventServiceConfig.retryAttempts = *retryAttemps;
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530140 }
141 }
142
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700143 if (retryInterval)
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530144 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700145 // Supported range [30 - 180]
146 if ((*retryInterval < 30) || (*retryInterval > 180))
147 {
148 messages::queryParameterOutOfRange(
149 asyncResp->res, std::to_string(*retryInterval),
150 "DeliveryRetryIntervalSeconds", "[30-180]");
151 }
152 else
153 {
JunLin Chen28afb492021-02-24 17:13:29 +0800154 eventServiceConfig.retryTimeoutInterval =
155 *retryInterval;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700156 }
157 }
158
159 EventServiceManager::getInstance().setEventServiceConfig(
JunLin Chen28afb492021-02-24 17:13:29 +0800160 eventServiceConfig);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700161 });
162}
163
164inline void requestRoutesSubmitTestEvent(App& app)
165{
166
167 BMCWEB_ROUTE(
168 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700169 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700170 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700171 [&app](const crow::Request& req,
172 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
173 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
174 {
175 return;
176 }
sunharis_in6ba8c822021-07-06 06:06:58 -0500177 if (!EventServiceManager::getInstance().sendTestEventLog())
178 {
179 messages::serviceDisabled(asyncResp->res,
180 "/redfish/v1/EventService/");
181 return;
182 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700183 asyncResp->res.result(boost::beast::http::status::no_content);
184 });
185}
186
187inline void requestRoutesEventDestinationCollection(App& app)
188{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000189 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700190 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700191 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700192 [&app](const crow::Request& req,
193 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
194 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
195 {
196 return;
197 }
Ed Tanous14766872022-03-15 10:44:42 -0700198 asyncResp->res.jsonValue["@odata.type"] =
199 "#EventDestinationCollection.EventDestinationCollection";
200 asyncResp->res.jsonValue["@odata.id"] =
201 "/redfish/v1/EventService/Subscriptions";
202 asyncResp->res.jsonValue["Name"] =
203 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700204
205 nlohmann::json& memberArray =
206 asyncResp->res.jsonValue["Members"];
207
208 std::vector<std::string> subscripIds =
209 EventServiceManager::getInstance().getAllIDs();
210 memberArray = nlohmann::json::array();
211 asyncResp->res.jsonValue["Members@odata.count"] =
212 subscripIds.size();
213
214 for (const std::string& id : subscripIds)
215 {
Ed Tanous14766872022-03-15 10:44:42 -0700216 nlohmann::json::object_t member;
217 member["@odata.id"] =
218 "/redfish/v1/EventService/Subscriptions/" + id;
219 memberArray.push_back(std::move(member));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700220 }
221 });
222 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500223 .privileges(redfish::privileges::postEventDestinationCollection)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800224 .methods(
225 boost::beast::http::verb::
Ed Tanous45ca1b82022-03-25 13:07:27 -0700226 post)([&app](
227 const crow::Request& req,
228 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
229 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
230 {
231 return;
232 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800233 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
234 maxNoOfSubscriptions)
235 {
236 messages::eventSubscriptionLimitExceeded(asyncResp->res);
237 return;
238 }
239 std::string destUrl;
240 std::string protocol;
241 std::optional<std::string> context;
242 std::optional<std::string> subscriptionType;
243 std::optional<std::string> eventFormatType2;
244 std::optional<std::string> retryPolicy;
245 std::optional<std::vector<std::string>> msgIds;
246 std::optional<std::vector<std::string>> regPrefixes;
247 std::optional<std::vector<std::string>> resTypes;
248 std::optional<std::vector<nlohmann::json>> headers;
249 std::optional<std::vector<nlohmann::json>> mrdJsonArray;
250
251 if (!json_util::readJsonPatch(
252 req, asyncResp->res, "Destination", destUrl, "Context",
253 context, "Protocol", protocol, "SubscriptionType",
254 subscriptionType, "EventFormatType", eventFormatType2,
255 "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
256 "MessageIds", msgIds, "DeliveryRetryPolicy", retryPolicy,
257 "MetricReportDefinitions", mrdJsonArray, "ResourceTypes",
258 resTypes))
259 {
260 return;
261 }
262
263 if (regPrefixes && msgIds)
264 {
265 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700266 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800267 messages::propertyValueConflict(
268 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530269 return;
270 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800271 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530272
Ed Tanouseb1c47d2022-02-09 11:47:27 -0800273 std::string host;
274 std::string urlProto;
275 uint16_t port = 0;
276 std::string path;
277
278 if (!crow::utility::validateAndSplitUrl(destUrl, urlProto, host,
279 port, path))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800280 {
Ed Tanouseb1c47d2022-02-09 11:47:27 -0800281 BMCWEB_LOG_WARNING
282 << "Failed to validate and split destination url";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800283 messages::propertyValueFormatError(asyncResp->res, destUrl,
284 "Destination");
285 return;
286 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700287
Ed Tanousfffb8c12022-02-07 23:53:03 -0800288 if (path.empty())
289 {
290 path = "/";
291 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800292 std::shared_ptr<Subscription> subValue =
Ed Tanouseb1c47d2022-02-09 11:47:27 -0800293 std::make_shared<Subscription>(host, port, path, urlProto);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800294
295 subValue->destinationUrl = destUrl;
296
297 if (subscriptionType)
298 {
299 if (*subscriptionType != "RedfishEvent")
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700300 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800301 messages::propertyValueNotInList(
302 asyncResp->res, *subscriptionType, "SubscriptionType");
AppaRao Puli144b6312020-08-03 22:23:12 +0530303 return;
304 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800305 subValue->subscriptionType = *subscriptionType;
306 }
307 else
308 {
309 subValue->subscriptionType = "RedfishEvent"; // Default
310 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530311
Ed Tanousfffb8c12022-02-07 23:53:03 -0800312 if (protocol != "Redfish")
313 {
314 messages::propertyValueNotInList(asyncResp->res, protocol,
315 "Protocol");
316 return;
317 }
318 subValue->protocol = protocol;
319
320 if (eventFormatType2)
321 {
322 if (std::find(supportedEvtFormatTypes.begin(),
323 supportedEvtFormatTypes.end(),
324 *eventFormatType2) ==
325 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700326 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800327 messages::propertyValueNotInList(
328 asyncResp->res, *eventFormatType2, "EventFormatType");
329 return;
330 }
331 subValue->eventFormatType = *eventFormatType2;
332 }
333 else
334 {
335 // If not specified, use default "Event"
336 subValue->eventFormatType = "Event";
337 }
338
339 if (context)
340 {
341 subValue->customText = *context;
342 }
343
344 if (headers)
345 {
346 for (const nlohmann::json& headerChunk : *headers)
347 {
348 for (const auto& item : headerChunk.items())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700349 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800350 const std::string* value =
351 item.value().get_ptr<const std::string*>();
352 if (value == nullptr)
353 {
354 messages::propertyValueFormatError(
355 asyncResp->res, item.value().dump(2, 1),
356 "HttpHeaders/" + item.key());
357 return;
358 }
359 subValue->httpHeaders.set(item.key(), *value);
360 }
361 }
362 }
363
364 if (regPrefixes)
365 {
366 for (const std::string& it : *regPrefixes)
367 {
368 if (std::find(supportedRegPrefixes.begin(),
369 supportedRegPrefixes.end(),
370 it) == supportedRegPrefixes.end())
371 {
372 messages::propertyValueNotInList(asyncResp->res, it,
373 "RegistryPrefixes");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700374 return;
375 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800376 }
377 subValue->registryPrefixes = *regPrefixes;
378 }
379
380 if (resTypes)
381 {
382 for (const std::string& it : *resTypes)
383 {
384 if (std::find(supportedResourceTypes.begin(),
385 supportedResourceTypes.end(),
386 it) == supportedResourceTypes.end())
387 {
388 messages::propertyValueNotInList(asyncResp->res, it,
389 "ResourceTypes");
390 return;
391 }
392 }
393 subValue->resourceTypes = *resTypes;
394 }
395
396 if (msgIds)
397 {
398 std::vector<std::string> registryPrefix;
399
400 // If no registry prefixes are mentioned, consider all
401 // supported prefixes
402 if (subValue->registryPrefixes.empty())
403 {
404 registryPrefix.assign(supportedRegPrefixes.begin(),
405 supportedRegPrefixes.end());
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700406 }
407 else
408 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800409 registryPrefix = subValue->registryPrefixes;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700410 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530411
Ed Tanousfffb8c12022-02-07 23:53:03 -0800412 for (const std::string& id : *msgIds)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700413 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800414 bool validId = false;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530415
Ed Tanousfffb8c12022-02-07 23:53:03 -0800416 // Check for Message ID in each of the selected Registry
417 for (const std::string& it : registryPrefix)
Ed Tanous601c71a2021-09-08 16:40:12 -0700418 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800419 const std::span<const redfish::registries::MessageEntry>
420 registry =
421 redfish::registries::getRegistryFromPrefix(it);
422
423 if (std::any_of(
424 registry.begin(), registry.end(),
425 [&id](const redfish::registries::MessageEntry&
426 messageEntry) {
Ed Tanous55f79e62022-01-25 11:26:16 -0800427 return id == messageEntry.first;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800428 }))
Ed Tanous601c71a2021-09-08 16:40:12 -0700429 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800430 validId = true;
431 break;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700432 }
433 }
434
Ed Tanousfffb8c12022-02-07 23:53:03 -0800435 if (!validId)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700436 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800437 messages::propertyValueNotInList(asyncResp->res, id,
438 "MessageIds");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700439 return;
440 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700441 }
442
Ed Tanousfffb8c12022-02-07 23:53:03 -0800443 subValue->registryMsgIds = *msgIds;
444 }
445
446 if (retryPolicy)
447 {
448 if (std::find(supportedRetryPolicies.begin(),
449 supportedRetryPolicies.end(),
450 *retryPolicy) == supportedRetryPolicies.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700451 {
Ed Tanousfffb8c12022-02-07 23:53:03 -0800452 messages::propertyValueNotInList(
453 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700454 return;
455 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800456 subValue->retryPolicy = *retryPolicy;
457 }
458 else
459 {
460 // Default "TerminateAfterRetries"
461 subValue->retryPolicy = "TerminateAfterRetries";
462 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700463
Ed Tanousfffb8c12022-02-07 23:53:03 -0800464 if (mrdJsonArray)
465 {
466 for (nlohmann::json& mrdObj : *mrdJsonArray)
467 {
468 std::string mrdUri;
469
470 if (!json_util::readJson(mrdObj, asyncResp->res,
471 "@odata.id", mrdUri))
472
473 {
474 return;
475 }
476 subValue->metricReportDefinitions.emplace_back(mrdUri);
477 }
478 }
479
480 std::string id =
481 EventServiceManager::getInstance().addSubscription(subValue);
482 if (id.empty())
483 {
484 messages::internalError(asyncResp->res);
485 return;
486 }
487
488 messages::created(asyncResp->res);
489 asyncResp->res.addHeader(
490 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
491 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700492}
493
494inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530495{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500496 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700497 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700498 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700499 [&app](const crow::Request& req,
500 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
501 const std::string& param) {
502 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
503 {
504 return;
505 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700506 std::shared_ptr<Subscription> subValue =
507 EventServiceManager::getInstance().getSubscription(param);
508 if (subValue == nullptr)
509 {
510 asyncResp->res.result(
511 boost::beast::http::status::not_found);
512 return;
513 }
514 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530515
Ed Tanous14766872022-03-15 10:44:42 -0700516 asyncResp->res.jsonValue["@odata.type"] =
517 "#EventDestination.v1_7_0.EventDestination";
518 asyncResp->res.jsonValue["Protocol"] = "Redfish";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700519 asyncResp->res.jsonValue["@odata.id"] =
520 "/redfish/v1/EventService/Subscriptions/" + id;
521 asyncResp->res.jsonValue["Id"] = id;
522 asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
523 asyncResp->res.jsonValue["Destination"] =
524 subValue->destinationUrl;
525 asyncResp->res.jsonValue["Context"] = subValue->customText;
526 asyncResp->res.jsonValue["SubscriptionType"] =
527 subValue->subscriptionType;
Ed Tanousad22fef2021-09-13 13:07:32 -0700528 asyncResp->res.jsonValue["HttpHeaders"] =
529 nlohmann::json::array();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700530 asyncResp->res.jsonValue["EventFormatType"] =
531 subValue->eventFormatType;
532 asyncResp->res.jsonValue["RegistryPrefixes"] =
533 subValue->registryPrefixes;
534 asyncResp->res.jsonValue["ResourceTypes"] =
535 subValue->resourceTypes;
zhanghch058d1b46d2021-04-01 11:18:24 +0800536
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700537 asyncResp->res.jsonValue["MessageIds"] =
538 subValue->registryMsgIds;
539 asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
540 subValue->retryPolicy;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530541
Ed Tanous14766872022-03-15 10:44:42 -0700542 nlohmann::json::array_t mrdJsonArray;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700543 for (const auto& mdrUri : subValue->metricReportDefinitions)
544 {
Ed Tanous14766872022-03-15 10:44:42 -0700545 nlohmann::json::object_t mdr;
546 mdr["@odata.id"] = mdrUri;
547 mrdJsonArray.emplace_back(std::move(mdr));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700548 }
549 asyncResp->res.jsonValue["MetricReportDefinitions"] =
550 mrdJsonArray;
551 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500552 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700553 // The below privilege is wrong, it should be ConfigureManager OR
554 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500555 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700556 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700557 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700558 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700559 [&app](const crow::Request& req,
560 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
561 const std::string& param) {
562 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
563 {
564 return;
565 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700566 std::shared_ptr<Subscription> subValue =
567 EventServiceManager::getInstance().getSubscription(param);
568 if (subValue == nullptr)
569 {
570 asyncResp->res.result(
571 boost::beast::http::status::not_found);
572 return;
573 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530574
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700575 std::optional<std::string> context;
576 std::optional<std::string> retryPolicy;
577 std::optional<std::vector<nlohmann::json>> headers;
Sunitha Harishe56f2542020-07-22 02:38:59 -0500578
Willy Tu15ed6782021-12-14 11:03:16 -0800579 if (!json_util::readJsonPatch(req, asyncResp->res, "Context",
580 context, "DeliveryRetryPolicy",
581 retryPolicy, "HttpHeaders",
582 headers))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700583 {
584 return;
585 }
AppaRao Puli144b6312020-08-03 22:23:12 +0530586
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700587 if (context)
588 {
589 subValue->customText = *context;
590 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530591
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700592 if (headers)
593 {
Ed Tanous601c71a2021-09-08 16:40:12 -0700594 boost::beast::http::fields fields;
595 for (const nlohmann::json& headerChunk : *headers)
596 {
597 for (auto& it : headerChunk.items())
598 {
599 const std::string* value =
600 it.value().get_ptr<const std::string*>();
601 if (value == nullptr)
602 {
603 messages::propertyValueFormatError(
604 asyncResp->res,
605 it.value().dump(2, ' ', true),
606 "HttpHeaders/" + it.key());
607 return;
608 }
609 fields.set(it.key(), *value);
610 }
611 }
612 subValue->httpHeaders = fields;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700613 }
zhanghch058d1b46d2021-04-01 11:18:24 +0800614
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700615 if (retryPolicy)
616 {
617 if (std::find(supportedRetryPolicies.begin(),
618 supportedRetryPolicies.end(),
619 *retryPolicy) == supportedRetryPolicies.end())
620 {
621 messages::propertyValueNotInList(asyncResp->res,
622 *retryPolicy,
623 "DeliveryRetryPolicy");
624 return;
625 }
626 subValue->retryPolicy = *retryPolicy;
627 subValue->updateRetryPolicy();
628 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530629
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700630 EventServiceManager::getInstance().updateSubscriptionData();
631 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500632 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700633 // The below privilege is wrong, it should be ConfigureManager OR
634 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500635 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700636 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700637 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700638 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700639 [&app](const crow::Request& req,
640 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
641 const std::string& param) {
642 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
643 {
644 return;
645 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700646 if (!EventServiceManager::getInstance().isSubscriptionExist(
647 param))
648 {
649 asyncResp->res.result(
650 boost::beast::http::status::not_found);
651 return;
652 }
653 EventServiceManager::getInstance().deleteSubscription(param);
654 });
655}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530656
657} // namespace redfish