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