1 #pragma once 2 3 #include "filter_expr_executor.hpp" 4 #include "privileges.hpp" 5 #include "registries/privilege_registry.hpp" 6 7 #include <app.hpp> 8 #include <event_service_manager.hpp> 9 10 #include <memory> 11 #include <string> 12 13 namespace redfish 14 { 15 16 inline void createSubscription(crow::sse_socket::Connection& conn, 17 const crow::Request& req) 18 { 19 EventServiceManager& manager = 20 EventServiceManager::getInstance(&conn.getIoContext()); 21 if ((manager.getNumberOfSubscriptions() >= maxNoOfSubscriptions) || 22 manager.getNumberOfSSESubscriptions() >= maxNoOfSSESubscriptions) 23 { 24 BMCWEB_LOG_WARNING("Max SSE subscriptions reached"); 25 conn.close("Max SSE subscriptions reached"); 26 return; 27 } 28 29 std::optional<filter_ast::LogicalAnd> filter; 30 31 boost::urls::params_base::iterator filterIt = 32 req.url().params().find("$filter"); 33 34 if (filterIt != req.url().params().end()) 35 { 36 std::string_view filterValue = (*filterIt).value; 37 filter = parseFilter(filterValue); 38 if (!filter) 39 { 40 conn.close(std::format("Bad $filter param: {}", filterValue)); 41 return; 42 } 43 } 44 45 std::string lastEventId(req.getHeaderValue("Last-Event-Id")); 46 47 std::shared_ptr<Subscription> subValue = 48 std::make_shared<Subscription>(conn); 49 50 // GET on this URI means, Its SSE subscriptionType. 51 subValue->userSub.subscriptionType = redfish::subscriptionTypeSSE; 52 53 subValue->userSub.protocol = "Redfish"; 54 subValue->userSub.retryPolicy = "TerminateAfterRetries"; 55 subValue->userSub.eventFormatType = "Event"; 56 57 std::string id = manager.addSSESubscription(subValue, lastEventId); 58 if (id.empty()) 59 { 60 conn.close("Internal Error"); 61 } 62 } 63 64 inline void deleteSubscription(crow::sse_socket::Connection& conn) 65 { 66 redfish::EventServiceManager::getInstance(&conn.getIoContext()) 67 .deleteSseSubscription(conn); 68 } 69 70 inline void requestRoutesEventServiceSse(App& app) 71 { 72 // Note, this endpoint is given the same privilege level as creating a 73 // subscription, because functionally, that's the operation being done 74 BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE") 75 .privileges(redfish::privileges::postEventDestinationCollection) 76 .serverSentEvent() 77 .onopen(createSubscription) 78 .onclose(deleteSubscription); 79 } 80 } // namespace redfish 81