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