102c1e29fSAlexander Hansen /* 202c1e29fSAlexander Hansen Copyright (c) 2020 Intel Corporation 302c1e29fSAlexander Hansen 402c1e29fSAlexander Hansen Licensed under the Apache License, Version 2.0 (the "License"); 502c1e29fSAlexander Hansen you may not use this file except in compliance with the License. 602c1e29fSAlexander Hansen You may obtain a copy of the License at 702c1e29fSAlexander Hansen 802c1e29fSAlexander Hansen http://www.apache.org/licenses/LICENSE-2.0 902c1e29fSAlexander Hansen 1002c1e29fSAlexander Hansen Unless required by applicable law or agreed to in writing, software 1102c1e29fSAlexander Hansen distributed under the License is distributed on an "AS IS" BASIS, 1202c1e29fSAlexander Hansen WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1302c1e29fSAlexander Hansen See the License for the specific language governing permissions and 1402c1e29fSAlexander Hansen limitations under the License. 1502c1e29fSAlexander Hansen */ 1602c1e29fSAlexander Hansen #include "subscription.hpp" 1702c1e29fSAlexander Hansen 18fb546105SMyung Bae #include "dbus_singleton.hpp" 19b80ba2e4SAlexander Hansen #include "event_log.hpp" 2002c1e29fSAlexander Hansen #include "event_logs_object_type.hpp" 2102c1e29fSAlexander Hansen #include "event_matches_filter.hpp" 2202c1e29fSAlexander Hansen #include "event_service_store.hpp" 2302c1e29fSAlexander Hansen #include "filter_expr_executor.hpp" 24fb546105SMyung Bae #include "heartbeat_messages.hpp" 2502c1e29fSAlexander Hansen #include "http_client.hpp" 2602c1e29fSAlexander Hansen #include "http_response.hpp" 2702c1e29fSAlexander Hansen #include "logging.hpp" 2802c1e29fSAlexander Hansen #include "metric_report.hpp" 2902c1e29fSAlexander Hansen #include "server_sent_event.hpp" 3002c1e29fSAlexander Hansen #include "ssl_key_handler.hpp" 3102c1e29fSAlexander Hansen #include "utils/time_utils.hpp" 3202c1e29fSAlexander Hansen 33fb546105SMyung Bae #include <boost/asio/error.hpp> 3402c1e29fSAlexander Hansen #include <boost/asio/io_context.hpp> 35fb546105SMyung Bae #include <boost/asio/steady_timer.hpp> 36*4ac78946SEd Tanous #include <boost/beast/http/field.hpp> 37*4ac78946SEd Tanous #include <boost/beast/http/fields.hpp> 3802c1e29fSAlexander Hansen #include <boost/beast/http/verb.hpp> 3902c1e29fSAlexander Hansen #include <boost/system/errc.hpp> 4002c1e29fSAlexander Hansen #include <boost/url/format.hpp> 4102c1e29fSAlexander Hansen #include <boost/url/url_view_base.hpp> 4202c1e29fSAlexander Hansen #include <nlohmann/json.hpp> 4302c1e29fSAlexander Hansen 4402c1e29fSAlexander Hansen #include <algorithm> 45fb546105SMyung Bae #include <chrono> 4602c1e29fSAlexander Hansen #include <cstdint> 4702c1e29fSAlexander Hansen #include <cstdlib> 4802c1e29fSAlexander Hansen #include <ctime> 4902c1e29fSAlexander Hansen #include <format> 5002c1e29fSAlexander Hansen #include <functional> 5102c1e29fSAlexander Hansen #include <memory> 5202c1e29fSAlexander Hansen #include <span> 5302c1e29fSAlexander Hansen #include <string> 5402c1e29fSAlexander Hansen #include <string_view> 5502c1e29fSAlexander Hansen #include <utility> 5602c1e29fSAlexander Hansen #include <vector> 5702c1e29fSAlexander Hansen 5802c1e29fSAlexander Hansen namespace redfish 5902c1e29fSAlexander Hansen { 6002c1e29fSAlexander Hansen 6102c1e29fSAlexander Hansen Subscription::Subscription( 6202c1e29fSAlexander Hansen std::shared_ptr<persistent_data::UserSubscription> userSubIn, 6302c1e29fSAlexander Hansen const boost::urls::url_view_base& url, boost::asio::io_context& ioc) : 6402c1e29fSAlexander Hansen userSub{std::move(userSubIn)}, 65fb546105SMyung Bae policy(std::make_shared<crow::ConnectionPolicy>()), hbTimer(ioc) 6602c1e29fSAlexander Hansen { 6702c1e29fSAlexander Hansen userSub->destinationUrl = url; 6802c1e29fSAlexander Hansen client.emplace(ioc, policy); 6902c1e29fSAlexander Hansen // Subscription constructor 7002c1e29fSAlexander Hansen policy->invalidResp = retryRespHandler; 7102c1e29fSAlexander Hansen } 7202c1e29fSAlexander Hansen 7302c1e29fSAlexander Hansen Subscription::Subscription(crow::sse_socket::Connection& connIn) : 7402c1e29fSAlexander Hansen userSub{std::make_shared<persistent_data::UserSubscription>()}, 75fb546105SMyung Bae sseConn(&connIn), hbTimer(crow::connections::systemBus->get_io_context()) 7602c1e29fSAlexander Hansen {} 7702c1e29fSAlexander Hansen 7802c1e29fSAlexander Hansen // callback for subscription sendData 7902c1e29fSAlexander Hansen void Subscription::resHandler(const std::shared_ptr<Subscription>& /*unused*/, 8002c1e29fSAlexander Hansen const crow::Response& res) 8102c1e29fSAlexander Hansen { 8202c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("Response handled with return code: {}", res.resultInt()); 8302c1e29fSAlexander Hansen 8402c1e29fSAlexander Hansen if (!client) 8502c1e29fSAlexander Hansen { 8602c1e29fSAlexander Hansen BMCWEB_LOG_ERROR( 8702c1e29fSAlexander Hansen "Http client wasn't filled but http client callback was called."); 8802c1e29fSAlexander Hansen return; 8902c1e29fSAlexander Hansen } 9002c1e29fSAlexander Hansen 9102c1e29fSAlexander Hansen if (userSub->retryPolicy != "TerminateAfterRetries") 9202c1e29fSAlexander Hansen { 9302c1e29fSAlexander Hansen return; 9402c1e29fSAlexander Hansen } 9502c1e29fSAlexander Hansen if (client->isTerminated()) 9602c1e29fSAlexander Hansen { 97fb546105SMyung Bae hbTimer.cancel(); 9802c1e29fSAlexander Hansen if (deleter) 9902c1e29fSAlexander Hansen { 10002c1e29fSAlexander Hansen BMCWEB_LOG_INFO("Subscription {} is deleted after MaxRetryAttempts", 10102c1e29fSAlexander Hansen userSub->id); 10202c1e29fSAlexander Hansen deleter(); 10302c1e29fSAlexander Hansen } 10402c1e29fSAlexander Hansen } 10502c1e29fSAlexander Hansen } 10602c1e29fSAlexander Hansen 107fb546105SMyung Bae void Subscription::sendHeartbeatEvent() 108fb546105SMyung Bae { 109fb546105SMyung Bae // send the heartbeat message 110fb546105SMyung Bae nlohmann::json eventMessage = messages::redfishServiceFunctional(); 111fb546105SMyung Bae 112fb546105SMyung Bae std::string heartEventId = std::to_string(eventSeqNum); 113fb546105SMyung Bae eventMessage["EventId"] = heartEventId; 114fb546105SMyung Bae eventMessage["EventTimestamp"] = time_utils::getDateTimeOffsetNow().first; 115fb546105SMyung Bae eventMessage["OriginOfCondition"] = 116fb546105SMyung Bae std::format("/redfish/v1/EventService/Subscriptions/{}", userSub->id); 117fb546105SMyung Bae eventMessage["MemberId"] = "0"; 118fb546105SMyung Bae 119fb546105SMyung Bae nlohmann::json::array_t eventRecord; 120fb546105SMyung Bae eventRecord.emplace_back(std::move(eventMessage)); 121fb546105SMyung Bae 122fb546105SMyung Bae nlohmann::json msgJson; 123fb546105SMyung Bae msgJson["@odata.type"] = "#Event.v1_4_0.Event"; 124fb546105SMyung Bae msgJson["Name"] = "Heartbeat"; 125fb546105SMyung Bae msgJson["Id"] = heartEventId; 126fb546105SMyung Bae msgJson["Events"] = std::move(eventRecord); 127fb546105SMyung Bae 128fb546105SMyung Bae std::string strMsg = 129fb546105SMyung Bae msgJson.dump(2, ' ', true, nlohmann::json::error_handler_t::replace); 130fb546105SMyung Bae sendEventToSubscriber(std::move(strMsg)); 131fb546105SMyung Bae eventSeqNum++; 132fb546105SMyung Bae } 133fb546105SMyung Bae 134fb546105SMyung Bae void Subscription::scheduleNextHeartbeatEvent() 135fb546105SMyung Bae { 136fb546105SMyung Bae hbTimer.expires_after(std::chrono::minutes(userSub->hbIntervalMinutes)); 137fb546105SMyung Bae hbTimer.async_wait( 138fb546105SMyung Bae std::bind_front(&Subscription::onHbTimeout, this, weak_from_this())); 139fb546105SMyung Bae } 140fb546105SMyung Bae 141fb546105SMyung Bae void Subscription::heartbeatParametersChanged() 142fb546105SMyung Bae { 143fb546105SMyung Bae hbTimer.cancel(); 144fb546105SMyung Bae 145fb546105SMyung Bae if (userSub->sendHeartbeat) 146fb546105SMyung Bae { 147fb546105SMyung Bae scheduleNextHeartbeatEvent(); 148fb546105SMyung Bae } 149fb546105SMyung Bae } 150fb546105SMyung Bae 151fb546105SMyung Bae void Subscription::onHbTimeout(const std::weak_ptr<Subscription>& weakSelf, 152fb546105SMyung Bae const boost::system::error_code& ec) 153fb546105SMyung Bae { 154fb546105SMyung Bae if (ec == boost::asio::error::operation_aborted) 155fb546105SMyung Bae { 156fb546105SMyung Bae BMCWEB_LOG_DEBUG("heartbeat timer async_wait is aborted"); 157fb546105SMyung Bae return; 158fb546105SMyung Bae } 159fb546105SMyung Bae if (ec == boost::system::errc::operation_canceled) 160fb546105SMyung Bae { 161fb546105SMyung Bae BMCWEB_LOG_DEBUG("heartbeat timer async_wait canceled"); 162fb546105SMyung Bae return; 163fb546105SMyung Bae } 164fb546105SMyung Bae if (ec) 165fb546105SMyung Bae { 166fb546105SMyung Bae BMCWEB_LOG_CRITICAL("heartbeat timer async_wait failed: {}", ec); 167fb546105SMyung Bae return; 168fb546105SMyung Bae } 169fb546105SMyung Bae 170fb546105SMyung Bae std::shared_ptr<Subscription> self = weakSelf.lock(); 171fb546105SMyung Bae if (!self) 172fb546105SMyung Bae { 173fb546105SMyung Bae BMCWEB_LOG_CRITICAL("onHbTimeout failed on Subscription"); 174fb546105SMyung Bae return; 175fb546105SMyung Bae } 176fb546105SMyung Bae 177fb546105SMyung Bae // Timer expired. 178fb546105SMyung Bae sendHeartbeatEvent(); 179fb546105SMyung Bae 180fb546105SMyung Bae // reschedule heartbeat timer 181fb546105SMyung Bae scheduleNextHeartbeatEvent(); 182fb546105SMyung Bae } 183fb546105SMyung Bae 18402c1e29fSAlexander Hansen bool Subscription::sendEventToSubscriber(std::string&& msg) 18502c1e29fSAlexander Hansen { 18602c1e29fSAlexander Hansen persistent_data::EventServiceConfig eventServiceConfig = 18702c1e29fSAlexander Hansen persistent_data::EventServiceStore::getInstance() 18802c1e29fSAlexander Hansen .getEventServiceConfig(); 18902c1e29fSAlexander Hansen if (!eventServiceConfig.enabled) 19002c1e29fSAlexander Hansen { 19102c1e29fSAlexander Hansen return false; 19202c1e29fSAlexander Hansen } 19302c1e29fSAlexander Hansen 19402c1e29fSAlexander Hansen if (client) 19502c1e29fSAlexander Hansen { 196*4ac78946SEd Tanous boost::beast::http::fields httpHeadersCopy(userSub->httpHeaders); 197*4ac78946SEd Tanous httpHeadersCopy.set(boost::beast::http::field::content_type, 198*4ac78946SEd Tanous "application/json"); 19902c1e29fSAlexander Hansen client->sendDataWithCallback( 20002c1e29fSAlexander Hansen std::move(msg), userSub->destinationUrl, 20102c1e29fSAlexander Hansen static_cast<ensuressl::VerifyCertificate>( 20202c1e29fSAlexander Hansen userSub->verifyCertificate), 203*4ac78946SEd Tanous httpHeadersCopy, boost::beast::http::verb::post, 20402c1e29fSAlexander Hansen std::bind_front(&Subscription::resHandler, this, 20502c1e29fSAlexander Hansen shared_from_this())); 20602c1e29fSAlexander Hansen return true; 20702c1e29fSAlexander Hansen } 20802c1e29fSAlexander Hansen 20902c1e29fSAlexander Hansen if (sseConn != nullptr) 21002c1e29fSAlexander Hansen { 21102c1e29fSAlexander Hansen eventSeqNum++; 21202c1e29fSAlexander Hansen sseConn->sendSseEvent(std::to_string(eventSeqNum), msg); 21302c1e29fSAlexander Hansen } 21402c1e29fSAlexander Hansen return true; 21502c1e29fSAlexander Hansen } 21602c1e29fSAlexander Hansen 21781ee0e74SChandramohan Harkude bool Subscription::sendTestEventLog(TestEvent& testEvent) 21802c1e29fSAlexander Hansen { 21902c1e29fSAlexander Hansen nlohmann::json::array_t logEntryArray; 22002c1e29fSAlexander Hansen nlohmann::json& logEntryJson = logEntryArray.emplace_back(); 22102c1e29fSAlexander Hansen 22281ee0e74SChandramohan Harkude if (testEvent.eventGroupId) 22381ee0e74SChandramohan Harkude { 22481ee0e74SChandramohan Harkude logEntryJson["EventGroupId"] = *testEvent.eventGroupId; 22581ee0e74SChandramohan Harkude } 22681ee0e74SChandramohan Harkude 22781ee0e74SChandramohan Harkude if (testEvent.eventId) 22881ee0e74SChandramohan Harkude { 22981ee0e74SChandramohan Harkude logEntryJson["EventId"] = *testEvent.eventId; 23081ee0e74SChandramohan Harkude } 23181ee0e74SChandramohan Harkude 23281ee0e74SChandramohan Harkude if (testEvent.eventTimestamp) 23381ee0e74SChandramohan Harkude { 23481ee0e74SChandramohan Harkude logEntryJson["EventTimestamp"] = *testEvent.eventTimestamp; 23581ee0e74SChandramohan Harkude } 23681ee0e74SChandramohan Harkude 23781ee0e74SChandramohan Harkude if (testEvent.originOfCondition) 23881ee0e74SChandramohan Harkude { 23981ee0e74SChandramohan Harkude logEntryJson["OriginOfCondition"]["@odata.id"] = 24081ee0e74SChandramohan Harkude *testEvent.originOfCondition; 24181ee0e74SChandramohan Harkude } 24281ee0e74SChandramohan Harkude if (testEvent.severity) 24381ee0e74SChandramohan Harkude { 24481ee0e74SChandramohan Harkude logEntryJson["Severity"] = *testEvent.severity; 24581ee0e74SChandramohan Harkude } 24681ee0e74SChandramohan Harkude 24781ee0e74SChandramohan Harkude if (testEvent.message) 24881ee0e74SChandramohan Harkude { 24981ee0e74SChandramohan Harkude logEntryJson["Message"] = *testEvent.message; 25081ee0e74SChandramohan Harkude } 25181ee0e74SChandramohan Harkude 25281ee0e74SChandramohan Harkude if (testEvent.resolution) 25381ee0e74SChandramohan Harkude { 25481ee0e74SChandramohan Harkude logEntryJson["Resolution"] = *testEvent.resolution; 25581ee0e74SChandramohan Harkude } 25681ee0e74SChandramohan Harkude 25781ee0e74SChandramohan Harkude if (testEvent.messageId) 25881ee0e74SChandramohan Harkude { 25981ee0e74SChandramohan Harkude logEntryJson["MessageId"] = *testEvent.messageId; 26081ee0e74SChandramohan Harkude } 26181ee0e74SChandramohan Harkude 26281ee0e74SChandramohan Harkude if (testEvent.messageArgs) 26381ee0e74SChandramohan Harkude { 26481ee0e74SChandramohan Harkude logEntryJson["MessageArgs"] = *testEvent.messageArgs; 26581ee0e74SChandramohan Harkude } 26602c1e29fSAlexander Hansen // MemberId is 0 : since we are sending one event record. 26702c1e29fSAlexander Hansen logEntryJson["MemberId"] = "0"; 26802c1e29fSAlexander Hansen 26902c1e29fSAlexander Hansen nlohmann::json msg; 27002c1e29fSAlexander Hansen msg["@odata.type"] = "#Event.v1_4_0.Event"; 27102c1e29fSAlexander Hansen msg["Id"] = std::to_string(eventSeqNum); 27202c1e29fSAlexander Hansen msg["Name"] = "Event Log"; 27302c1e29fSAlexander Hansen msg["Events"] = logEntryArray; 27402c1e29fSAlexander Hansen 27502c1e29fSAlexander Hansen std::string strMsg = 27602c1e29fSAlexander Hansen msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace); 27702c1e29fSAlexander Hansen return sendEventToSubscriber(std::move(strMsg)); 27802c1e29fSAlexander Hansen } 27902c1e29fSAlexander Hansen 28002c1e29fSAlexander Hansen void Subscription::filterAndSendEventLogs( 28102c1e29fSAlexander Hansen const std::vector<EventLogObjectsType>& eventRecords) 28202c1e29fSAlexander Hansen { 28302c1e29fSAlexander Hansen nlohmann::json::array_t logEntryArray; 28402c1e29fSAlexander Hansen for (const EventLogObjectsType& logEntry : eventRecords) 28502c1e29fSAlexander Hansen { 28602c1e29fSAlexander Hansen std::vector<std::string_view> messageArgsView( 28702c1e29fSAlexander Hansen logEntry.messageArgs.begin(), logEntry.messageArgs.end()); 28802c1e29fSAlexander Hansen 28902c1e29fSAlexander Hansen nlohmann::json::object_t bmcLogEntry; 29002c1e29fSAlexander Hansen if (event_log::formatEventLogEntry( 29102c1e29fSAlexander Hansen logEntry.id, logEntry.messageId, messageArgsView, 29202c1e29fSAlexander Hansen logEntry.timestamp, userSub->customText, bmcLogEntry) != 0) 29302c1e29fSAlexander Hansen { 29402c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("Read eventLog entry failed"); 29502c1e29fSAlexander Hansen continue; 29602c1e29fSAlexander Hansen } 29702c1e29fSAlexander Hansen 29802c1e29fSAlexander Hansen if (!eventMatchesFilter(*userSub, bmcLogEntry, "")) 29902c1e29fSAlexander Hansen { 30002c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("Event {} did not match the filter", 30102c1e29fSAlexander Hansen nlohmann::json(bmcLogEntry).dump()); 30202c1e29fSAlexander Hansen continue; 30302c1e29fSAlexander Hansen } 30402c1e29fSAlexander Hansen 30502c1e29fSAlexander Hansen if (filter) 30602c1e29fSAlexander Hansen { 30702c1e29fSAlexander Hansen if (!memberMatches(bmcLogEntry, *filter)) 30802c1e29fSAlexander Hansen { 30902c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("Filter didn't match"); 31002c1e29fSAlexander Hansen continue; 31102c1e29fSAlexander Hansen } 31202c1e29fSAlexander Hansen } 31302c1e29fSAlexander Hansen 31402c1e29fSAlexander Hansen logEntryArray.emplace_back(std::move(bmcLogEntry)); 31502c1e29fSAlexander Hansen } 31602c1e29fSAlexander Hansen 31702c1e29fSAlexander Hansen if (logEntryArray.empty()) 31802c1e29fSAlexander Hansen { 31902c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("No log entries available to be transferred."); 32002c1e29fSAlexander Hansen return; 32102c1e29fSAlexander Hansen } 32202c1e29fSAlexander Hansen 32302c1e29fSAlexander Hansen nlohmann::json msg; 32402c1e29fSAlexander Hansen msg["@odata.type"] = "#Event.v1_4_0.Event"; 32502c1e29fSAlexander Hansen msg["Id"] = std::to_string(eventSeqNum); 32602c1e29fSAlexander Hansen msg["Name"] = "Event Log"; 32702c1e29fSAlexander Hansen msg["Events"] = std::move(logEntryArray); 32802c1e29fSAlexander Hansen std::string strMsg = 32902c1e29fSAlexander Hansen msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace); 33002c1e29fSAlexander Hansen sendEventToSubscriber(std::move(strMsg)); 33102c1e29fSAlexander Hansen eventSeqNum++; 33202c1e29fSAlexander Hansen } 33302c1e29fSAlexander Hansen 33402c1e29fSAlexander Hansen void Subscription::filterAndSendReports(const std::string& reportId, 33502c1e29fSAlexander Hansen const telemetry::TimestampReadings& var) 33602c1e29fSAlexander Hansen { 33702c1e29fSAlexander Hansen boost::urls::url mrdUri = boost::urls::format( 33802c1e29fSAlexander Hansen "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", reportId); 33902c1e29fSAlexander Hansen 34002c1e29fSAlexander Hansen // Empty list means no filter. Send everything. 34102c1e29fSAlexander Hansen if (!userSub->metricReportDefinitions.empty()) 34202c1e29fSAlexander Hansen { 34302c1e29fSAlexander Hansen if (std::ranges::find(userSub->metricReportDefinitions, 34402c1e29fSAlexander Hansen mrdUri.buffer()) == 34502c1e29fSAlexander Hansen userSub->metricReportDefinitions.end()) 34602c1e29fSAlexander Hansen { 34702c1e29fSAlexander Hansen return; 34802c1e29fSAlexander Hansen } 34902c1e29fSAlexander Hansen } 35002c1e29fSAlexander Hansen 35102c1e29fSAlexander Hansen nlohmann::json msg; 35202c1e29fSAlexander Hansen if (!telemetry::fillReport(msg, reportId, var)) 35302c1e29fSAlexander Hansen { 35402c1e29fSAlexander Hansen BMCWEB_LOG_ERROR("Failed to fill the MetricReport for DBus " 35502c1e29fSAlexander Hansen "Report with id {}", 35602c1e29fSAlexander Hansen reportId); 35702c1e29fSAlexander Hansen return; 35802c1e29fSAlexander Hansen } 35902c1e29fSAlexander Hansen 36002c1e29fSAlexander Hansen // Context is set by user during Event subscription and it must be 36102c1e29fSAlexander Hansen // set for MetricReport response. 36202c1e29fSAlexander Hansen if (!userSub->customText.empty()) 36302c1e29fSAlexander Hansen { 36402c1e29fSAlexander Hansen msg["Context"] = userSub->customText; 36502c1e29fSAlexander Hansen } 36602c1e29fSAlexander Hansen 36702c1e29fSAlexander Hansen std::string strMsg = 36802c1e29fSAlexander Hansen msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace); 36902c1e29fSAlexander Hansen sendEventToSubscriber(std::move(strMsg)); 37002c1e29fSAlexander Hansen } 37102c1e29fSAlexander Hansen 37202c1e29fSAlexander Hansen void Subscription::updateRetryConfig(uint32_t retryAttempts, 37302c1e29fSAlexander Hansen uint32_t retryTimeoutInterval) 37402c1e29fSAlexander Hansen { 37502c1e29fSAlexander Hansen if (policy == nullptr) 37602c1e29fSAlexander Hansen { 37702c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("Retry policy was nullptr, ignoring set"); 37802c1e29fSAlexander Hansen return; 37902c1e29fSAlexander Hansen } 38002c1e29fSAlexander Hansen policy->maxRetryAttempts = retryAttempts; 38102c1e29fSAlexander Hansen policy->retryIntervalSecs = std::chrono::seconds(retryTimeoutInterval); 38202c1e29fSAlexander Hansen } 38302c1e29fSAlexander Hansen 38402c1e29fSAlexander Hansen uint64_t Subscription::getEventSeqNum() const 38502c1e29fSAlexander Hansen { 38602c1e29fSAlexander Hansen return eventSeqNum; 38702c1e29fSAlexander Hansen } 38802c1e29fSAlexander Hansen 38902c1e29fSAlexander Hansen bool Subscription::matchSseId(const crow::sse_socket::Connection& thisConn) 39002c1e29fSAlexander Hansen { 39102c1e29fSAlexander Hansen return &thisConn == sseConn; 39202c1e29fSAlexander Hansen } 39302c1e29fSAlexander Hansen 39402c1e29fSAlexander Hansen // Check used to indicate what response codes are valid as part of our retry 39502c1e29fSAlexander Hansen // policy. 2XX is considered acceptable 39602c1e29fSAlexander Hansen boost::system::error_code Subscription::retryRespHandler(unsigned int respCode) 39702c1e29fSAlexander Hansen { 39802c1e29fSAlexander Hansen BMCWEB_LOG_DEBUG("Checking response code validity for SubscriptionEvent"); 39902c1e29fSAlexander Hansen if ((respCode < 200) || (respCode >= 300)) 40002c1e29fSAlexander Hansen { 40102c1e29fSAlexander Hansen return boost::system::errc::make_error_code( 40202c1e29fSAlexander Hansen boost::system::errc::result_out_of_range); 40302c1e29fSAlexander Hansen } 40402c1e29fSAlexander Hansen 40502c1e29fSAlexander Hansen // Return 0 if the response code is valid 40602c1e29fSAlexander Hansen return boost::system::errc::make_error_code(boost::system::errc::success); 40702c1e29fSAlexander Hansen } 40802c1e29fSAlexander Hansen 40902c1e29fSAlexander Hansen } // namespace redfish 410