summaryrefslogtreecommitdiff
path: root/redfish-core/lib/event_service.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'redfish-core/lib/event_service.hpp')
-rw-r--r--redfish-core/lib/event_service.hpp1128
1 files changed, 587 insertions, 541 deletions
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index aebc2824b0..ff3de8298a 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -16,6 +16,7 @@
#pragma once
#include "app.hpp"
#include "event_service_manager.hpp"
+#include "generated/enums/event_service.hpp"
#include "http/utility.hpp"
#include "logging.hpp"
#include "query.hpp"
@@ -51,118 +52,123 @@ inline void requestRoutesEventService(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
.privileges(redfish::privileges::getEventService)
- .methods(boost::beast::http::verb::get)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ .methods(
+ boost::beast::http::verb::
+ get)([&app](
+ const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventService.v1_5_0.EventService";
- asyncResp->res.jsonValue["Id"] = "EventService";
- asyncResp->res.jsonValue["Name"] = "Event Service";
- asyncResp->res.jsonValue["ServerSentEventUri"] =
- "/redfish/v1/EventService/SSE";
-
- asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
- "/redfish/v1/EventService/Subscriptions";
- asyncResp->res
- .jsonValue["Actions"]["#EventService.SubmitTestEvent"]["target"] =
- "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
-
- const persistent_data::EventServiceConfig eventServiceConfig =
- persistent_data::EventServiceStore::getInstance()
- .getEventServiceConfig();
-
- asyncResp->res.jsonValue["Status"]["State"] =
- (eventServiceConfig.enabled ? "Enabled" : "Disabled");
- asyncResp->res.jsonValue["ServiceEnabled"] = eventServiceConfig.enabled;
- asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
- eventServiceConfig.retryAttempts;
- asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
- eventServiceConfig.retryTimeoutInterval;
- asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
- asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
- asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
-
- nlohmann::json::object_t supportedSSEFilters;
- supportedSSEFilters["EventFormatType"] = true;
- supportedSSEFilters["MessageId"] = true;
- supportedSSEFilters["MetricReportDefinition"] = true;
- supportedSSEFilters["RegistryPrefix"] = true;
- supportedSSEFilters["OriginResource"] = false;
- supportedSSEFilters["ResourceType"] = false;
-
- asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
- std::move(supportedSSEFilters);
- });
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EventService.v1_5_0.EventService";
+ asyncResp->res.jsonValue["Id"] = "EventService";
+ asyncResp->res.jsonValue["Name"] = "Event Service";
+ asyncResp->res.jsonValue["ServerSentEventUri"] =
+ "/redfish/v1/EventService/SSE";
+
+ asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
+ "/redfish/v1/EventService/Subscriptions";
+ asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
+ ["target"] =
+ "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
+
+ const persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
+
+ asyncResp->res.jsonValue["Status"]["State"] =
+ (eventServiceConfig.enabled ? "Enabled" : "Disabled");
+ asyncResp->res.jsonValue["ServiceEnabled"] =
+ eventServiceConfig.enabled;
+ asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
+ eventServiceConfig.retryAttempts;
+ asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
+ eventServiceConfig.retryTimeoutInterval;
+ asyncResp->res.jsonValue["EventFormatTypes"] =
+ supportedEvtFormatTypes;
+ asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
+ asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
+
+ nlohmann::json::object_t supportedSSEFilters;
+ supportedSSEFilters["EventFormatType"] = true;
+ supportedSSEFilters["MessageId"] = true;
+ supportedSSEFilters["MetricReportDefinition"] = true;
+ supportedSSEFilters["RegistryPrefix"] = true;
+ supportedSSEFilters["OriginResource"] = false;
+ supportedSSEFilters["ResourceType"] = false;
+
+ asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
+ std::move(supportedSSEFilters);
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
.privileges(redfish::privileges::patchEventService)
.methods(boost::beast::http::verb::patch)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::optional<bool> serviceEnabled;
- std::optional<uint32_t> retryAttemps;
- std::optional<uint32_t> retryInterval;
-
- if (!json_util::readJsonPatch(
- req, asyncResp->res, "ServiceEnabled", serviceEnabled,
- "DeliveryRetryAttempts", retryAttemps,
- "DeliveryRetryIntervalSeconds", retryInterval))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::optional<bool> serviceEnabled;
+ std::optional<uint32_t> retryAttemps;
+ std::optional<uint32_t> retryInterval;
+
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "ServiceEnabled", serviceEnabled,
+ "DeliveryRetryAttempts", retryAttemps,
+ "DeliveryRetryIntervalSeconds", retryInterval))
+ {
+ return;
+ }
- persistent_data::EventServiceConfig eventServiceConfig =
- persistent_data::EventServiceStore::getInstance()
- .getEventServiceConfig();
+ persistent_data::EventServiceConfig eventServiceConfig =
+ persistent_data::EventServiceStore::getInstance()
+ .getEventServiceConfig();
- if (serviceEnabled)
- {
- eventServiceConfig.enabled = *serviceEnabled;
- }
+ if (serviceEnabled)
+ {
+ eventServiceConfig.enabled = *serviceEnabled;
+ }
- if (retryAttemps)
- {
- // Supported range [1-3]
- if ((*retryAttemps < 1) || (*retryAttemps > 3))
- {
- messages::queryParameterOutOfRange(
- asyncResp->res, std::to_string(*retryAttemps),
- "DeliveryRetryAttempts", "[1-3]");
- }
- else
- {
- eventServiceConfig.retryAttempts = *retryAttemps;
- }
- }
+ if (retryAttemps)
+ {
+ // Supported range [1-3]
+ if ((*retryAttemps < 1) || (*retryAttemps > 3))
+ {
+ messages::queryParameterOutOfRange(
+ asyncResp->res, std::to_string(*retryAttemps),
+ "DeliveryRetryAttempts", "[1-3]");
+ }
+ else
+ {
+ eventServiceConfig.retryAttempts = *retryAttemps;
+ }
+ }
- if (retryInterval)
- {
- // Supported range [5 - 180]
- if ((*retryInterval < 5) || (*retryInterval > 180))
- {
- messages::queryParameterOutOfRange(
- asyncResp->res, std::to_string(*retryInterval),
- "DeliveryRetryIntervalSeconds", "[5-180]");
- }
- else
- {
- eventServiceConfig.retryTimeoutInterval = *retryInterval;
- }
- }
+ if (retryInterval)
+ {
+ // Supported range [5 - 180]
+ if ((*retryInterval < 5) || (*retryInterval > 180))
+ {
+ messages::queryParameterOutOfRange(
+ asyncResp->res, std::to_string(*retryInterval),
+ "DeliveryRetryIntervalSeconds", "[5-180]");
+ }
+ else
+ {
+ eventServiceConfig.retryTimeoutInterval =
+ *retryInterval;
+ }
+ }
- EventServiceManager::getInstance().setEventServiceConfig(
- eventServiceConfig);
- });
+ EventServiceManager::getInstance().setEventServiceConfig(
+ eventServiceConfig);
+ });
}
inline void requestRoutesSubmitTestEvent(App& app)
@@ -173,18 +179,18 @@ inline void requestRoutesSubmitTestEvent(App& app)
.methods(boost::beast::http::verb::post)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (!EventServiceManager::getInstance().sendTestEventLog())
- {
- messages::serviceDisabled(asyncResp->res,
- "/redfish/v1/EventService/");
- return;
- }
- asyncResp->res.result(boost::beast::http::status::no_content);
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ if (!EventServiceManager::getInstance().sendTestEventLog())
+ {
+ messages::serviceDisabled(asyncResp->res,
+ "/redfish/v1/EventService/");
+ return;
+ }
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ });
}
inline void doSubscriptionCollection(
@@ -227,402 +233,417 @@ inline void requestRoutesEventDestinationCollection(App& app)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventDestinationCollection.EventDestinationCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/EventService/Subscriptions";
- asyncResp->res.jsonValue["Name"] = "Event Destination Collections";
-
- nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
-
- std::vector<std::string> subscripIds =
- EventServiceManager::getInstance().getAllIDs();
- memberArray = nlohmann::json::array();
- asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
-
- for (const std::string& id : subscripIds)
- {
- nlohmann::json::object_t member;
- member["@odata.id"] = boost::urls::format(
- "/redfish/v1/EventService/Subscriptions/{}" + id);
- memberArray.emplace_back(std::move(member));
- }
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code& ec,
- const dbus::utility::ManagedObjectType& resp) {
- doSubscriptionCollection(ec, asyncResp, resp);
- },
- "xyz.openbmc_project.Network.SNMP",
- "/xyz/openbmc_project/network/snmp/manager",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
- });
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EventDestinationCollection.EventDestinationCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/EventService/Subscriptions";
+ asyncResp->res.jsonValue["Name"] =
+ "Event Destination Collections";
+
+ nlohmann::json& memberArray =
+ asyncResp->res.jsonValue["Members"];
+
+ std::vector<std::string> subscripIds =
+ EventServiceManager::getInstance().getAllIDs();
+ memberArray = nlohmann::json::array();
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ subscripIds.size();
+
+ for (const std::string& id : subscripIds)
+ {
+ nlohmann::json::object_t member;
+ member["@odata.id"] = boost::urls::format(
+ "/redfish/v1/EventService/Subscriptions/{}" + id);
+ memberArray.emplace_back(std::move(member));
+ }
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code& ec,
+ const dbus::utility::ManagedObjectType& resp) {
+ doSubscriptionCollection(ec, asyncResp, resp);
+ },
+ "xyz.openbmc_project.Network.SNMP",
+ "/xyz/openbmc_project/network/snmp/manager",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
.privileges(redfish::privileges::postEventDestinationCollection)
- .methods(boost::beast::http::verb::post)(
- [&app](const crow::Request& req,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
- maxNoOfSubscriptions)
- {
- messages::eventSubscriptionLimitExceeded(asyncResp->res);
- return;
- }
- std::string destUrl;
- std::string protocol;
- std::optional<std::string> context;
- std::optional<std::string> subscriptionType;
- std::optional<std::string> eventFormatType2;
- std::optional<std::string> retryPolicy;
- std::optional<std::vector<std::string>> msgIds;
- std::optional<std::vector<std::string>> regPrefixes;
- std::optional<std::vector<std::string>> resTypes;
- std::optional<std::vector<nlohmann::json::object_t>> headers;
- std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
-
- if (!json_util::readJsonPatch(
- req, asyncResp->res, "Destination", destUrl, "Context", context,
- "Protocol", protocol, "SubscriptionType", subscriptionType,
- "EventFormatType", eventFormatType2, "HttpHeaders", headers,
- "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
- "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
- mrdJsonArray, "ResourceTypes", resTypes))
- {
- return;
- }
-
- // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
- static constexpr const uint16_t maxDestinationSize = 2000;
- if (destUrl.size() > maxDestinationSize)
- {
- messages::stringValueTooLong(asyncResp->res, "Destination",
- maxDestinationSize);
- return;
- }
-
- if (regPrefixes && msgIds)
- {
- if (!regPrefixes->empty() && !msgIds->empty())
+ .methods(
+ boost::beast::http::verb::
+ post)([&app](
+ const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
- messages::propertyValueConflict(asyncResp->res, "MessageIds",
- "RegistryPrefixes");
return;
}
- }
-
- boost::system::result<boost::urls::url> url =
- boost::urls::parse_absolute_uri(destUrl);
- if (!url)
- {
- BMCWEB_LOG_WARNING("Failed to validate and split destination url");
- messages::propertyValueFormatError(asyncResp->res, destUrl,
- "Destination");
- return;
- }
- url->normalize();
- crow::utility::setProtocolDefaults(*url, protocol);
- crow::utility::setPortDefaults(*url);
-
- if (url->path().empty())
- {
- url->set_path("/");
- }
-
- if (url->has_userinfo())
- {
- messages::propertyValueFormatError(asyncResp->res, destUrl,
- "Destination");
- return;
- }
-
- if (protocol == "SNMPv2c")
- {
- if (context)
+ if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
+ maxNoOfSubscriptions)
{
- messages::propertyValueConflict(asyncResp->res, "Context",
- "Protocol");
+ messages::eventSubscriptionLimitExceeded(asyncResp->res);
return;
}
- if (eventFormatType2)
+ std::string destUrl;
+ std::string protocol;
+ std::optional<bool> verifyCertificate;
+ std::optional<std::string> context;
+ std::optional<std::string> subscriptionType;
+ std::optional<std::string> eventFormatType2;
+ std::optional<std::string> retryPolicy;
+ std::optional<std::vector<std::string>> msgIds;
+ std::optional<std::vector<std::string>> regPrefixes;
+ std::optional<std::vector<std::string>> resTypes;
+ std::optional<std::vector<nlohmann::json::object_t>> headers;
+ std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
+
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "Destination", destUrl, "Context",
+ context, "Protocol", protocol, "SubscriptionType",
+ subscriptionType, "EventFormatType", eventFormatType2,
+ "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
+ "MessageIds", msgIds, "DeliveryRetryPolicy", retryPolicy,
+ "MetricReportDefinitions", mrdJsonArray, "ResourceTypes",
+ resTypes, "VerifyCertificate", verifyCertificate))
{
- messages::propertyValueConflict(asyncResp->res,
- "EventFormatType", "Protocol");
return;
}
- if (retryPolicy)
- {
- messages::propertyValueConflict(asyncResp->res, "RetryPolicy",
- "Protocol");
- return;
- }
- if (msgIds)
+
+ // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
+ static constexpr const uint16_t maxDestinationSize = 2000;
+ if (destUrl.size() > maxDestinationSize)
{
- messages::propertyValueConflict(asyncResp->res, "MessageIds",
- "Protocol");
+ messages::stringValueTooLong(asyncResp->res, "Destination",
+ maxDestinationSize);
return;
}
- if (regPrefixes)
+
+ if (regPrefixes && msgIds)
{
- messages::propertyValueConflict(asyncResp->res,
- "RegistryPrefixes", "Protocol");
- return;
+ if (!regPrefixes->empty() && !msgIds->empty())
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "MessageIds", "RegistryPrefixes");
+ return;
+ }
}
- if (resTypes)
+
+ boost::system::result<boost::urls::url> url =
+ boost::urls::parse_absolute_uri(destUrl);
+ if (!url)
{
- messages::propertyValueConflict(asyncResp->res, "ResourceTypes",
- "Protocol");
+ BMCWEB_LOG_WARNING(
+ "Failed to validate and split destination url");
+ messages::propertyValueFormatError(asyncResp->res, destUrl,
+ "Destination");
return;
}
- if (headers)
+ url->normalize();
+ crow::utility::setProtocolDefaults(*url, protocol);
+ crow::utility::setPortDefaults(*url);
+
+ if (url->path().empty())
{
- messages::propertyValueConflict(asyncResp->res, "HttpHeaders",
- "Protocol");
- return;
+ url->set_path("/");
}
- if (mrdJsonArray)
+
+ if (url->has_userinfo())
{
- messages::propertyValueConflict(
- asyncResp->res, "MetricReportDefinitions", "Protocol");
+ messages::propertyValueFormatError(asyncResp->res, destUrl,
+ "Destination");
return;
}
- if (url->scheme() != "snmp")
+
+ if (protocol == "SNMPv2c")
{
- messages::propertyValueConflict(asyncResp->res, "Destination",
- "Protocol");
+ if (context)
+ {
+ messages::propertyValueConflict(asyncResp->res, "Context",
+ "Protocol");
+ return;
+ }
+ if (eventFormatType2)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "EventFormatType", "Protocol");
+ return;
+ }
+ if (retryPolicy)
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "RetryPolicy", "Protocol");
+ return;
+ }
+ if (msgIds)
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "MessageIds", "Protocol");
+ return;
+ }
+ if (regPrefixes)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "RegistryPrefixes", "Protocol");
+ return;
+ }
+ if (resTypes)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "ResourceTypes", "Protocol");
+ return;
+ }
+ if (headers)
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "HttpHeaders", "Protocol");
+ return;
+ }
+ if (mrdJsonArray)
+ {
+ messages::propertyValueConflict(
+ asyncResp->res, "MetricReportDefinitions", "Protocol");
+ return;
+ }
+ if (url->scheme() != "snmp")
+ {
+ messages::propertyValueConflict(asyncResp->res,
+ "Destination", "Protocol");
+ return;
+ }
+
+ addSnmpTrapClient(asyncResp, url->host_address(),
+ url->port_number());
return;
}
- addSnmpTrapClient(asyncResp, url->host_address(),
- url->port_number());
- return;
- }
+ std::shared_ptr<Subscription> subValue =
+ std::make_shared<Subscription>(*url, app.ioContext());
- std::shared_ptr<Subscription> subValue =
- std::make_shared<Subscription>(*url, app.ioContext());
+ subValue->destinationUrl = std::move(*url);
- subValue->destinationUrl = std::move(*url);
-
- if (subscriptionType)
- {
- if (*subscriptionType != "RedfishEvent")
+ if (subscriptionType)
{
- messages::propertyValueNotInList(
- asyncResp->res, *subscriptionType, "SubscriptionType");
- return;
+ if (*subscriptionType != "RedfishEvent")
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, *subscriptionType, "SubscriptionType");
+ return;
+ }
+ subValue->subscriptionType = *subscriptionType;
}
- subValue->subscriptionType = *subscriptionType;
- }
- else
- {
- subValue->subscriptionType = "RedfishEvent"; // Default
- }
-
- if (protocol != "Redfish")
- {
- messages::propertyValueNotInList(asyncResp->res, protocol,
- "Protocol");
- return;
- }
- subValue->protocol = protocol;
-
- if (eventFormatType2)
- {
- if (std::ranges::find(supportedEvtFormatTypes, *eventFormatType2) ==
- supportedEvtFormatTypes.end())
+ else
{
- messages::propertyValueNotInList(
- asyncResp->res, *eventFormatType2, "EventFormatType");
- return;
+ subValue->subscriptionType = "RedfishEvent"; // Default
}
- subValue->eventFormatType = *eventFormatType2;
- }
- else
- {
- // If not specified, use default "Event"
- subValue->eventFormatType = "Event";
- }
- if (context)
- {
- // This value is selected arbitrarily.
- constexpr const size_t maxContextSize = 256;
- if (context->size() > maxContextSize)
+ if (protocol != "Redfish")
{
- messages::stringValueTooLong(asyncResp->res, "Context",
- maxContextSize);
+ messages::propertyValueNotInList(asyncResp->res, protocol,
+ "Protocol");
return;
}
- subValue->customText = *context;
- }
+ subValue->protocol = protocol;
- if (headers)
- {
- size_t cumulativeLen = 0;
+ if (verifyCertificate)
+ {
+ subValue->verifyCertificate = *verifyCertificate;
+ }
- for (const nlohmann::json::object_t& headerChunk : *headers)
+ if (eventFormatType2)
{
- for (const auto& item : headerChunk)
+ if (std::ranges::find(supportedEvtFormatTypes,
+ *eventFormatType2) ==
+ supportedEvtFormatTypes.end())
{
- const std::string* value =
- item.second.get_ptr<const std::string*>();
- if (value == nullptr)
- {
- messages::propertyValueFormatError(
- asyncResp->res, item.second,
- "HttpHeaders/" + item.first);
- return;
- }
- // Adding a new json value is the size of the key, +
- // the size of the value + 2 * 2 quotes for each, +
- // the colon and space between. example:
- // "key": "value"
- cumulativeLen += item.first.size() + value->size() + 6;
- // This value is selected to mirror http_connection.hpp
- constexpr const uint16_t maxHeaderSizeED = 8096;
- if (cumulativeLen > maxHeaderSizeED)
- {
- messages::arraySizeTooLong(
- asyncResp->res, "HttpHeaders", maxHeaderSizeED);
- return;
- }
- subValue->httpHeaders.set(item.first, *value);
+ messages::propertyValueNotInList(
+ asyncResp->res, *eventFormatType2, "EventFormatType");
+ return;
}
+ subValue->eventFormatType = *eventFormatType2;
+ }
+ else
+ {
+ // If not specified, use default "Event"
+ subValue->eventFormatType = "Event";
}
- }
- if (regPrefixes)
- {
- for (const std::string& it : *regPrefixes)
+ if (context)
{
- if (std::ranges::find(supportedRegPrefixes, it) ==
- supportedRegPrefixes.end())
+ // This value is selected arbitrarily.
+ constexpr const size_t maxContextSize = 256;
+ if (context->size() > maxContextSize)
{
- messages::propertyValueNotInList(asyncResp->res, it,
- "RegistryPrefixes");
+ messages::stringValueTooLong(asyncResp->res, "Context",
+ maxContextSize);
return;
}
+ subValue->customText = *context;
}
- subValue->registryPrefixes = *regPrefixes;
- }
- if (resTypes)
- {
- for (const std::string& it : *resTypes)
+ if (headers)
{
- if (std::ranges::find(supportedResourceTypes, it) ==
- supportedResourceTypes.end())
+ size_t cumulativeLen = 0;
+
+ for (const nlohmann::json::object_t& headerChunk : *headers)
{
- messages::propertyValueNotInList(asyncResp->res, it,
- "ResourceTypes");
- return;
+ for (const auto& item : headerChunk)
+ {
+ const std::string* value =
+ item.second.get_ptr<const std::string*>();
+ if (value == nullptr)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, item.second,
+ "HttpHeaders/" + item.first);
+ return;
+ }
+ // Adding a new json value is the size of the key, +
+ // the size of the value + 2 * 2 quotes for each, +
+ // the colon and space between. example:
+ // "key": "value"
+ cumulativeLen += item.first.size() + value->size() + 6;
+ // This value is selected to mirror http_connection.hpp
+ constexpr const uint16_t maxHeaderSizeED = 8096;
+ if (cumulativeLen > maxHeaderSizeED)
+ {
+ messages::arraySizeTooLong(
+ asyncResp->res, "HttpHeaders", maxHeaderSizeED);
+ return;
+ }
+ subValue->httpHeaders.set(item.first, *value);
+ }
}
}
- subValue->resourceTypes = *resTypes;
- }
-
- if (msgIds)
- {
- std::vector<std::string> registryPrefix;
- // If no registry prefixes are mentioned, consider all
- // supported prefixes
- if (subValue->registryPrefixes.empty())
+ if (regPrefixes)
{
- registryPrefix.assign(supportedRegPrefixes.begin(),
- supportedRegPrefixes.end());
+ for (const std::string& it : *regPrefixes)
+ {
+ if (std::ranges::find(supportedRegPrefixes, it) ==
+ supportedRegPrefixes.end())
+ {
+ messages::propertyValueNotInList(asyncResp->res, it,
+ "RegistryPrefixes");
+ return;
+ }
+ }
+ subValue->registryPrefixes = *regPrefixes;
}
- else
+
+ if (resTypes)
{
- registryPrefix = subValue->registryPrefixes;
+ for (const std::string& it : *resTypes)
+ {
+ if (std::ranges::find(supportedResourceTypes, it) ==
+ supportedResourceTypes.end())
+ {
+ messages::propertyValueNotInList(asyncResp->res, it,
+ "ResourceTypes");
+ return;
+ }
+ }
+ subValue->resourceTypes = *resTypes;
}
- for (const std::string& id : *msgIds)
+ if (msgIds)
{
- bool validId = false;
+ std::vector<std::string> registryPrefix;
- // Check for Message ID in each of the selected Registry
- for (const std::string& it : registryPrefix)
+ // If no registry prefixes are mentioned, consider all
+ // supported prefixes
+ if (subValue->registryPrefixes.empty())
{
- const std::span<const redfish::registries::MessageEntry>
- registry =
- redfish::registries::getRegistryFromPrefix(it);
+ registryPrefix.assign(supportedRegPrefixes.begin(),
+ supportedRegPrefixes.end());
+ }
+ else
+ {
+ registryPrefix = subValue->registryPrefixes;
+ }
+
+ for (const std::string& id : *msgIds)
+ {
+ bool validId = false;
- if (std::ranges::any_of(
- registry,
- [&id](const redfish::registries::MessageEntry&
- messageEntry) {
- return id == messageEntry.first;
- }))
+ // Check for Message ID in each of the selected Registry
+ for (const std::string& it : registryPrefix)
{
- validId = true;
- break;
+ const std::span<const redfish::registries::MessageEntry>
+ registry =
+ redfish::registries::getRegistryFromPrefix(it);
+
+ if (std::ranges::any_of(
+ registry,
+ [&id](const redfish::registries::MessageEntry&
+ messageEntry) {
+ return id == messageEntry.first;
+ }))
+ {
+ validId = true;
+ break;
+ }
+ }
+
+ if (!validId)
+ {
+ messages::propertyValueNotInList(asyncResp->res, id,
+ "MessageIds");
+ return;
}
}
- if (!validId)
+ subValue->registryMsgIds = *msgIds;
+ }
+
+ if (retryPolicy)
+ {
+ if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
+ supportedRetryPolicies.end())
{
- messages::propertyValueNotInList(asyncResp->res, id,
- "MessageIds");
+ messages::propertyValueNotInList(
+ asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
return;
}
+ subValue->retryPolicy = *retryPolicy;
}
-
- subValue->registryMsgIds = *msgIds;
- }
-
- if (retryPolicy)
- {
- if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
- supportedRetryPolicies.end())
+ else
{
- messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
- "DeliveryRetryPolicy");
- return;
+ // Default "TerminateAfterRetries"
+ subValue->retryPolicy = "TerminateAfterRetries";
}
- subValue->retryPolicy = *retryPolicy;
- }
- else
- {
- // Default "TerminateAfterRetries"
- subValue->retryPolicy = "TerminateAfterRetries";
- }
- if (mrdJsonArray)
- {
- for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
+ if (mrdJsonArray)
{
- std::string mrdUri;
+ for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
+ {
+ std::string mrdUri;
- if (!json_util::readJsonObject(mrdObj, asyncResp->res,
- "@odata.id", mrdUri))
+ if (!json_util::readJsonObject(mrdObj, asyncResp->res,
+ "@odata.id", mrdUri))
- {
- return;
+ {
+ return;
+ }
+ subValue->metricReportDefinitions.emplace_back(mrdUri);
}
- subValue->metricReportDefinitions.emplace_back(mrdUri);
}
- }
- std::string id =
- EventServiceManager::getInstance().addSubscription(subValue);
- if (id.empty())
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ std::string id =
+ EventServiceManager::getInstance().addPushSubscription(
+ subValue);
+ if (id.empty())
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
- messages::created(asyncResp->res);
- asyncResp->res.addHeader(
- "Location", "/redfish/v1/EventService/Subscriptions/" + id);
- });
+ messages::created(asyncResp->res);
+ asyncResp->res.addHeader(
+ "Location", "/redfish/v1/EventService/Subscriptions/" + id);
+ });
}
inline void requestRoutesEventDestination(App& app)
@@ -633,55 +654,66 @@ inline void requestRoutesEventDestination(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (param.starts_with("snmp"))
- {
- getSnmpTrapClient(asyncResp, param);
- return;
- }
+ if (param.starts_with("snmp"))
+ {
+ getSnmpTrapClient(asyncResp, param);
+ return;
+ }
- std::shared_ptr<Subscription> subValue =
- EventServiceManager::getInstance().getSubscription(param);
- if (subValue == nullptr)
- {
- asyncResp->res.result(boost::beast::http::status::not_found);
- return;
- }
- const std::string& id = param;
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventDestination.v1_8_0.EventDestination";
- asyncResp->res.jsonValue["Protocol"] = "Redfish";
- asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
- "/redfish/v1/EventService/Subscriptions/{}", id);
- asyncResp->res.jsonValue["Id"] = id;
- asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
- asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
- asyncResp->res.jsonValue["Context"] = subValue->customText;
- asyncResp->res.jsonValue["SubscriptionType"] =
- subValue->subscriptionType;
- asyncResp->res.jsonValue["HttpHeaders"] = nlohmann::json::array();
- asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
- asyncResp->res.jsonValue["RegistryPrefixes"] =
- subValue->registryPrefixes;
- asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes;
-
- asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
- asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
-
- nlohmann::json::array_t mrdJsonArray;
- for (const auto& mdrUri : subValue->metricReportDefinitions)
- {
- nlohmann::json::object_t mdr;
- mdr["@odata.id"] = mdrUri;
- mrdJsonArray.emplace_back(std::move(mdr));
- }
- asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray;
- });
+ std::shared_ptr<Subscription> subValue =
+ EventServiceManager::getInstance().getSubscription(param);
+ if (subValue == nullptr)
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::not_found);
+ return;
+ }
+ const std::string& id = param;
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EventDestination.v1_8_0.EventDestination";
+ asyncResp->res.jsonValue["Protocol"] =
+ event_destination::EventDestinationProtocol::Redfish;
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/EventService/Subscriptions/{}", id);
+ asyncResp->res.jsonValue["Id"] = id;
+ asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
+ asyncResp->res.jsonValue["Destination"] =
+ subValue->destinationUrl;
+ asyncResp->res.jsonValue["Context"] = subValue->customText;
+ asyncResp->res.jsonValue["SubscriptionType"] =
+ subValue->subscriptionType;
+ asyncResp->res.jsonValue["HttpHeaders"] =
+ nlohmann::json::array();
+ asyncResp->res.jsonValue["EventFormatType"] =
+ subValue->eventFormatType;
+ asyncResp->res.jsonValue["RegistryPrefixes"] =
+ subValue->registryPrefixes;
+ asyncResp->res.jsonValue["ResourceTypes"] =
+ subValue->resourceTypes;
+
+ asyncResp->res.jsonValue["MessageIds"] =
+ subValue->registryMsgIds;
+ asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
+ subValue->retryPolicy;
+ asyncResp->res.jsonValue["VerifyCertificate"] =
+ subValue->verifyCertificate;
+
+ nlohmann::json::array_t mrdJsonArray;
+ for (const auto& mdrUri : subValue->metricReportDefinitions)
+ {
+ nlohmann::json::object_t mdr;
+ mdr["@odata.id"] = mdrUri;
+ mrdJsonArray.emplace_back(std::move(mdr));
+ }
+ asyncResp->res.jsonValue["MetricReportDefinitions"] =
+ mrdJsonArray;
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
// The below privilege is wrong, it should be ConfigureManager OR
// ConfigureSelf
@@ -692,70 +724,81 @@ inline void requestRoutesEventDestination(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
- std::shared_ptr<Subscription> subValue =
- EventServiceManager::getInstance().getSubscription(param);
- if (subValue == nullptr)
- {
- asyncResp->res.result(boost::beast::http::status::not_found);
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+ std::shared_ptr<Subscription> subValue =
+ EventServiceManager::getInstance().getSubscription(param);
+ if (subValue == nullptr)
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::not_found);
+ return;
+ }
- std::optional<std::string> context;
- std::optional<std::string> retryPolicy;
- std::optional<std::vector<nlohmann::json::object_t>> headers;
+ std::optional<std::string> context;
+ std::optional<std::string> retryPolicy;
+ std::optional<bool> verifyCertificate;
+ std::optional<std::vector<nlohmann::json::object_t>> headers;
- if (!json_util::readJsonPatch(req, asyncResp->res, "Context", context,
- "DeliveryRetryPolicy", retryPolicy,
- "HttpHeaders", headers))
- {
- return;
- }
+ if (!json_util::readJsonPatch(
+ req, asyncResp->res, "Context", context,
+ "VerifyCertificate", verifyCertificate,
+ "DeliveryRetryPolicy", retryPolicy, "HttpHeaders",
+ headers))
+ {
+ return;
+ }
- if (context)
- {
- subValue->customText = *context;
- }
+ if (context)
+ {
+ subValue->customText = *context;
+ }
- if (headers)
- {
- boost::beast::http::fields fields;
- for (const nlohmann::json::object_t& headerChunk : *headers)
- {
- for (const auto& it : headerChunk)
+ if (headers)
{
- const std::string* value =
- it.second.get_ptr<const std::string*>();
- if (value == nullptr)
+ boost::beast::http::fields fields;
+ for (const nlohmann::json::object_t& headerChunk : *headers)
{
- messages::propertyValueFormatError(
- asyncResp->res, it.second,
- "HttpHeaders/" + it.first);
+ for (const auto& it : headerChunk)
+ {
+ const std::string* value =
+ it.second.get_ptr<const std::string*>();
+ if (value == nullptr)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, it.second,
+ "HttpHeaders/" + it.first);
+ return;
+ }
+ fields.set(it.first, *value);
+ }
+ }
+ subValue->httpHeaders = std::move(fields);
+ }
+
+ if (retryPolicy)
+ {
+ if (std::ranges::find(supportedRetryPolicies,
+ *retryPolicy) ==
+ supportedRetryPolicies.end())
+ {
+ messages::propertyValueNotInList(asyncResp->res,
+ *retryPolicy,
+ "DeliveryRetryPolicy");
return;
}
- fields.set(it.first, *value);
+ subValue->retryPolicy = *retryPolicy;
}
- }
- subValue->httpHeaders = std::move(fields);
- }
- if (retryPolicy)
- {
- if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
- supportedRetryPolicies.end())
- {
- messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
- "DeliveryRetryPolicy");
- return;
- }
- subValue->retryPolicy = *retryPolicy;
- }
+ if (verifyCertificate)
+ {
+ subValue->verifyCertificate = *verifyCertificate;
+ }
- EventServiceManager::getInstance().updateSubscriptionData();
- });
+ EventServiceManager::getInstance().updateSubscriptionData();
+ });
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
// The below privilege is wrong, it should be ConfigureManager OR
// ConfigureSelf
@@ -766,25 +809,28 @@ inline void requestRoutesEventDestination(App& app)
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& param) {
- if (!redfish::setUpRedfishRoute(app, req, asyncResp))
- {
- return;
- }
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
- if (param.starts_with("snmp"))
- {
- deleteSnmpTrapClient(asyncResp, param);
- EventServiceManager::getInstance().deleteSubscription(param);
- return;
- }
+ if (param.starts_with("snmp"))
+ {
+ deleteSnmpTrapClient(asyncResp, param);
+ EventServiceManager::getInstance().deleteSubscription(
+ param);
+ return;
+ }
- if (!EventServiceManager::getInstance().isSubscriptionExist(param))
- {
- asyncResp->res.result(boost::beast::http::status::not_found);
- return;
- }
- EventServiceManager::getInstance().deleteSubscription(param);
- });
+ if (!EventServiceManager::getInstance().isSubscriptionExist(
+ param))
+ {
+ asyncResp->res.result(
+ boost::beast::http::status::not_found);
+ return;
+ }
+ EventServiceManager::getInstance().deleteSubscription(param);
+ });
}
} // namespace redfish