Line data Source code
1 : /* 2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef __CONNECTION_INFO_H__ 6 : #define __CONNECTION_INFO_H__ 7 : 8 : #include <map> 9 : #include <mutex> 10 : #include <vector> 11 : 12 : #include <boost/tuple/tuple.hpp> 13 : #include <boost/asio/ip/tcp.hpp> 14 : #include <boost/bind/bind.hpp> 15 : #include <boost/assign/list_of.hpp> 16 : #include <boost/scoped_ptr.hpp> 17 : 18 : #include <base/feature_flags.h> 19 : #include <base/sandesh/process_info_constants.h> 20 : #include <base/sandesh/process_info_types.h> 21 : #include <base/sandesh/cpuinfo_constants.h> 22 : #include <base/sandesh/cpuinfo_types.h> 23 : #include <base/sandesh/nodeinfo_constants.h> 24 : #include <base/sandesh/nodeinfo_types.h> 25 : 26 : using namespace boost::placeholders; 27 : 28 : class ConnectionInfoTest; 29 : 30 : namespace process { 31 : 32 : typedef boost::asio::ip::tcp::endpoint Endpoint; 33 : typedef boost::function<void (const std::vector<ConnectionInfo> &, 34 : ProcessState::type &, std::string &)> ProcessStateFn; 35 : 36 : typedef std::pair<std::string, std::string> ConnectionTypeName; 37 : void GetProcessStateCb(const std::vector<ConnectionInfo> &cinfos, 38 : ProcessState::type &state, std::string &message, 39 : const std::vector<ConnectionTypeName> &expected_connections); 40 : void GetConnectionInfoMessage(const std::vector<ConnectionInfo> &cinfos, 41 : const std::vector<ConnectionTypeName> &expected_connections, 42 : std::string &message); 43 : 44 : // ConnectionState 45 : class ConnectionState { 46 : public: 47 : static ConnectionState* GetInstance(); 48 : void Update(); 49 : void Update(ConnectionType::type ctype, const std::string &name, 50 : ConnectionStatus::type status, Endpoint server, 51 : std::string message); 52 : void Update(ConnectionType::type ctype, const std::string &name, 53 : ConnectionStatus::type status, const std::vector<Endpoint> &servers, 54 : std::string message); 55 : void Delete(ConnectionType::type ctype, const std::string &name); 56 : std::vector<ConnectionInfo> GetInfos() const; 57 : 58 : private: 59 : void UpdateInternal(ConnectionType::type ctype, 60 : const std::string &name, ConnectionStatus::type status, 61 : const std::vector<Endpoint> &servers, std::string message); 62 : 63 : friend class 64 : ConnectionStateManager; 65 : 66 : typedef boost::tuple<ConnectionType::type, std::string> ConnectionInfoKey; 67 : typedef std::map<ConnectionInfoKey, ConnectionInfo> ConnectionInfoMap; 68 : typedef boost::function<void (void)> SendUveCb; 69 : 70 : std::vector<ConnectionInfo> GetInfosUnlocked() const; 71 : // Singleton 72 : ConnectionState(SendUveCb send_uve_cb); 73 : static void CreateInstance(SendUveCb send_uve_cb); 74 : 75 : static boost::scoped_ptr<ConnectionState> instance_; 76 : mutable std::mutex mutex_; 77 : ConnectionInfoMap connection_map_; 78 : SendUveCb send_uve_cb_; 79 : }; 80 : 81 : // ConnectionStateManager 82 : class ConnectionStateManager { 83 : public: 84 94 : static ConnectionStateManager* GetInstance() { 85 94 : if (instance_ == NULL) { 86 46 : instance_.reset( 87 46 : new ConnectionStateManager()); 88 : // Create ConnectionState instance and bind the send UVE function 89 46 : assert(ConnectionState::instance_ == NULL); 90 46 : ConnectionState::CreateInstance(boost::bind( 91 : &ConnectionStateManager:: 92 : SendProcessStateUve, instance_.get(), false)); 93 46 : FlagUveManager::CreateInstance(FlagManager::GetInstance(), 94 : boost::bind(&ConnectionStateManager:: 95 : SendProcessStateUve, instance_.get(), false)); 96 : } 97 94 : return instance_.get(); 98 : } 99 : 100 46 : void Init(boost::asio::io_context &service, const std::string &hostname, 101 : const std::string &module, const std::string &instance_id, 102 : ProcessStateFn status_cb, std::string table) { 103 46 : data_.set_name(hostname); 104 46 : process_status_.set_module_id(module); 105 46 : process_status_.set_instance_id(instance_id); 106 46 : status_cb_ = status_cb; 107 46 : data_.table_ = table; 108 46 : } 109 : 110 46 : void Shutdown() { 111 46 : } 112 : 113 : private: 114 : friend class ConnectionState; 115 : friend class FlagUveManager; 116 : friend class ::ConnectionInfoTest; 117 : 118 : // Singleton 119 46 : ConnectionStateManager() : 120 46 : status_cb_(NULL) { 121 46 : } 122 : 123 3 : void SetProcessStateCb(ProcessStateFn status_cb) { 124 3 : status_cb_ = status_cb; 125 3 : } 126 : 127 : // Convert flag_infos to sandesh type 128 : std::vector<FlagInfo> GetFlagInfos(const FlagConfigVec &flag_infos); 129 : 130 433 : bool SendProcessStateUve(bool lock) { 131 433 : if (status_cb_.empty()) { 132 0 : return false; 133 : } 134 433 : std::scoped_lock uve_lock(uve_mutex_); 135 : // Update 136 : // Add connection_info 137 433 : process_status_.set_connection_infos(lock ? 138 : ConnectionState::GetInstance()->GetInfos() : 139 : ConnectionState::GetInstance()->GetInfosUnlocked()); 140 : // Add flag_info 141 433 : process_status_.set_flag_infos(GetFlagInfos( 142 866 : FlagUveManager::GetInstance()->GetFlagInfos(lock))); 143 : ProcessState::type pstate; 144 433 : std::string message; 145 433 : status_cb_(process_status_.get_connection_infos(), pstate, message); 146 866 : process_status_.set_state(g_process_info_constants. 147 433 : ProcessStateNames.find(pstate)->second); 148 433 : process_status_.set_description(message); 149 : // Send 150 : std::vector<ProcessStatus> vps = boost::assign::list_of 151 433 : (process_status_); 152 433 : data_.set_process_status(vps); 153 433 : NodeStatusUVE::Send(data_); 154 433 : return true; 155 433 : } 156 : 157 : static boost::scoped_ptr<ConnectionStateManager> instance_; 158 : 159 : ProcessStateFn status_cb_; 160 : mutable std::mutex uve_mutex_; 161 : ProcessStatus process_status_; 162 : NodeStatus data_; 163 : }; 164 : 165 : } // namespace process 166 : 167 : #endif // __CONNECTION_INFO_H__