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 createSubscription(crow::sse_socket::Connection & conn,const crow::Request & req)16inline 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 if (subValue->userSub == nullptr) 51 { 52 BMCWEB_LOG_ERROR("Subscription data is null"); 53 conn.close("Internal Error"); 54 return; 55 } 56 57 // GET on this URI means, Its SSE subscriptionType. 58 subValue->userSub->subscriptionType = redfish::subscriptionTypeSSE; 59 60 subValue->userSub->protocol = "Redfish"; 61 subValue->userSub->retryPolicy = "TerminateAfterRetries"; 62 subValue->userSub->eventFormatType = "Event"; 63 64 std::string id = manager.addSSESubscription(subValue, lastEventId); 65 if (id.empty()) 66 { 67 conn.close("Internal Error"); 68 } 69 } 70 deleteSubscription(crow::sse_socket::Connection & conn)71inline void deleteSubscription(crow::sse_socket::Connection& conn) 72 { 73 redfish::EventServiceManager::getInstance(&conn.getIoContext()) 74 .deleteSseSubscription(conn); 75 } 76 requestRoutesEventServiceSse(App & app)77inline void requestRoutesEventServiceSse(App& app) 78 { 79 // Note, this endpoint is given the same privilege level as creating a 80 // subscription, because functionally, that's the operation being done 81 BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE") 82 .privileges(redfish::privileges::postEventDestinationCollection) 83 .serverSentEvent() 84 .onopen(createSubscription) 85 .onclose(deleteSubscription); 86 } 87 } // namespace redfish 88