blob: f61d553c2f66357f4b4622a91be86a772de116ae [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
AppaRao Puli5e44e3d2021-03-16 15:37:24 +00003#pragma once
4
Ed Tanousf80a87f2024-06-16 12:10:33 -07005#include "filter_expr_executor.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -07006#include "privileges.hpp"
7#include "registries/privilege_registry.hpp"
8
AppaRao Puli5e44e3d2021-03-16 15:37:24 +00009#include <app.hpp>
10#include <event_service_manager.hpp>
11
Ed Tanous5b904292024-04-16 11:10:17 -070012#include <memory>
13#include <string>
14
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000015namespace redfish
16{
17
Ed Tanousf80a87f2024-06-16 12:10:33 -070018inline void createSubscription(crow::sse_socket::Connection& conn,
19 const crow::Request& req)
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000020{
21 EventServiceManager& manager =
22 EventServiceManager::getInstance(&conn.getIoContext());
23 if ((manager.getNumberOfSubscriptions() >= maxNoOfSubscriptions) ||
24 manager.getNumberOfSSESubscriptions() >= maxNoOfSSESubscriptions)
25 {
Ed Tanous62598e32023-07-17 17:06:25 -070026 BMCWEB_LOG_WARNING("Max SSE subscriptions reached");
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000027 conn.close("Max SSE subscriptions reached");
28 return;
29 }
Ed Tanousf80a87f2024-06-16 12:10:33 -070030
31 std::optional<filter_ast::LogicalAnd> filter;
32
33 boost::urls::params_base::iterator filterIt =
34 req.url().params().find("$filter");
35
36 if (filterIt != req.url().params().end())
37 {
38 std::string_view filterValue = (*filterIt).value;
39 filter = parseFilter(filterValue);
40 if (!filter)
41 {
42 conn.close(std::format("Bad $filter param: {}", filterValue));
43 return;
44 }
45 }
46
47 std::string lastEventId(req.getHeaderValue("Last-Event-Id"));
48
Ed Tanous4b712a22023-08-02 12:56:52 -070049 std::shared_ptr<Subscription> subValue =
50 std::make_shared<Subscription>(conn);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000051
Myung Bae5fe4ef32024-10-19 09:56:02 -040052 if (subValue->userSub == nullptr)
53 {
54 BMCWEB_LOG_ERROR("Subscription data is null");
55 conn.close("Internal Error");
56 return;
57 }
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000058
Myung Bae5fe4ef32024-10-19 09:56:02 -040059 // GET on this URI means, Its SSE subscriptionType.
60 subValue->userSub->subscriptionType = redfish::subscriptionTypeSSE;
61
62 subValue->userSub->protocol = "Redfish";
63 subValue->userSub->retryPolicy = "TerminateAfterRetries";
64 subValue->userSub->eventFormatType = "Event";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000065
Ed Tanousf80a87f2024-06-16 12:10:33 -070066 std::string id = manager.addSSESubscription(subValue, lastEventId);
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000067 if (id.empty())
68 {
69 conn.close("Internal Error");
70 }
71}
72
73inline void deleteSubscription(crow::sse_socket::Connection& conn)
74{
75 redfish::EventServiceManager::getInstance(&conn.getIoContext())
76 .deleteSseSubscription(conn);
77}
78
79inline void requestRoutesEventServiceSse(App& app)
80{
81 // Note, this endpoint is given the same privilege level as creating a
82 // subscription, because functionally, that's the operation being done
83 BMCWEB_ROUTE(app, "/redfish/v1/EventService/SSE")
84 .privileges(redfish::privileges::postEventDestinationCollection)
85 .serverSentEvent()
86 .onopen(createSubscription)
87 .onclose(deleteSubscription);
88}
89} // namespace redfish