Move UserSubscription to composition
This allows for two very important simplifying changes. First, we can
use the default copy operators on the UserSubscription class, which is
far less error prone than writing it manually, which we have two copies
of in code already.
Second, it allows the Subscription class to move to using values rather
than shared_ptr everywhere, which cleans up a significant amount of
code.
Tested:
Ran Redfish-Event-Listener, subscription created and destroyed
correctly.
Calling POST SubmitTestEvent showed events propagating to server.
Change-Id: I6d258cfe3594edddf3960ae2d4559d70acca1bf8
Signed-off-by: Ed Tanous <ed@tanous.net>
diff --git a/http/http_client.hpp b/http/http_client.hpp
index 0df0656..546d92c 100644
--- a/http/http_client.hpp
+++ b/http/http_client.hpp
@@ -848,7 +848,9 @@
private:
std::unordered_map<std::string, std::shared_ptr<ConnectionPool>>
connectionPools;
- boost::asio::io_context& ioc;
+
+ // reference_wrapper here makes HttpClient movable
+ std::reference_wrapper<boost::asio::io_context> ioc;
std::shared_ptr<ConnectionPolicy> connPolicy;
// Used as a dummy callback by sendData() in order to call
@@ -868,8 +870,8 @@
HttpClient(const HttpClient&) = delete;
HttpClient& operator=(const HttpClient&) = delete;
- HttpClient(HttpClient&&) = delete;
- HttpClient& operator=(HttpClient&&) = delete;
+ HttpClient(HttpClient&& client) = default;
+ HttpClient& operator=(HttpClient&& client) = default;
~HttpClient() = default;
// Send a request to destIP where additional processing of the
diff --git a/include/event_service_store.hpp b/include/event_service_store.hpp
index 9761eb5..f875986 100644
--- a/include/event_service_store.hpp
+++ b/include/event_service_store.hpp
@@ -12,6 +12,7 @@
struct UserSubscription
{
+ // Represents a Redfish EventDestination instance
std::string id;
boost::urls::url destinationUrl;
std::string protocol;
@@ -27,11 +28,10 @@
std::vector<std::string> metricReportDefinitions;
std::vector<std::string> originResources;
- static std::shared_ptr<UserSubscription> fromJson(
+ static std::optional<UserSubscription> fromJson(
const nlohmann::json::object_t& j, const bool loadFromOldConfig = false)
{
- std::shared_ptr<UserSubscription> subvalue =
- std::make_shared<UserSubscription>();
+ UserSubscription subvalue;
for (const auto& element : j)
{
if (element.first == "Id")
@@ -42,7 +42,7 @@
{
continue;
}
- subvalue->id = *value;
+ subvalue.id = *value;
}
else if (element.first == "Destination")
{
@@ -58,7 +58,7 @@
{
continue;
}
- subvalue->destinationUrl = std::move(*url);
+ subvalue.destinationUrl = std::move(*url);
}
else if (element.first == "Protocol")
{
@@ -68,7 +68,7 @@
{
continue;
}
- subvalue->protocol = *value;
+ subvalue.protocol = *value;
}
else if (element.first == "VerifyCertificate")
{
@@ -77,7 +77,7 @@
{
continue;
}
- subvalue->verifyCertificate = *value;
+ subvalue.verifyCertificate = *value;
}
else if (element.first == "DeliveryRetryPolicy")
{
@@ -87,7 +87,7 @@
{
continue;
}
- subvalue->retryPolicy = *value;
+ subvalue.retryPolicy = *value;
}
else if (element.first == "Context")
{
@@ -97,7 +97,7 @@
{
continue;
}
- subvalue->customText = *value;
+ subvalue.customText = *value;
}
else if (element.first == "EventFormatType")
{
@@ -107,7 +107,7 @@
{
continue;
}
- subvalue->eventFormatType = *value;
+ subvalue.eventFormatType = *value;
}
else if (element.first == "SubscriptionType")
{
@@ -117,7 +117,7 @@
{
continue;
}
- subvalue->subscriptionType = *value;
+ subvalue.subscriptionType = *value;
}
else if (element.first == "MessageIds")
{
@@ -135,7 +135,7 @@
{
continue;
}
- subvalue->registryMsgIds.emplace_back(*value);
+ subvalue.registryMsgIds.emplace_back(*value);
}
}
else if (element.first == "RegistryPrefixes")
@@ -154,7 +154,7 @@
{
continue;
}
- subvalue->registryPrefixes.emplace_back(*value);
+ subvalue.registryPrefixes.emplace_back(*value);
}
}
else if (element.first == "ResourceTypes")
@@ -173,7 +173,7 @@
{
continue;
}
- subvalue->resourceTypes.emplace_back(*value);
+ subvalue.resourceTypes.emplace_back(*value);
}
}
else if (element.first == "HttpHeaders")
@@ -194,7 +194,7 @@
val.first);
continue;
}
- subvalue->httpHeaders.set(val.first, *value);
+ subvalue.httpHeaders.set(val.first, *value);
}
}
else if (element.first == "MetricReportDefinitions")
@@ -213,7 +213,7 @@
{
continue;
}
- subvalue->metricReportDefinitions.emplace_back(*value);
+ subvalue.metricReportDefinitions.emplace_back(*value);
}
}
else if (element.first == "OriginResources")
@@ -232,7 +232,7 @@
{
continue;
}
- subvalue->originResources.emplace_back(*value);
+ subvalue.originResources.emplace_back(*value);
}
}
else
@@ -244,15 +244,14 @@
}
}
- if ((subvalue->id.empty() && !loadFromOldConfig) ||
- subvalue->destinationUrl.empty() || subvalue->protocol.empty() ||
- subvalue->retryPolicy.empty() ||
- subvalue->eventFormatType.empty() ||
- subvalue->subscriptionType.empty())
+ if ((subvalue.id.empty() && !loadFromOldConfig) ||
+ subvalue.destinationUrl.empty() || subvalue.protocol.empty() ||
+ subvalue.retryPolicy.empty() || subvalue.eventFormatType.empty() ||
+ subvalue.subscriptionType.empty())
{
BMCWEB_LOG_ERROR("Subscription missing required field "
"information, refusing to restore");
- return nullptr;
+ return std::nullopt;
}
return subvalue;
@@ -307,7 +306,7 @@
class EventServiceStore
{
public:
- boost::container::flat_map<std::string, std::shared_ptr<UserSubscription>>
+ boost::container::flat_map<std::string, UserSubscription>
subscriptionsConfigMap;
EventServiceConfig eventServiceConfig;
diff --git a/include/persistent_data.hpp b/include/persistent_data.hpp
index bcecf9f..13a43c4 100644
--- a/include/persistent_data.hpp
+++ b/include/persistent_data.hpp
@@ -157,10 +157,10 @@
{
for (const auto& elem : item.second)
{
- std::shared_ptr<UserSubscription> newSubscription =
+ std::optional<UserSubscription> newSub =
UserSubscription::fromJson(elem);
- if (newSubscription == nullptr)
+ if (!newSub)
{
BMCWEB_LOG_ERROR("Problem reading subscription "
"from persistent store");
@@ -168,11 +168,13 @@
}
BMCWEB_LOG_DEBUG("Restored subscription: {} {}",
- newSubscription->id,
- newSubscription->customText);
- EventServiceStore::getInstance()
- .subscriptionsConfigMap.emplace(
- newSubscription->id, newSubscription);
+ newSub->id, newSub->customText);
+
+ boost::container::flat_map<
+ std::string, UserSubscription>& configMap =
+ EventServiceStore::getInstance()
+ .subscriptionsConfigMap;
+ configMap.emplace(newSub->id, *newSub);
}
}
else
@@ -268,7 +270,7 @@
for (const auto& it :
EventServiceStore::getInstance().subscriptionsConfigMap)
{
- const UserSubscription& subValue = *it.second;
+ const UserSubscription& subValue = it.second;
if (subValue.subscriptionType == "SSE")
{
BMCWEB_LOG_DEBUG("The subscription type is SSE, so skipping.");
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 8fd0157..f9ac760 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -267,7 +267,7 @@
} // namespace event_log
-class Subscription : public persistent_data::UserSubscription
+class Subscription
{
public:
Subscription(const Subscription&) = delete;
@@ -279,7 +279,7 @@
boost::asio::io_context& ioc) :
policy(std::make_shared<crow::ConnectionPolicy>())
{
- destinationUrl = url;
+ userSub.destinationUrl = url;
client.emplace(ioc, policy);
// Subscription constructor
policy->invalidResp = retryRespHandler;
@@ -303,10 +303,11 @@
if (client)
{
- client->sendData(
- std::move(msg), destinationUrl,
- static_cast<ensuressl::VerifyCertificate>(verifyCertificate),
- httpHeaders, boost::beast::http::verb::post);
+ client->sendData(std::move(msg), userSub.destinationUrl,
+ static_cast<ensuressl::VerifyCertificate>(
+ userSub.verifyCertificate),
+ userSub.httpHeaders,
+ boost::beast::http::verb::post);
return true;
}
@@ -322,14 +323,14 @@
std::string_view resType)
{
// If resourceTypes list is empty, assume all
- if (!resourceTypes.empty())
+ if (!userSub.resourceTypes.empty())
{
// Search the resourceTypes list for the subscription.
auto resourceTypeIndex = std::ranges::find_if(
- resourceTypes, [resType](const std::string& rtEntry) {
+ userSub.resourceTypes, [resType](const std::string& rtEntry) {
return rtEntry == resType;
});
- if (resourceTypeIndex == resourceTypes.end())
+ if (resourceTypeIndex == userSub.resourceTypes.end())
{
BMCWEB_LOG_DEBUG("Not subscribed to this resource");
return false;
@@ -340,7 +341,7 @@
// If registryPrefixes list is empty, don't filter events
// send everything.
- if (!registryPrefixes.empty())
+ if (!userSub.registryPrefixes.empty())
{
auto eventJson = eventMessage.find("MessageId");
if (eventJson == eventMessage.end())
@@ -361,14 +362,14 @@
event_log::getRegistryAndMessageKey(*messageId, registry,
messageKey);
- auto obj = std::ranges::find(registryPrefixes, registry);
- if (obj == registryPrefixes.end())
+ auto obj = std::ranges::find(userSub.registryPrefixes, registry);
+ if (obj == userSub.registryPrefixes.end())
{
return false;
}
}
- if (!originResources.empty())
+ if (!userSub.originResources.empty())
{
auto eventJson = eventMessage.find("OriginOfCondition");
if (eventJson == eventMessage.end())
@@ -384,16 +385,17 @@
return false;
}
- auto obj = std::ranges::find(originResources, *originOfCondition);
+ auto obj =
+ std::ranges::find(userSub.originResources, *originOfCondition);
- if (obj == originResources.end())
+ if (obj == userSub.originResources.end())
{
return false;
}
}
// If registryMsgIds list is empty, assume all
- if (!registryMsgIds.empty())
+ if (!userSub.registryMsgIds.empty())
{
auto eventJson = eventMessage.find("MessageId");
if (eventJson == eventMessage.end())
@@ -418,14 +420,15 @@
BMCWEB_LOG_DEBUG("extracted registry {}", registry);
BMCWEB_LOG_DEBUG("extracted message key {}", messageKey);
- auto obj = std::ranges::find(
- registryMsgIds, std::format("{}.{}", registry, messageKey));
- if (obj == registryMsgIds.end())
+ auto obj =
+ std::ranges::find(userSub.registryMsgIds,
+ std::format("{}.{}", registry, messageKey));
+ if (obj == userSub.registryMsgIds.end())
{
BMCWEB_LOG_DEBUG("did not find registry {} in registryMsgIds",
registry);
BMCWEB_LOG_DEBUG("registryMsgIds has {} entries",
- registryMsgIds.size());
+ userSub.registryMsgIds.size());
return false;
}
}
@@ -456,7 +459,7 @@
logEntryJson["MessageArgs"] = nlohmann::json::array();
logEntryJson["EventTimestamp"] =
redfish::time_utils::getDateTimeOffsetNow().first;
- logEntryJson["Context"] = customText;
+ logEntryJson["Context"] = userSub.customText;
nlohmann::json msg;
msg["@odata.type"] = "#Event.v1_4_0.Event";
@@ -481,7 +484,7 @@
nlohmann::json::object_t bmcLogEntry;
if (event_log::formatEventLogEntry(
logEntry.id, logEntry.messageId, messageArgsView,
- logEntry.timestamp, customText, bmcLogEntry) != 0)
+ logEntry.timestamp, userSub.customText, bmcLogEntry) != 0)
{
BMCWEB_LOG_DEBUG("Read eventLog entry failed");
continue;
@@ -522,10 +525,11 @@
reportId);
// Empty list means no filter. Send everything.
- if (!metricReportDefinitions.empty())
+ if (!userSub.metricReportDefinitions.empty())
{
- if (std::ranges::find(metricReportDefinitions, mrdUri.buffer()) ==
- metricReportDefinitions.end())
+ if (std::ranges::find(userSub.metricReportDefinitions,
+ mrdUri.buffer()) ==
+ userSub.metricReportDefinitions.end())
{
return;
}
@@ -542,9 +546,9 @@
// Context is set by user during Event subscription and it must be
// set for MetricReport response.
- if (!customText.empty())
+ if (!userSub.customText.empty())
{
- msg["Context"] = customText;
+ msg["Context"] = userSub.customText;
}
std::string strMsg =
@@ -602,6 +606,8 @@
boost::system::errc::success);
}
+ persistent_data::UserSubscription userSub;
+
private:
std::string subId;
uint64_t eventSeqNum = 1;
@@ -677,11 +683,10 @@
for (const auto& it : persistent_data::EventServiceStore::getInstance()
.subscriptionsConfigMap)
{
- std::shared_ptr<persistent_data::UserSubscription> newSub =
- it.second;
+ const persistent_data::UserSubscription& newSub = it.second;
boost::system::result<boost::urls::url> url =
- boost::urls::parse_absolute_uri(newSub->destinationUrl);
+ boost::urls::parse_absolute_uri(newSub.destinationUrl);
if (!url)
{
@@ -691,27 +696,9 @@
}
std::shared_ptr<Subscription> subValue =
std::make_shared<Subscription>(*url, ioc);
+ subValue->userSub = newSub;
- subValue->id = newSub->id;
- subValue->destinationUrl = newSub->destinationUrl;
- subValue->protocol = newSub->protocol;
- subValue->verifyCertificate = newSub->verifyCertificate;
- subValue->retryPolicy = newSub->retryPolicy;
- subValue->customText = newSub->customText;
- subValue->eventFormatType = newSub->eventFormatType;
- subValue->subscriptionType = newSub->subscriptionType;
- subValue->registryMsgIds = newSub->registryMsgIds;
- subValue->registryPrefixes = newSub->registryPrefixes;
- subValue->resourceTypes = newSub->resourceTypes;
- subValue->httpHeaders = newSub->httpHeaders;
- subValue->metricReportDefinitions = newSub->metricReportDefinitions;
- subValue->originResources = newSub->originResources;
-
- if (subValue->id.empty())
- {
- BMCWEB_LOG_ERROR("Failed to add subscription");
- }
- subscriptionsMap.insert(std::pair(subValue->id, subValue));
+ subscriptionsMap.insert(std::pair(subValue->userSub.id, subValue));
updateNoOfSubscribersCount();
@@ -754,16 +741,18 @@
{
for (const auto& elem : item.second)
{
- std::shared_ptr<persistent_data::UserSubscription>
+ std::optional<persistent_data::UserSubscription>
newSubscription =
persistent_data::UserSubscription::fromJson(elem,
true);
- if (newSubscription == nullptr)
+ if (!newSubscription)
{
BMCWEB_LOG_ERROR("Problem reading subscription "
"from old persistent store");
continue;
}
+ persistent_data::UserSubscription& newSub =
+ *newSubscription;
std::uniform_int_distribution<uint32_t> dist(0);
bmcweb::OpenSSLGenerator gen;
@@ -779,11 +768,11 @@
retry = 0;
break;
}
- newSubscription->id = id;
+ newSub.id = id;
auto inserted =
persistent_data::EventServiceStore::getInstance()
.subscriptionsConfigMap.insert(
- std::pair(id, newSubscription));
+ std::pair(id, newSub));
if (inserted.second)
{
break;
@@ -885,11 +874,11 @@
for (const auto& it : subscriptionsMap)
{
std::shared_ptr<Subscription> entry = it.second;
- if (entry->eventFormatType == eventFormatType)
+ if (entry->userSub.eventFormatType == eventFormatType)
{
eventLogSubCount++;
}
- else if (entry->eventFormatType == metricReportFormatType)
+ else if (entry->userSub.eventFormatType == metricReportFormatType)
{
metricReportSubCount++;
}
@@ -953,24 +942,10 @@
return "";
}
- std::shared_ptr<persistent_data::UserSubscription> newSub =
- std::make_shared<persistent_data::UserSubscription>();
- newSub->id = id;
- newSub->destinationUrl = subValue->destinationUrl;
- newSub->protocol = subValue->protocol;
- newSub->retryPolicy = subValue->retryPolicy;
- newSub->customText = subValue->customText;
- newSub->eventFormatType = subValue->eventFormatType;
- newSub->subscriptionType = subValue->subscriptionType;
- newSub->registryMsgIds = subValue->registryMsgIds;
- newSub->registryPrefixes = subValue->registryPrefixes;
- newSub->resourceTypes = subValue->resourceTypes;
- newSub->httpHeaders = subValue->httpHeaders;
- newSub->metricReportDefinitions = subValue->metricReportDefinitions;
- newSub->originResources = subValue->originResources;
+ persistent_data::UserSubscription newSub(subValue->userSub);
persistent_data::EventServiceStore::getInstance()
- .subscriptionsConfigMap.emplace(newSub->id, newSub);
+ .subscriptionsConfigMap.emplace(newSub.id, newSub);
updateNoOfSubscribersCount();
@@ -1044,19 +1019,28 @@
return obj != subscriptionsMap.end();
}
- void deleteSubscription(const std::string& id)
+ bool deleteSubscription(const std::string& id)
{
auto obj = subscriptionsMap.find(id);
- if (obj != subscriptionsMap.end())
+ if (obj == subscriptionsMap.end())
{
- subscriptionsMap.erase(obj);
- auto obj2 = persistent_data::EventServiceStore::getInstance()
- .subscriptionsConfigMap.find(id);
- persistent_data::EventServiceStore::getInstance()
- .subscriptionsConfigMap.erase(obj2);
- updateNoOfSubscribersCount();
- updateSubscriptionData();
+ BMCWEB_LOG_WARNING("Could not find subscription with id {}", id);
+ return false;
}
+ subscriptionsMap.erase(obj);
+ auto& event = persistent_data::EventServiceStore::getInstance();
+ auto persistentObj = event.subscriptionsConfigMap.find(id);
+ if (persistentObj == event.subscriptionsConfigMap.end())
+ {
+ BMCWEB_LOG_ERROR("Subscription wasn't in persistent data");
+ return true;
+ }
+ persistent_data::EventServiceStore::getInstance()
+ .subscriptionsConfigMap.erase(persistentObj);
+ updateNoOfSubscribersCount();
+ updateSubscriptionData();
+
+ return true;
}
void deleteSseSubscription(const crow::sse_socket::Connection& thisConn)
@@ -1088,7 +1072,8 @@
subscriptionsMap,
[](const std::pair<std::string, std::shared_ptr<Subscription>>&
entry) {
- return (entry.second->subscriptionType == subscriptionTypeSSE);
+ return (entry.second->userSub.subscriptionType ==
+ subscriptionTypeSSE);
});
return static_cast<size_t>(size);
}
@@ -1254,7 +1239,7 @@
for (const auto& it : subscriptionsMap)
{
std::shared_ptr<Subscription> entry = it.second;
- if (entry->eventFormatType == "Event")
+ if (entry->userSub.eventFormatType == "Event")
{
entry->filterAndSendEventLogs(eventRecords);
}
@@ -1452,7 +1437,7 @@
EventServiceManager::getInstance().subscriptionsMap)
{
Subscription& entry = *it.second;
- if (entry.eventFormatType == metricReportFormatType)
+ if (entry.userSub.eventFormatType == metricReportFormatType)
{
entry.filterAndSendReports(id, *readings);
}
diff --git a/redfish-core/include/snmp_trap_event_clients.hpp b/redfish-core/include/snmp_trap_event_clients.hpp
index d71d59f..ebc0280 100644
--- a/redfish-core/include/snmp_trap_event_clients.hpp
+++ b/redfish-core/include/snmp_trap_event_clients.hpp
@@ -70,17 +70,6 @@
asyncResp->res.jsonValue["EventFormatType"] =
event_destination::EventFormatType::Event;
- std::shared_ptr<Subscription> subValue =
- EventServiceManager::getInstance().getSubscription(id);
- if (subValue != nullptr)
- {
- asyncResp->res.jsonValue["Context"] = subValue->customText;
- }
- else
- {
- asyncResp->res.jsonValue["Context"] = "";
- }
-
sdbusplus::asio::getAllProperties(
*crow::connections::systemBus, "xyz.openbmc_project.Network.SNMP",
objectPath, "xyz.openbmc_project.Network.Client",
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index 76f3c5a..60946b2 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -302,18 +302,27 @@
std::optional<std::vector<nlohmann::json::object_t>> headers;
std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
+ // clang-format off
if (!json_util::readJsonPatch(
- req, asyncResp->res, "Destination", destUrl, "Context",
- context, "Protocol", protocol, "SubscriptionType",
- subscriptionType, "EventFormatType", eventFormatType2,
- "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
- "OriginResources", originResources, "MessageIds", msgIds,
+ req, asyncResp->res,
+ "Context", context,
"DeliveryRetryPolicy", retryPolicy,
- "MetricReportDefinitions", mrdJsonArray, "ResourceTypes",
- resTypes, "VerifyCertificate", verifyCertificate))
+ "Destination", destUrl,
+ "EventFormatType", eventFormatType2,
+ "HttpHeaders", headers,
+ "MessageIds", msgIds,
+ "MetricReportDefinitions", mrdJsonArray,
+ "OriginResources", originResources,
+ "Protocol", protocol,
+ "RegistryPrefixes", regPrefixes,
+ "ResourceTypes", resTypes,
+ "SubscriptionType", subscriptionType,
+ "VerifyCertificate", verifyCertificate
+ ))
{
return;
}
+ // clang-format on
// https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
static constexpr const uint16_t maxDestinationSize = 2000;
@@ -425,7 +434,7 @@
std::shared_ptr<Subscription> subValue =
std::make_shared<Subscription>(*url, app.ioContext());
- subValue->destinationUrl = std::move(*url);
+ subValue->userSub.destinationUrl = std::move(*url);
if (subscriptionType)
{
@@ -435,11 +444,12 @@
asyncResp->res, *subscriptionType, "SubscriptionType");
return;
}
- subValue->subscriptionType = *subscriptionType;
+ subValue->userSub.subscriptionType = *subscriptionType;
}
else
{
- subValue->subscriptionType = "RedfishEvent"; // Default
+ // Default
+ subValue->userSub.subscriptionType = "RedfishEvent";
}
if (protocol != "Redfish")
@@ -448,11 +458,11 @@
"Protocol");
return;
}
- subValue->protocol = protocol;
+ subValue->userSub.protocol = protocol;
if (verifyCertificate)
{
- subValue->verifyCertificate = *verifyCertificate;
+ subValue->userSub.verifyCertificate = *verifyCertificate;
}
if (eventFormatType2)
@@ -465,12 +475,12 @@
asyncResp->res, *eventFormatType2, "EventFormatType");
return;
}
- subValue->eventFormatType = *eventFormatType2;
+ subValue->userSub.eventFormatType = *eventFormatType2;
}
else
{
// If not specified, use default "Event"
- subValue->eventFormatType = "Event";
+ subValue->userSub.eventFormatType = "Event";
}
if (context)
@@ -483,7 +493,7 @@
maxContextSize);
return;
}
- subValue->customText = *context;
+ subValue->userSub.customText = *context;
}
if (headers)
@@ -516,7 +526,7 @@
asyncResp->res, "HttpHeaders", maxHeaderSizeED);
return;
}
- subValue->httpHeaders.set(item.first, *value);
+ subValue->userSub.httpHeaders.set(item.first, *value);
}
}
}
@@ -533,12 +543,12 @@
return;
}
}
- subValue->registryPrefixes = *regPrefixes;
+ subValue->userSub.registryPrefixes = *regPrefixes;
}
if (originResources)
{
- subValue->originResources = *originResources;
+ subValue->userSub.originResources = *originResources;
}
if (resTypes)
@@ -553,7 +563,7 @@
return;
}
}
- subValue->resourceTypes = *resTypes;
+ subValue->userSub.resourceTypes = *resTypes;
}
if (msgIds)
@@ -562,14 +572,14 @@
// If no registry prefixes are mentioned, consider all
// supported prefixes
- if (subValue->registryPrefixes.empty())
+ if (subValue->userSub.registryPrefixes.empty())
{
registryPrefix.assign(supportedRegPrefixes.begin(),
supportedRegPrefixes.end());
}
else
{
- registryPrefix = subValue->registryPrefixes;
+ registryPrefix = subValue->userSub.registryPrefixes;
}
for (const std::string& id : *msgIds)
@@ -603,7 +613,7 @@
}
}
- subValue->registryMsgIds = *msgIds;
+ subValue->userSub.registryMsgIds = *msgIds;
}
if (retryPolicy)
@@ -615,12 +625,12 @@
asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
return;
}
- subValue->retryPolicy = *retryPolicy;
+ subValue->userSub.retryPolicy = *retryPolicy;
}
else
{
// Default "TerminateAfterRetries"
- subValue->retryPolicy = "TerminateAfterRetries";
+ subValue->userSub.retryPolicy = "TerminateAfterRetries";
}
if (mrdJsonArray)
@@ -635,7 +645,8 @@
{
return;
}
- subValue->metricReportDefinitions.emplace_back(mrdUri);
+ subValue->userSub.metricReportDefinitions.emplace_back(
+ mrdUri);
}
}
@@ -683,44 +694,38 @@
}
const std::string& id = param;
- asyncResp->res.jsonValue["@odata.type"] =
- "#EventDestination.v1_14_1.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;
+ const persistent_data::UserSubscription& userSub =
+ subValue->userSub;
- asyncResp->res.jsonValue["MessageIds"] =
- subValue->registryMsgIds;
- asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
- subValue->retryPolicy;
- asyncResp->res.jsonValue["VerifyCertificate"] =
- subValue->verifyCertificate;
+ nlohmann::json& jVal = asyncResp->res.jsonValue;
+ jVal["@odata.type"] =
+ "#EventDestination.v1_14_1.EventDestination";
+ jVal["Protocol"] =
+ event_destination::EventDestinationProtocol::Redfish;
+ jVal["@odata.id"] = boost::urls::format(
+ "/redfish/v1/EventService/Subscriptions/{}", id);
+ jVal["Id"] = id;
+ jVal["Name"] = "Event Destination " + id;
+ jVal["Destination"] = userSub.destinationUrl;
+ jVal["Context"] = userSub.customText;
+ jVal["SubscriptionType"] = userSub.subscriptionType;
+ jVal["HttpHeaders"] = nlohmann::json::array();
+ jVal["EventFormatType"] = userSub.eventFormatType;
+ jVal["RegistryPrefixes"] = userSub.registryPrefixes;
+ jVal["ResourceTypes"] = userSub.resourceTypes;
+
+ jVal["MessageIds"] = userSub.registryMsgIds;
+ jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
+ jVal["VerifyCertificate"] = userSub.verifyCertificate;
nlohmann::json::array_t mrdJsonArray;
- for (const auto& mdrUri : subValue->metricReportDefinitions)
+ for (const auto& mdrUri : userSub.metricReportDefinitions)
{
nlohmann::json::object_t mdr;
mdr["@odata.id"] = mdrUri;
mrdJsonArray.emplace_back(std::move(mdr));
}
- asyncResp->res.jsonValue["MetricReportDefinitions"] =
- mrdJsonArray;
+ jVal["MetricReportDefinitions"] = mrdJsonArray;
});
BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
// The below privilege is wrong, it should be ConfigureManager OR
@@ -761,7 +766,7 @@
if (context)
{
- subValue->customText = *context;
+ subValue->userSub.customText = *context;
}
if (headers)
@@ -783,7 +788,7 @@
fields.set(it.first, *value);
}
}
- subValue->httpHeaders = std::move(fields);
+ subValue->userSub.httpHeaders = std::move(fields);
}
if (retryPolicy)
@@ -797,12 +802,12 @@
"DeliveryRetryPolicy");
return;
}
- subValue->retryPolicy = *retryPolicy;
+ subValue->userSub.retryPolicy = *retryPolicy;
}
if (verifyCertificate)
{
- subValue->verifyCertificate = *verifyCertificate;
+ subValue->userSub.verifyCertificate = *verifyCertificate;
}
EventServiceManager::getInstance().updateSubscriptionData();
@@ -821,23 +826,21 @@
{
return;
}
-
+ EventServiceManager& event = EventServiceManager::getInstance();
if (param.starts_with("snmp"))
{
deleteSnmpTrapClient(asyncResp, param);
- EventServiceManager::getInstance().deleteSubscription(
- param);
+ event.deleteSubscription(param);
return;
}
- if (!EventServiceManager::getInstance().isSubscriptionExist(
- param))
+ if (!event.deleteSubscription(param))
{
- asyncResp->res.result(
- boost::beast::http::status::not_found);
+ messages::resourceNotFound(asyncResp->res,
+ "EventDestination", param);
return;
}
- EventServiceManager::getInstance().deleteSubscription(param);
+ messages::success(asyncResp->res);
});
}
diff --git a/redfish-core/lib/eventservice_sse.hpp b/redfish-core/lib/eventservice_sse.hpp
index c0a9527..80c0a3a 100644
--- a/redfish-core/lib/eventservice_sse.hpp
+++ b/redfish-core/lib/eventservice_sse.hpp
@@ -44,16 +44,15 @@
std::string lastEventId(req.getHeaderValue("Last-Event-Id"));
- std::shared_ptr<redfish::Subscription> subValue =
- std::make_shared<redfish::Subscription>(conn);
+ std::shared_ptr<Subscription> subValue =
+ std::make_shared<Subscription>(conn);
// GET on this URI means, Its SSE subscriptionType.
- subValue->subscriptionType = redfish::subscriptionTypeSSE;
+ subValue->userSub.subscriptionType = redfish::subscriptionTypeSSE;
- subValue->protocol = "Redfish";
- subValue->retryPolicy = "TerminateAfterRetries";
- subValue->eventFormatType = "Event";
- subValue->filter = filter;
+ subValue->userSub.protocol = "Redfish";
+ subValue->userSub.retryPolicy = "TerminateAfterRetries";
+ subValue->userSub.eventFormatType = "Event";
std::string id = manager.addSSESubscription(subValue, lastEventId);
if (id.empty())
diff --git a/test/redfish-core/include/event_service_manager_test.cpp b/test/redfish-core/include/event_service_manager_test.cpp
index bb86e77..fa3818d 100644
--- a/test/redfish-core/include/event_service_manager_test.cpp
+++ b/test/redfish-core/include/event_service_manager_test.cpp
@@ -1,4 +1,5 @@
#include "event_service_manager.hpp"
+#include "event_service_store.hpp"
#include "filter_expr_printer.hpp"
#include <boost/asio/io_context.hpp>
@@ -19,83 +20,88 @@
boost::urls::url url;
{
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
nlohmann::json::object_t event;
// Default constructed should always pass
- EXPECT_TRUE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_TRUE(ioSub.eventMatchesFilter(event, "Event"));
}
{
nlohmann::json::object_t event;
// Resource types filter
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
+ persistent_data::UserSubscription& sub = ioSub.userSub;
sub.resourceTypes.emplace_back("Task");
- EXPECT_FALSE(sub.eventMatchesFilter(event, "Event"));
- EXPECT_TRUE(sub.eventMatchesFilter(event, "Task"));
+ EXPECT_FALSE(ioSub.eventMatchesFilter(event, "Event"));
+ EXPECT_TRUE(ioSub.eventMatchesFilter(event, "Task"));
}
{
nlohmann::json::object_t event;
// Resource types filter
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
+ persistent_data::UserSubscription& sub = ioSub.userSub;
sub.registryMsgIds.emplace_back("OpenBMC.PostComplete");
// Correct message registry
event["MessageId"] = "OpenBMC.0.1.PostComplete";
- EXPECT_TRUE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_TRUE(ioSub.eventMatchesFilter(event, "Event"));
// Different message registry
event["MessageId"] = "Task.0.1.PostComplete";
- EXPECT_FALSE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_FALSE(ioSub.eventMatchesFilter(event, "Event"));
// Different MessageId
event["MessageId"] = "OpenBMC.0.1.NoMatch";
- EXPECT_FALSE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_FALSE(ioSub.eventMatchesFilter(event, "Event"));
}
{
nlohmann::json::object_t event;
// Resource types filter
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
event["MessageId"] = "OpenBMC.0.1.PostComplete";
// Correct message registry
- sub.filter = parseFilter("MessageId eq 'OpenBMC.0.1.PostComplete'");
- EXPECT_TRUE(sub.eventMatchesFilter(event, "Event"));
+ ioSub.filter = parseFilter("MessageId eq 'OpenBMC.0.1.PostComplete'");
+ EXPECT_TRUE(ioSub.eventMatchesFilter(event, "Event"));
// Different message registry
- sub.filter = parseFilter("MessageId ne 'OpenBMC.0.1.PostComplete'");
- EXPECT_FALSE(sub.eventMatchesFilter(event, "Event"));
+ ioSub.filter = parseFilter("MessageId ne 'OpenBMC.0.1.PostComplete'");
+ EXPECT_FALSE(ioSub.eventMatchesFilter(event, "Event"));
}
{
nlohmann::json::object_t event;
// Resource types filter
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
+ persistent_data::UserSubscription& sub = ioSub.userSub;
event["MessageId"] = "OpenBMC.0.1.PostComplete";
// Correct message registry
sub.registryPrefixes.emplace_back("OpenBMC");
- EXPECT_TRUE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_TRUE(ioSub.eventMatchesFilter(event, "Event"));
// Different message registry
event["MessageId"] = "Task.0.1.PostComplete";
- EXPECT_FALSE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_FALSE(ioSub.eventMatchesFilter(event, "Event"));
}
{
nlohmann::json::object_t event;
// Resource types filter
{
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
+ persistent_data::UserSubscription& sub = ioSub.userSub;
event["OriginOfCondition"] = "/redfish/v1/Managers/bmc";
// Correct origin
sub.originResources.emplace_back("/redfish/v1/Managers/bmc");
- EXPECT_TRUE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_TRUE(ioSub.eventMatchesFilter(event, "Event"));
}
{
- Subscription sub(url, io);
+ Subscription ioSub(url, io);
+ persistent_data::UserSubscription& sub = ioSub.userSub;
// Incorrect origin
sub.originResources.clear();
sub.originResources.emplace_back("/redfish/v1/Managers/bmc_not");
- EXPECT_FALSE(sub.eventMatchesFilter(event, "Event"));
+ EXPECT_FALSE(ioSub.eventMatchesFilter(event, "Event"));
}
}
}