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