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