OpenSDN source code
agent_uve_base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <base/cpuinfo.h>
6 #include <db/db.h>
7 #include <cmn/agent_cmn.h>
9 #include <oper/interface.h>
10 
11 #include "vr_genetlink.h"
12 #include "nl_util.h"
13 
14 #include <uve/agent_uve_base.h>
15 #include <uve/vn_uve_table_base.h>
16 #include <uve/stats_interval_types.h>
17 #include <init/agent_param.h>
18 #include <oper/mirror_table.h>
19 #include <oper/global_vrouter.h>
20 #include <oper/tag.h>
22 #include <cmn/agent_stats.h>
23 
24 using process::ConnectionInfo;
25 using process::ConnectionType;
26 using process::ProcessState;
27 using process::ConnectionStatus;
30 using process::g_process_info_constants;
31 
32 
33 const uint32_t AgentUveBase::kUveCountPerTimer;
34 
35 const uint32_t AgentUveBase::kDefaultInterval;
36 
38 
40 
41 
43 
44 AgentUveBase::AgentUveBase(Agent *agent, uint64_t intvl,
45  uint32_t default_intvl, uint32_t incremental_intvl)
46  : vn_uve_table_(NULL), vm_uve_table_(NULL), vrouter_uve_entry_(NULL),
47  prouter_uve_table_(new ProuterUveTable(agent, default_intvl)),
48  interface_uve_table_(NULL),
49  default_interval_(default_intvl),
50  incremental_interval_(incremental_intvl),
51  agent_(agent), bandwidth_intvl_(intvl),
52  vrouter_stats_collector_(new VrouterStatsCollector(
53  *(agent->event_manager()->io_service()),
54  this)) {
55  singleton_ = this;
56 }
57 
59 }
60 
62  const {
63  TagTable *table = agent_->tag_table();
64  TagList::const_iterator it = tl.begin();
65  while (it != tl.end()) {
66  uint32_t type = ((uint32_t)*it >> TagEntry::kTagTypeBitShift);
67  switch (type) {
69  info->application = table->TagName(*it);
70  break;
71  case TagTable::TIER:
72  info->tier = table->TagName(*it);
73  break;
74  case TagTable::SITE:
75  info->site = table->TagName(*it);
76  break;
78  info->deployment = table->TagName(*it);
79  break;
80  case TagTable::LABEL:
81  if (info->fill_type == UveTagData::SET) {
82  info->label_set.insert(table->TagName(*it));
83  break;
84  } else if (info->fill_type == UveTagData::VECTOR) {
85  info->label_vector.push_back(table->TagName(*it));
86  break;
87  }
88  if (!info->labels.empty()) {
89  info->labels += ";";
90  }
91  info->labels.append(table->TagName(*it));
92  break;
94  info->application = table->TagName(*it);
95  break;
96  default:
97  if (info->fill_type == UveTagData::SET) {
98  info->custom_tag_set.insert(table->TagName(*it));
99  break;
100  } else if (info->fill_type == UveTagData::VECTOR) {
101  info->custom_tag_vector.push_back(table->TagName(*it));
102  break;
103  }
104  if (!info->custom_tags.empty()) {
105  info->custom_tags += ";";
106  }
107  info->custom_tags.append(table->TagName(*it));
108  break;
109  }
110  ++it;
111  }
112 }
113 
114 /* Web-UI requires tag-id to returned as hex string. This should start with 0x
115  * and have exactly 8 digits/characters. Zero should be used for filling leading
116  * characters if the tag-id is not 8 digits wide. Web-UI uses this id to do
117  * lookup in API server */
118 string AgentUveBase::IntegerToHexString(uint32_t value) const {
119  std::stringstream ss;
120  ss << "0x" << std::setfill('0') <<
121  std::setw(8) << std::hex << (uint32_t)value;
122  return ss.str();
123 }
124 
126  const {
127  TagList::const_iterator it = tl.begin();
128  while (it != tl.end()) {
129  uint32_t type = ((uint32_t)*it >> TagEntry::kTagTypeBitShift);
130  switch (type) {
132  info->application = IntegerToHexString(*it);
133  break;
134  case TagTable::TIER:
135  info->tier = IntegerToHexString(*it);
136  break;
137  case TagTable::SITE:
138  info->site = IntegerToHexString(*it);
139  break;
141  info->deployment = IntegerToHexString(*it);
142  break;
143  case TagTable::LABEL:
144  if (info->fill_type == UveTagData::SET) {
145  info->label_set.insert(IntegerToHexString(*it));
146  break;
147  } else if (info->fill_type == UveTagData::VECTOR) {
148  info->label_vector.push_back(IntegerToHexString(*it));
149  break;
150  }
151  if (!info->labels.empty()) {
152  info->labels += ";";
153  }
154  info->labels.append(IntegerToHexString(*it));
155  break;
157  info->application = IntegerToHexString(*it);
158  break;
159  default:
160  if (info->fill_type == UveTagData::SET) {
161  info->custom_tag_set.insert(IntegerToHexString(*it));
162  break;
163  } else if (info->fill_type == UveTagData::VECTOR) {
164  info->custom_tag_vector.push_back(IntegerToHexString(*it));
165  break;
166  }
167  if (!info->custom_tags.empty()) {
168  info->custom_tags += ";";
169  }
170  info->custom_tags.append(IntegerToHexString(*it));
171  break;
172  }
173  ++it;
174  }
175 }
176 
177 void AgentUveBase::set_default_interval(uint32_t new_interval) {
178  if (new_interval == 0) {
180  } else {
181  default_interval_ = new_interval;
182  }
183 }
184 
185 void AgentUveBase::set_incremental_interval(uint32_t new_interval) {
186  if (new_interval == 0) {
188  } else {
189  incremental_interval_ = new_interval;
190  }
191 }
192 
194  vn_uve_table_.get()->Shutdown();
195  vm_uve_table_.get()->Shutdown();
196  vrouter_uve_entry_.get()->Shutdown();
197  prouter_uve_table_.get()->Shutdown();
198  interface_uve_table_.get()->Shutdown();
200  vrouter_stats_collector_->Shutdown();
201 }
202 
204  std::string module_id(agent_->module_name());
205  std::string instance_id(agent_->instance_id());
207  boost::asio::io_context &io = *evm->io_service();
208 
211  ConnectionStateManager::
212  GetInstance();
213  agent_->set_connection_state(ConnectionState::GetInstance());
215  module_id, instance_id,
217  this, _1, _2, _3), "ObjectVRouter");
218 }
219 
220 uint8_t AgentUveBase::ExpectedConnections(uint8_t &num_control_nodes,
221  uint8_t &num_dns_servers) {
222  uint8_t count = 0;
223  AgentParam *cfg = agent_->params();
224 
225  for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
226  if (!agent_->controller_ifmap_xmpp_server(i).empty()) {
227  num_control_nodes++;
228  count++;
229  }
230  if (agent_->services() && !agent_->dns_server(i).empty()) {
231  num_dns_servers++;
232  count++;
233  }
234  }
235  //Increment 1 for collector service
236  if (cfg->collector_server_list().size() != 0) {
237  count++;
238  }
239 
240  return count;
241 }
242 
243 void AgentUveBase::UpdateMessage(const ConnectionInfo &cinfo,
244  std::string &message) {
245  if (message.empty()) {
246  message = cinfo.get_type();
247  } else {
248  message += ", " + cinfo.get_type();
249  }
250  const std::string &name(cinfo.get_name());
251  if (!name.empty()) {
252  message += ":" + name;
253  }
254 }
255 
257  if (!agent_ || !agent_->oper_db() || !agent_->oper_db()->global_vrouter()) {
258  return false;
259  }
260  return agent_->oper_db()->global_vrouter()->configured();
261 }
262 
264  (const std::vector<ConnectionInfo> &cinfos,
265  ProcessState::type &pstate, std::string &message) {
266  size_t num_conns = 0;
267  uint8_t num_control_nodes = 0, num_dns_servers = 0;
268  uint8_t down_control_nodes = 0;
269  uint8_t expected_conns = ExpectedConnections(num_control_nodes,
270  num_dns_servers);
271  std::string cup(g_process_info_constants.ConnectionStatusNames.
272  find(ConnectionStatus::UP)->second);
273  bool is_cup = true;
274  bool is_tor_connected = false;
275  string tor_type(g_process_info_constants.ConnectionTypeNames.
276  find(ConnectionType::TOR)->second);
277  // Iterate to determine process connectivity status
278  for (std::vector<ConnectionInfo>::const_iterator it = cinfos.begin();
279  it != cinfos.end(); it++) {
280  const ConnectionInfo &cinfo(*it);
281  const std::string &conn_status(cinfo.get_status());
282  if (cinfo.get_type() == tor_type) {
283  is_tor_connected = true;
284  continue;
285  }
286  /* Don't consider ConnectionType::TOR type for counting connections.
287  * contrail-tor-agent is not supposed to report as Non-Functional when
288  * it is in backup mode, but contrail-tor-agent does not have a way to
289  * figure out that it is in backup mode. Hence for contrail-tor-agent
290  * (both active and backup modes) we don't consider connection to TOR
291  * for reporting Node Status */
292  num_conns++;
293  if (conn_status != cup) {
294  if (cinfo.get_name().compare(0, 13,
295  agent_->xmpp_control_node_prefix()) == 0) {
296  down_control_nodes++;
297  }
298  is_cup = false;
299  UpdateMessage(cinfo, message);
300  }
301  }
302  if ((num_control_nodes == 0) || (num_control_nodes == down_control_nodes)) {
303  pstate = ProcessState::NON_FUNCTIONAL;
304  if ((num_control_nodes == 0) && message.empty()) {
305  message = "No control-nodes configured";
306  }
307  } else if (!is_tor_connected && agent_->tor_agent_enabled()) {
308  // waiting for first TOR config to arrive
309  pstate = ProcessState::NON_FUNCTIONAL;
310  message += " No ToR Config";
311  } else {
312  pstate = ProcessState::FUNCTIONAL;
313  }
314  if (!is_cup) {
315  message += " connection down";
316  }
317  if (!HasSelfConfiguration()) {
318  // waiting for Global vrouter config
319  pstate = ProcessState::NON_FUNCTIONAL;
320  if (message.empty()) {
321  message = "No Configuration for self";
322  } else {
323  message += ", No Configuration for self";
324  }
325  }
326  for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
327  if (!agent_->controller_ifmap_xmpp_server(i).empty()) {
328  if (agent_->stats()->xmpp_reconnects(i) >= 1) {
329  break;
330  }
331  }
332  }
333 
334  if (num_conns != expected_conns) {
335  message += " Number of connections:" + integerToString(num_conns) +
336  ", Expected: " + integerToString(expected_conns);
337  return;
338  }
339  return;
340 }
341 
343  vn_uve_table_.get()->RegisterDBClients();
344  vm_uve_table_.get()->RegisterDBClients();
345  vrouter_uve_entry_.get()->RegisterDBClients();
346  prouter_uve_table_.get()->RegisterDBClients();
347  interface_uve_table_.get()->RegisterDBClients();
348 }
349 
351  vrouter_stats_collector_->InitDone();
352 }
std::vector< int > TagList
Definition: agent.h:202
#define MAX_XMPP_SERVERS
Definition: agent.h:291
const std::vector< std::string > collector_server_list() const
Definition: agent_param.h:304
uint32_t xmpp_reconnects(uint8_t idx) const
Definition: agent_stats.h:59
static const uint32_t kUveCountPerTimer
boost::scoped_ptr< VrouterStatsCollector > vrouter_stats_collector_
static const uint64_t kBandwidthInterval
virtual ~AgentUveBase()
void VrouterAgentProcessState(const std::vector< process::ConnectionInfo > &c, process::ProcessState::type &state, std::string &message)
virtual void RegisterDBClients()
void BuildTagIdsFromList(const TagList &tl, UveTagData *info) const
boost::scoped_ptr< VnUveTableBase > vn_uve_table_
boost::scoped_ptr< VrouterUveEntryBase > vrouter_uve_entry_
boost::scoped_ptr< InterfaceUveTable > interface_uve_table_
AgentUveBase(Agent *agent, uint64_t intvl, uint32_t default_intvl, uint32_t incremental_intvl)
uint32_t incremental_interval_
void set_incremental_interval(uint32_t new_interval=kIncrementalInterval)
Sets the incremental interval (time between dispatches of Agent's information and its remnant to UVE)...
static AgentUveBase * singleton_
void set_default_interval(uint32_t new_interval=kDefaultInterval)
Sets the default interval (time between two dispatches of Agent's information to UVE).
boost::scoped_ptr< VmUveTableBase > vm_uve_table_
void UpdateMessage(const process::ConnectionInfo &info, std::string &message)
static const uint32_t kDefaultInterval
static const uint32_t kIncrementalInterval
virtual void Shutdown()
uint8_t ExpectedConnections(uint8_t &num_c_nodes, uint8_t &num_d_servers)
boost::scoped_ptr< ProuterUveTable > prouter_uve_table_
uint32_t default_interval_
std::string IntegerToHexString(uint32_t value) const
virtual void InitDone()
process::ConnectionStateManager * connection_state_manager_
void BuildTagNamesFromList(const TagList &tl, UveTagData *info) const
bool HasSelfConfiguration() const
Definition: agent.h:360
ServicesModule * services() const
Definition: agent.cc:976
TagTable * tag_table() const
Definition: agent.h:507
OperDB * oper_db() const
Definition: agent.cc:1016
const std::string & dns_server(uint8_t idx) const
Definition: agent.h:859
AgentParam * params() const
Definition: agent.h:1226
const std::string & agent_name() const
Definition: agent.h:880
EventManager * event_manager() const
Definition: agent.h:1105
void set_connection_state(process::ConnectionState *state)
Definition: agent.h:958
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:732
const std::string & module_name() const
Definition: agent.h:894
static const std::string & xmpp_control_node_prefix()
Definition: agent.h:449
bool tor_agent_enabled() const
Definition: agent.h:1166
AgentStats * stats() const
Definition: agent.cc:884
const std::string & instance_id() const
Definition: agent.h:888
static void Init()
boost::asio::io_context * io_service()
Definition: event_manager.h:42
bool configured() const
GlobalVrouter * global_vrouter() const
Definition: operdb_init.h:54
static const uint32_t kTagTypeBitShift
const std::string & TagName(uint32_t id)
void Init(boost::asio::io_context &service, const std::string &hostname, const std::string &module, const std::string &instance_id, ProcessStateFn status_cb, std::string table)
static EventManager evm
uint8_t type
Definition: load_balance.h:2
Definition: io_utils.cc:11
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
std::vector< string > label_vector
std::vector< string > custom_tag_vector
std::set< string > label_set
std::string application
std::string tier
std::string site
std::string deployment
FillType fill_type
std::set< string > custom_tag_set
std::string labels
std::string custom_tags