xref: /openbmc/bmcweb/features/redfish/include/event_service_manager.hpp (revision 2a5689a752d31a4a5758d3827c7ca6302bc0acc7)
1b52664e2SAppaRao Puli /*
2b52664e2SAppaRao Puli // Copyright (c) 2020 Intel Corporation
3b52664e2SAppaRao Puli //
4b52664e2SAppaRao Puli // Licensed under the Apache License, Version 2.0 (the "License");
5b52664e2SAppaRao Puli // you may not use this file except in compliance with the License.
6b52664e2SAppaRao Puli // You may obtain a copy of the License at
7b52664e2SAppaRao Puli //
8b52664e2SAppaRao Puli //      http://www.apache.org/licenses/LICENSE-2.0
9b52664e2SAppaRao Puli //
10b52664e2SAppaRao Puli // Unless required by applicable law or agreed to in writing, software
11b52664e2SAppaRao Puli // distributed under the License is distributed on an "AS IS" BASIS,
12b52664e2SAppaRao Puli // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b52664e2SAppaRao Puli // See the License for the specific language governing permissions and
14b52664e2SAppaRao Puli // limitations under the License.
15b52664e2SAppaRao Puli */
16b52664e2SAppaRao Puli #pragma once
17b52664e2SAppaRao Puli #include "node.hpp"
18b52664e2SAppaRao Puli 
19b52664e2SAppaRao Puli #include <boost/container/flat_map.hpp>
20b52664e2SAppaRao Puli #include <cstdlib>
21b52664e2SAppaRao Puli #include <ctime>
22b52664e2SAppaRao Puli #include <error_messages.hpp>
23b52664e2SAppaRao Puli #include <http_client.hpp>
24b52664e2SAppaRao Puli #include <memory>
25b52664e2SAppaRao Puli #include <utils/json_utils.hpp>
26b52664e2SAppaRao Puli #include <variant>
27b52664e2SAppaRao Puli 
28b52664e2SAppaRao Puli namespace redfish
29b52664e2SAppaRao Puli {
30b52664e2SAppaRao Puli class Subscription
31b52664e2SAppaRao Puli {
32b52664e2SAppaRao Puli   public:
33b52664e2SAppaRao Puli     std::string id;
34b52664e2SAppaRao Puli     std::string destinationUrl;
35b52664e2SAppaRao Puli     std::string protocol;
36b52664e2SAppaRao Puli     std::string retryPolicy;
37b52664e2SAppaRao Puli     std::string customText;
38b52664e2SAppaRao Puli     std::string eventFormatType;
39b52664e2SAppaRao Puli     std::string subscriptionType;
40b52664e2SAppaRao Puli     std::vector<std::string> registryMsgIds;
41b52664e2SAppaRao Puli     std::vector<std::string> registryPrefixes;
42b52664e2SAppaRao Puli     std::vector<nlohmann::json> httpHeaders; // key-value pair
43b52664e2SAppaRao Puli 
44b52664e2SAppaRao Puli     Subscription(const Subscription&) = delete;
45b52664e2SAppaRao Puli     Subscription& operator=(const Subscription&) = delete;
46b52664e2SAppaRao Puli     Subscription(Subscription&&) = delete;
47b52664e2SAppaRao Puli     Subscription& operator=(Subscription&&) = delete;
48b52664e2SAppaRao Puli 
49b52664e2SAppaRao Puli     Subscription(const std::string& inHost, const std::string& inPort,
50b52664e2SAppaRao Puli                  const std::string& inPath, const std::string& inUriProto) :
51b52664e2SAppaRao Puli         host(inHost),
52b52664e2SAppaRao Puli         port(inPort), path(inPath), uriProto(inUriProto)
53b52664e2SAppaRao Puli     {
54b52664e2SAppaRao Puli         conn = std::make_shared<crow::HttpClient>(
55*2a5689a7SAppaRao Puli             crow::connections::systemBus->get_io_context(), host, port, path);
56b52664e2SAppaRao Puli     }
57b52664e2SAppaRao Puli     ~Subscription()
58b52664e2SAppaRao Puli     {
59b52664e2SAppaRao Puli     }
60b52664e2SAppaRao Puli 
61b52664e2SAppaRao Puli     void sendEvent(const std::string& msg)
62b52664e2SAppaRao Puli     {
63b52664e2SAppaRao Puli         std::vector<std::pair<std::string, std::string>> reqHeaders;
64b52664e2SAppaRao Puli         for (const auto& header : httpHeaders)
65b52664e2SAppaRao Puli         {
66b52664e2SAppaRao Puli             for (const auto& item : header.items())
67b52664e2SAppaRao Puli             {
68b52664e2SAppaRao Puli                 std::string key = item.key();
69b52664e2SAppaRao Puli                 std::string val = item.value();
70b52664e2SAppaRao Puli                 reqHeaders.emplace_back(std::pair(key, val));
71b52664e2SAppaRao Puli             }
72b52664e2SAppaRao Puli         }
73b52664e2SAppaRao Puli         conn->setHeaders(reqHeaders);
74*2a5689a7SAppaRao Puli         conn->sendData(msg);
75b52664e2SAppaRao Puli     }
76b52664e2SAppaRao Puli 
77b52664e2SAppaRao Puli   private:
78b52664e2SAppaRao Puli     std::string host;
79b52664e2SAppaRao Puli     std::string port;
80b52664e2SAppaRao Puli     std::string path;
81b52664e2SAppaRao Puli     std::string uriProto;
82b52664e2SAppaRao Puli     std::shared_ptr<crow::HttpClient> conn;
83b52664e2SAppaRao Puli };
84b52664e2SAppaRao Puli 
85b52664e2SAppaRao Puli class EventServiceManager
86b52664e2SAppaRao Puli {
87b52664e2SAppaRao Puli   private:
88b52664e2SAppaRao Puli     EventServiceManager(const EventServiceManager&) = delete;
89b52664e2SAppaRao Puli     EventServiceManager& operator=(const EventServiceManager&) = delete;
90b52664e2SAppaRao Puli     EventServiceManager(EventServiceManager&&) = delete;
91b52664e2SAppaRao Puli     EventServiceManager& operator=(EventServiceManager&&) = delete;
92b52664e2SAppaRao Puli 
93b52664e2SAppaRao Puli     EventServiceManager()
94b52664e2SAppaRao Puli     {
95b52664e2SAppaRao Puli         // TODO: Read the persistent data from store and populate.
96b52664e2SAppaRao Puli         // Populating with default.
97b52664e2SAppaRao Puli         enabled = true;
98b52664e2SAppaRao Puli         retryAttempts = 3;
99b52664e2SAppaRao Puli         retryTimeoutInterval = 30; // seconds
100b52664e2SAppaRao Puli     }
101b52664e2SAppaRao Puli 
102b52664e2SAppaRao Puli     boost::container::flat_map<std::string, std::shared_ptr<Subscription>>
103b52664e2SAppaRao Puli         subscriptionsMap;
104b52664e2SAppaRao Puli 
105b52664e2SAppaRao Puli   public:
106b52664e2SAppaRao Puli     bool enabled;
107b52664e2SAppaRao Puli     uint32_t retryAttempts;
108b52664e2SAppaRao Puli     uint32_t retryTimeoutInterval;
109b52664e2SAppaRao Puli 
110b52664e2SAppaRao Puli     static EventServiceManager& getInstance()
111b52664e2SAppaRao Puli     {
112b52664e2SAppaRao Puli         static EventServiceManager handler;
113b52664e2SAppaRao Puli         return handler;
114b52664e2SAppaRao Puli     }
115b52664e2SAppaRao Puli 
116b52664e2SAppaRao Puli     void updateSubscriptionData()
117b52664e2SAppaRao Puli     {
118b52664e2SAppaRao Puli         // Persist the config and subscription data.
119b52664e2SAppaRao Puli         // TODO: subscriptionsMap & configData need to be
120b52664e2SAppaRao Puli         // written to Persist store.
121b52664e2SAppaRao Puli         return;
122b52664e2SAppaRao Puli     }
123b52664e2SAppaRao Puli 
124b52664e2SAppaRao Puli     std::shared_ptr<Subscription> getSubscription(const std::string& id)
125b52664e2SAppaRao Puli     {
126b52664e2SAppaRao Puli         auto obj = subscriptionsMap.find(id);
127b52664e2SAppaRao Puli         if (obj == subscriptionsMap.end())
128b52664e2SAppaRao Puli         {
129b52664e2SAppaRao Puli             BMCWEB_LOG_ERROR << "No subscription exist with ID:" << id;
130b52664e2SAppaRao Puli             return nullptr;
131b52664e2SAppaRao Puli         }
132b52664e2SAppaRao Puli         std::shared_ptr<Subscription> subValue = obj->second;
133b52664e2SAppaRao Puli         return subValue;
134b52664e2SAppaRao Puli     }
135b52664e2SAppaRao Puli 
136b52664e2SAppaRao Puli     std::string addSubscription(const std::shared_ptr<Subscription> subValue)
137b52664e2SAppaRao Puli     {
138b52664e2SAppaRao Puli         std::srand(static_cast<uint32_t>(std::time(0)));
139b52664e2SAppaRao Puli         std::string id;
140b52664e2SAppaRao Puli 
141b52664e2SAppaRao Puli         int retry = 3;
142b52664e2SAppaRao Puli         while (retry)
143b52664e2SAppaRao Puli         {
144b52664e2SAppaRao Puli             id = std::to_string(std::rand());
145b52664e2SAppaRao Puli             auto inserted = subscriptionsMap.insert(std::pair(id, subValue));
146b52664e2SAppaRao Puli             if (inserted.second)
147b52664e2SAppaRao Puli             {
148b52664e2SAppaRao Puli                 break;
149b52664e2SAppaRao Puli             }
150b52664e2SAppaRao Puli             --retry;
151b52664e2SAppaRao Puli         };
152b52664e2SAppaRao Puli 
153b52664e2SAppaRao Puli         if (retry <= 0)
154b52664e2SAppaRao Puli         {
155b52664e2SAppaRao Puli             BMCWEB_LOG_ERROR << "Failed to generate random number";
156b52664e2SAppaRao Puli             return std::string("");
157b52664e2SAppaRao Puli         }
158b52664e2SAppaRao Puli 
159b52664e2SAppaRao Puli         updateSubscriptionData();
160b52664e2SAppaRao Puli         return id;
161b52664e2SAppaRao Puli     }
162b52664e2SAppaRao Puli 
163b52664e2SAppaRao Puli     bool isSubscriptionExist(const std::string& id)
164b52664e2SAppaRao Puli     {
165b52664e2SAppaRao Puli         auto obj = subscriptionsMap.find(id);
166b52664e2SAppaRao Puli         if (obj == subscriptionsMap.end())
167b52664e2SAppaRao Puli         {
168b52664e2SAppaRao Puli             return false;
169b52664e2SAppaRao Puli         }
170b52664e2SAppaRao Puli         return true;
171b52664e2SAppaRao Puli     }
172b52664e2SAppaRao Puli 
173b52664e2SAppaRao Puli     void deleteSubscription(const std::string& id)
174b52664e2SAppaRao Puli     {
175b52664e2SAppaRao Puli         auto obj = subscriptionsMap.find(id);
176b52664e2SAppaRao Puli         if (obj != subscriptionsMap.end())
177b52664e2SAppaRao Puli         {
178b52664e2SAppaRao Puli             subscriptionsMap.erase(obj);
179b52664e2SAppaRao Puli             updateSubscriptionData();
180b52664e2SAppaRao Puli         }
181b52664e2SAppaRao Puli     }
182b52664e2SAppaRao Puli 
183b52664e2SAppaRao Puli     size_t getNumberOfSubscriptions()
184b52664e2SAppaRao Puli     {
185b52664e2SAppaRao Puli         return subscriptionsMap.size();
186b52664e2SAppaRao Puli     }
187b52664e2SAppaRao Puli 
188b52664e2SAppaRao Puli     std::vector<std::string> getAllIDs()
189b52664e2SAppaRao Puli     {
190b52664e2SAppaRao Puli         std::vector<std::string> idList;
191b52664e2SAppaRao Puli         for (const auto& it : subscriptionsMap)
192b52664e2SAppaRao Puli         {
193b52664e2SAppaRao Puli             idList.emplace_back(it.first);
194b52664e2SAppaRao Puli         }
195b52664e2SAppaRao Puli         return idList;
196b52664e2SAppaRao Puli     }
197b52664e2SAppaRao Puli 
198b52664e2SAppaRao Puli     bool isDestinationExist(const std::string& destUrl)
199b52664e2SAppaRao Puli     {
200b52664e2SAppaRao Puli         for (const auto& it : subscriptionsMap)
201b52664e2SAppaRao Puli         {
202b52664e2SAppaRao Puli             std::shared_ptr<Subscription> entry = it.second;
203b52664e2SAppaRao Puli             if (entry->destinationUrl == destUrl)
204b52664e2SAppaRao Puli             {
205b52664e2SAppaRao Puli                 BMCWEB_LOG_ERROR << "Destination exist already" << destUrl;
206b52664e2SAppaRao Puli                 return true;
207b52664e2SAppaRao Puli             }
208b52664e2SAppaRao Puli         }
209b52664e2SAppaRao Puli         return false;
210b52664e2SAppaRao Puli     }
211b52664e2SAppaRao Puli };
212b52664e2SAppaRao Puli 
213b52664e2SAppaRao Puli } // namespace redfish
214