diff options
-rw-r--r-- | redfish-core/include/event_service_manager.hpp | 89 | ||||
-rw-r--r-- | redfish-core/lib/event_service.hpp | 58 |
2 files changed, 143 insertions, 4 deletions
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp index 03d5dc3159..801a7ad485 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -267,6 +267,95 @@ int formatEventLogEntry(const std::string& logEntryID, } // namespace event_log #endif +bool isFilterQuerySpecialChar(char c) +{ + switch (c) + { + case '(': + case ')': + case '\'': + return true; + default: + return false; + } +} + +bool readSSEQueryParams(std::string sseFilter, std::string& formatType, + std::vector<std::string>& messageIds, + std::vector<std::string>& registryPrefixes, + std::vector<nlohmann::json>& metricReportDefinitions) +{ + sseFilter.erase(std::remove_if(sseFilter.begin(), sseFilter.end(), + isFilterQuerySpecialChar), + sseFilter.end()); + + std::vector<std::string> result; + boost::split(result, sseFilter, boost::is_any_of(" "), + boost::token_compress_on); + + BMCWEB_LOG_DEBUG << "No of tokens in SEE query: " << result.size(); + + constexpr uint8_t divisor = 4; + constexpr uint8_t minTokenSize = 3; + if (result.size() % divisor != minTokenSize) + { + BMCWEB_LOG_ERROR << "Invalid SSE filter specified."; + return false; + } + + for (std::size_t i = 0; i < result.size(); i += divisor) + { + std::string& key = result[i]; + std::string& op = result[i + 1]; + std::string& value = result[i + 2]; + + if ((i + minTokenSize) < result.size()) + { + std::string& seperator = result[i + minTokenSize]; + // SSE supports only "or" and "and" in query params. + if ((seperator != "or") && (seperator != "and")) + { + BMCWEB_LOG_ERROR + << "Invalid group operator in SSE query parameters"; + return false; + } + } + + // SSE supports only "eq" as per spec. + if (op != "eq") + { + BMCWEB_LOG_ERROR + << "Invalid assignment operator in SSE query parameters"; + return false; + } + + BMCWEB_LOG_DEBUG << key << " : " << value; + if (key == "EventFormatType") + { + formatType = value; + } + else if (key == "MessageId") + { + messageIds.push_back(value); + } + else if (key == "RegistryPrefix") + { + registryPrefixes.push_back(value); + } + else if (key == "MetricReportDefinition") + { + metricReportDefinitions.push_back(value); + } + else + { + BMCWEB_LOG_ERROR << "Invalid property(" << key + << ")in SSE filter query."; + return false; + } + } + return true; +} + class Subscription { public: diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp index adb62389cf..da537bfc1e 100644 --- a/redfish-core/lib/event_service.hpp +++ b/redfish-core/lib/event_service.hpp @@ -72,6 +72,14 @@ class EventService : public Node retryTimeoutInterval; asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes; asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes; + + nlohmann::json supportedSSEFilters = { + {"EventFormatType", true}, {"MessageId", true}, + {"MetricReportDefinition", true}, {"RegistryPrefix", true}, + {"OriginResource", false}, {"ResourceType", false}}; + + asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] = + supportedSSEFilters; } void doPatch(crow::Response& res, const crow::Request& req, @@ -432,19 +440,61 @@ class EventServiceSSE : public Node // GET on this URI means, Its SSE subscriptionType. subValue->subscriptionType = "SSE"; + + // Default values subValue->protocol = "Redfish"; + subValue->retryPolicy = "TerminateAfterRetries"; char* filters = req.urlParams.get("$filter"); if (filters == nullptr) { subValue->eventFormatType = "Event"; - subValue->retryPolicy = "TerminateAfterRetries"; } else { - // TODO: Need to read this from query params. - subValue->eventFormatType = "Event"; - subValue->retryPolicy = "TerminateAfterRetries"; + // Reading from query params. + bool status = readSSEQueryParams( + filters, subValue->eventFormatType, subValue->registryMsgIds, + subValue->registryPrefixes, subValue->metricReportDefinitions); + + if (!status) + { + messages::invalidObject(res, filters); + return; + } + + if (!subValue->eventFormatType.empty()) + { + if (std::find(supportedEvtFormatTypes.begin(), + supportedEvtFormatTypes.end(), + subValue->eventFormatType) == + supportedEvtFormatTypes.end()) + { + messages::propertyValueNotInList( + res, subValue->eventFormatType, "EventFormatType"); + return; + } + } + else + { + // If nothing specified, using default "Event" + subValue->eventFormatType.assign({"Event"}); + } + + if (!subValue->registryPrefixes.empty()) + { + for (const std::string& it : subValue->registryPrefixes) + { + if (std::find(supportedRegPrefixes.begin(), + supportedRegPrefixes.end(), + it) == supportedRegPrefixes.end()) + { + messages::propertyValueNotInList(res, it, + "RegistryPrefixes"); + return; + } + } + } } std::string id = |