OpenSDN source code
ifmap_server_show.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <sandesh/request_pipeline.h>
6 
7 #include <boost/bind/bind.hpp>
8 #include <boost/assign/list_of.hpp>
9 #include "base/regex.h"
10 #include "base/logging.h"
11 #include "db/db.h"
12 #include "db/db_graph.h"
13 #include "db/db_graph_vertex.h"
14 #include "db/db_table_partition.h"
15 #include "base/bitset.h"
16 
17 #include "config_client_manager.h"
18 #include "config_db_client.h"
19 #include "config_client_show_types.h"
20 
21 #include "ifmap/ifmap_client.h"
22 #include "ifmap/ifmap_exporter.h"
23 #include "ifmap/ifmap_link.h"
24 #include "ifmap/ifmap_link_table.h"
25 #include "ifmap/ifmap_log.h"
26 #include "ifmap/ifmap_node.h"
27 #include "ifmap/ifmap_object.h"
28 #include "ifmap/ifmap_origin.h"
30 #include "ifmap/ifmap_server.h"
31 #include "ifmap/ifmap_server_show_types.h"
32 #include "ifmap/ifmap_server_show_internal_types.h"
33 #include "ifmap/ifmap_log_types.h"
34 #include "ifmap/ifmap_table.h"
35 #include "ifmap/ifmap_update.h"
37 
38 #include <pugixml/pugixml.hpp>
39 
40 using namespace boost::assign;
41 using namespace std;
42 using namespace pugi;
43 using namespace boost::placeholders;
44 
45 using contrail::regex;
48 
50 public:
51  IFMapNodeCopier(IFMapNodeShowInfo *dest, DBEntryBase *src,
52  IFMapServer *server) {
53  // Get the name of the node
54  IFMapNode *src_node = static_cast<IFMapNode *>(src);
55  dest->node_name = src_node->ToString();
56 
57  IFMapNodeState *state = server->exporter()->NodeStateLookup(src_node);
58 
59  if (state) {
60  // Get the interests and advertised from state
61  dest->interests = state->interest().ToNumberedString();
62  dest->advertised = state->advertised().ToNumberedString();
63  } else {
64  dest->dbentryflags.append("No state, ");
65  }
66 
67  if (src_node->IsDeleted()) {
68  dest->dbentryflags.append("Deleted, ");
69  }
70  if (src_node->is_onlist()) {
71  dest->dbentryflags.append("OnList, ");
72  }
73  if (src_node->IsOnRemoveQ()) {
74  dest->dbentryflags.append("OnRemoveQ");
75  }
76 
77  dest->obj_info.reserve(src_node->list_.size());
78  for (IFMapNode::ObjectList::const_iterator iter =
79  src_node->list_.begin(); iter != src_node->list_.end(); ++iter) {
80  const IFMapObject *src_obj = iter.operator->();
81 
82  IFMapObjectShowInfo dest_obj;
83  dest_obj.sequence_number = src_obj->sequence_number();
84  dest_obj.origin = src_obj->origin().ToString();
85  dest_obj.data = GetIFMapObjectData(src_obj);
86 
87  dest->obj_info.push_back(dest_obj);
88  }
89  if (src_node->IsVertexValid()) {
90  DBGraph *graph = server->graph();
91  int neighbor_count = 0;
93  src_node->begin(graph); iter != src_node->end(graph); ++iter) {
94  ++neighbor_count;
95  }
96  dest->neighbors.reserve(neighbor_count);
98  src_node->begin(graph); iter != src_node->end(graph); ++iter) {
99  IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
100  dest->neighbors.push_back(adj->ToString());
101  }
102  }
103  dest->last_modified = src_node->last_change_at_str();
104  }
105 
106  string GetIFMapObjectData(const IFMapObject *src_obj) {
107  pugi::xml_document xdoc;
108  pugi::xml_node xnode = xdoc.append_child("iq");
109  src_obj->EncodeUpdate(&xnode);
110 
111  ostringstream oss;
112  xnode.print(oss);
113  string objdata = oss.str();
114  return objdata;
115  }
116 };
117 
118 const string kShowIterSeparator = "||";
119 
120 // almost everything in this class is static since we dont really want to
121 // intantiate this class
123 public:
124  static const uint32_t kMaxElementsPerRound = 50;
125 
126  static int GetPageLimit(IFMapSandeshContext *sctx) {
127  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
128  }
129 
131  vector<IFMapNodeShowInfo> send_buffer;
134  };
135 
137  return static_cast<RequestPipeline::InstData *>(new ShowData);
138  }
139 
140  static bool BufferStageCommon(const IFMapTableShowReq *request,
142  const string &next_table_name,
143  const string &last_node_name);
144  static bool BufferStage(const Sandesh *sr,
145  const RequestPipeline::PipeSpec ps, int stage,
146  int instNum, RequestPipeline::InstData *data);
147  static bool BufferStageIterate(const Sandesh *sr,
148  const RequestPipeline::PipeSpec ps, int stage,
149  int instNum, RequestPipeline::InstData *data);
150  static void SendStageCommon(const IFMapTableShowReq *request,
151  const RequestPipeline::PipeSpec ps,
152  IFMapTableShowResp *response);
153  static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps,
154  int stage, int instNum,
156  static bool SendStageIterate(const Sandesh *sr,
157  const RequestPipeline::PipeSpec ps, int stage,
158  int instNum, RequestPipeline::InstData *data);
159  static bool TableToBuffer(const IFMapTableShowReq *request,
160  IFMapTable *table, IFMapServer *server,
161  const string &last_node_name,
162  ShowData *show_data, uint32_t page_limit);
163  static bool BufferAllTables(const IFMapTableShowReq *req,
165  const string &next_table_name,
166  const string &last_node_name);
167  static bool BufferOneTable(const IFMapTableShowReq *request,
169  const string &last_node_name);
170  static bool ConvertReqIterateToReq(
171  const IFMapTableShowReqIterate *req_iterate,
172  IFMapTableShowReq *req, string *next_table_name,
173  string *last_node_name);
174 };
175 
176 // Return true if the buffer is full.
177 bool ShowIFMapTable::TableToBuffer(const IFMapTableShowReq *request,
178  IFMapTable *table, IFMapServer *server,
179  const string &last_node_name,
180  ShowData *show_data, uint32_t page_limit) {
181  DBEntryBase *src = NULL;
182  if (last_node_name.length()) {
183  // If the last_node_name is set, it was the last node printed in the
184  // previous round. Search for the node 'after' last_node_name and start
185  // this round with it. If there is no next node, we are done with this
186  // table.
187  IFMapNode *last_node = table->FindNextNode(last_node_name);
188  if (last_node) {
189  src = last_node;
190  } else {
191  return false;
192  }
193  }
194 
195  bool buffer_full = false;
196  regex search_expr(request->get_search_string());
197  DBTablePartBase *partition = table->GetTablePartition(0);
198  if (!src) {
199  src = partition->GetFirst();
200  }
201  for (; src != NULL; src = partition->GetNext(src)) {
202  IFMapNode *src_node = static_cast<IFMapNode *>(src);
203  if (!regex_search(src_node->ToString(), search_expr)) {
204  continue;
205  }
206  IFMapNodeShowInfo dest;
207  IFMapNodeCopier copyNode(&dest, src, server);
208  show_data->send_buffer.push_back(dest);
209 
210  // If we have picked up enough nodes for this round...
211  if (show_data->send_buffer.size() == page_limit) {
212  // Save the values needed for the next round. When we come
213  // back, we will use the 'names' to lookup the elements since
214  // the 'names' are the keys in the respective tables.
215  show_data->next_table_name = table->name();
216  show_data->last_node_name = src_node->name();
217  buffer_full = true;
218  break;
219  }
220  }
221 
222  return buffer_full;
223 }
224 
225 bool ShowIFMapTable::BufferOneTable(const IFMapTableShowReq *request,
227  const string &last_node_name) {
228  IFMapSandeshContext *sctx =
229  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
230 
232  request->get_table_name());
233  if (table) {
234  ShowData *show_data = static_cast<ShowData *>(data);
235  uint32_t page_limit = GetPageLimit(sctx);
236  show_data->send_buffer.reserve(page_limit);
237  TableToBuffer(request, table, sctx->ifmap_server(), last_node_name,
238  show_data, page_limit);
239  } else {
240  IFMAP_WARN(IFMapTblNotFound, "Cant show/find table ",
241  request->get_table_name());
242  }
243 
244  return true;
245 }
246 
247 bool ShowIFMapTable::BufferAllTables(const IFMapTableShowReq *request,
249  const string &next_table_name,
250  const string &last_node_name) {
251  IFMapSandeshContext *sctx =
252  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
253  string last_name = last_node_name;
254 
255  DB *db = sctx->ifmap_server()->database();
256  DB::iterator iter;
257  if (next_table_name.empty()) {
258  iter = db->lower_bound("__ifmap__.");
259  } else {
260  iter = db->FindTableIter(next_table_name);
261  }
262 
263  ShowData *show_data = static_cast<ShowData *>(data);
264  uint32_t page_limit = GetPageLimit(sctx);
265  show_data->send_buffer.reserve(page_limit);
266  for (; iter != db->end(); ++iter) {
267  if (iter->first.find("__ifmap__.") != 0) {
268  break;
269  }
270  IFMapTable *table = static_cast<IFMapTable *>(iter->second);
271  bool buffer_full = TableToBuffer(request, table, sctx->ifmap_server(),
272  last_name, show_data, page_limit);
273  if (buffer_full) {
274  break;
275  }
276  // last_node_name is only relevant for the first iteration.
277  last_name.clear();
278  }
279 
280  return true;
281 }
282 
283 // Format of node_info string:
284 // table_name||search_string||next_table_name||last_node_name
285 // table_name/search_string: original input. Could be empty.
286 // next_table_name: next table to lookup in
287 // last_node_name: name of last node that was printed in the previous round
289  const IFMapTableShowReqIterate *req_iterate,
290  IFMapTableShowReq *req, string *next_table_name,
291  string *last_node_name) {
292  // First, set the context from the original request since we might return
293  // due to parsing errors.
294  req->set_context(req_iterate->context());
295 
296  string node_info = req_iterate->get_node_info();
297  size_t sep_size = kShowIterSeparator.size();
298 
299  // table_name
300  size_t pos1 = node_info.find(kShowIterSeparator);
301  if (pos1 == string::npos) {
302  return false;
303  }
304  string table_name = node_info.substr(0, pos1);
305 
306  // search_string
307  size_t pos2 = node_info.find(kShowIterSeparator, (pos1 + sep_size));
308  if (pos2 == string::npos) {
309  return false;
310  }
311  string search_string = node_info.substr((pos1 + sep_size),
312  pos2 - (pos1 + sep_size));
313 
314  // next_table_name
315  size_t pos3 = node_info.find(kShowIterSeparator, (pos2 + sep_size));
316  if (pos3 == string::npos) {
317  return false;
318  }
319  *next_table_name = node_info.substr((pos2 + sep_size),
320  pos3 - (pos2 + sep_size));
321 
322  // last_node_name
323  *last_node_name = node_info.substr(pos3 + sep_size);
324 
325  // Fill up the fields of IFMapTableShowReq appropriately.
326  req->set_table_name(table_name);
327  req->set_search_string(search_string);
328  return true;
329 }
330 
331 bool ShowIFMapTable::BufferStageCommon(const IFMapTableShowReq *request,
333  const string &next_table_name,
334  const string &last_node_name) {
335  // If table name has not been passed, print all tables
336  if (request->get_table_name().length()) {
337  return BufferOneTable(request, data, last_node_name);
338  } else {
339  return BufferAllTables(request, data, next_table_name, last_node_name);
340  }
341 }
342 
344  const RequestPipeline::PipeSpec ps,
345  int stage, int instNum,
347  const IFMapTableShowReq *request =
348  static_cast<const IFMapTableShowReq *>(ps.snhRequest_.get());
349  string next_table_name;
350  string last_node_name;
351  return BufferStageCommon(request, data, next_table_name, last_node_name);
352 }
353 
355  const RequestPipeline::PipeSpec ps,
356  int stage, int instNum,
358  const IFMapTableShowReqIterate *request_iterate =
359  static_cast<const IFMapTableShowReqIterate *>(ps.snhRequest_.get());
360 
361  string next_table_name;
362  string last_node_name;
363  IFMapTableShowReq *request = new IFMapTableShowReq;
364  bool success = ConvertReqIterateToReq(request_iterate, request,
365  &next_table_name, &last_node_name);
366  if (success) {
367  BufferStageCommon(request, data, next_table_name, last_node_name);
368  }
369  request->Release();
370  return true;
371 }
372 
373 void ShowIFMapTable::SendStageCommon(const IFMapTableShowReq *request,
374  const RequestPipeline::PipeSpec ps,
375  IFMapTableShowResp *response) {
376  const RequestPipeline::StageData *prev_stage_data = ps.GetStageData(0);
377  const ShowIFMapTable::ShowData &show_data =
378  static_cast<const ShowIFMapTable::ShowData&>(prev_stage_data->at(0));
379  IFMapSandeshContext *sctx =
380  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
381 
382  vector<IFMapNodeShowInfo> dest_buffer;
383  dest_buffer = show_data.send_buffer;
384 
385  // If we have filled the buffer, set next_batch with all the values we will
386  // need in the next round.
387  string next_batch;
388  uint32_t page_limit = GetPageLimit(sctx);
389  if (dest_buffer.size() == page_limit) {
390  next_batch = request->get_table_name() + kShowIterSeparator +
391  request->get_search_string() + kShowIterSeparator +
392  show_data.next_table_name + kShowIterSeparator +
393  show_data.last_node_name;
394  }
395 
396  response->set_ifmap_db(dest_buffer);
397  response->set_next_batch(next_batch);
398 }
399 
401  const RequestPipeline::PipeSpec ps,
402  int stage, int instNum,
404  const IFMapTableShowReq *request =
405  static_cast<const IFMapTableShowReq *>(ps.snhRequest_.get());
406  IFMapTableShowResp *response = new IFMapTableShowResp;
407  SendStageCommon(request, ps, response);
408 
409  response->set_context(request->context());
410  response->set_more(false);
411  response->Response();
412  return true;
413 }
414 
416  const RequestPipeline::PipeSpec ps,
417  int stage, int instNum,
419  const IFMapTableShowReqIterate *request_iterate =
420  static_cast<const IFMapTableShowReqIterate *>(ps.snhRequest_.get());
421 
422  string next_table_name;
423  string last_node_name;
424 
425  IFMapTableShowResp *response = new IFMapTableShowResp;
426  IFMapTableShowReq *request = new IFMapTableShowReq;
427  bool success = ConvertReqIterateToReq(request_iterate, request,
428  &next_table_name, &last_node_name);
429  if (success) {
430  SendStageCommon(request, ps, response);
431  }
432 
433  response->set_context(request->context());
434  response->set_more(false);
435  response->Response();
436 
437  request->Release();
438  return true;
439 }
440 
441 void IFMapTableShowReq::HandleRequest() const {
442 
445 
446  // 2 stages - first: gather/read, second: send
447 
448  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
451  s0.instances_.push_back(0);
452 
453  // control-node ifmap show command task
454  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
456  s1.instances_.push_back(0);
457 
458  RequestPipeline::PipeSpec ps(this);
459  ps.stages_ = list_of(s0)(s1)
460  .convert_to_container<vector<RequestPipeline::StageSpec> >();
461  RequestPipeline rp(ps);
462 }
463 
464 void IFMapTableShowReqIterate::HandleRequest() const {
465 
468 
469  // 2 stages - first: gather/read, second: send
470 
471  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
474  s0.instances_.push_back(0);
475 
476  // control-node ifmap show command task
477  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
479  s1.instances_.push_back(0);
480 
481  RequestPipeline::PipeSpec ps(this);
482  ps.stages_ = list_of(s0)(s1)
483  .convert_to_container<vector<RequestPipeline::StageSpec> >();
484  RequestPipeline rp(ps);
485 }
486 
487 // Code to display link-table entries
488 
490 public:
491  static const uint32_t kMaxElementsPerRound = 50;
492 
493  static int GetPageLimit(IFMapSandeshContext *sctx) {
494  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
495  }
496 
498  vector<IFMapLinkShowInfo> send_buffer;
499  uint32_t table_size;
501  };
502 
504  return static_cast<RequestPipeline::InstData *>(new ShowData);
505  }
506 
507  static bool IncludeLink(DBEntryBase *src, const string &search_string,
508  const regex &search_expr, const string &metadata,
509  const regex &metadata_expr);
510  static void CopyNode(IFMapLinkShowInfo *dest, DBEntryBase *src,
511  IFMapServer *server);
512  static bool BufferStageCommon(const IFMapLinkTableShowReq *request,
514  const string &last_link_name);
515  static bool BufferStage(const Sandesh *sr,
516  const RequestPipeline::PipeSpec ps, int stage,
517  int instNum, RequestPipeline::InstData *data);
518  static bool BufferStageIterate(const Sandesh *sr,
519  const RequestPipeline::PipeSpec ps,
520  int stage, int instNum,
522  static void SendStageCommon(const IFMapLinkTableShowReq *request,
523  const RequestPipeline::PipeSpec ps,
524  IFMapLinkTableShowResp *response);
525  static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps,
526  int stage, int instNum,
528  static bool SendStageIterate(const Sandesh *sr,
529  const RequestPipeline::PipeSpec ps, int stage,
530  int instNum, RequestPipeline::InstData *data);
531  static bool ConvertReqIterateToReq(
532  const IFMapLinkTableShowReqIterate *req_iterate,
533  IFMapLinkTableShowReq *req, string *last_link_name);
534 };
535 
537  const string &search_string,
538  const regex &search_expr,
539  const string &metadata,
540  const regex &metadata_expr) {
541  IFMapLink *link = static_cast<IFMapLink *>(src);
542  IFMapNode *left = link->left();
543  IFMapNode *right = link->right();
544 
545  // If we do not find the search string in the names of either of the
546  // two ends, do not include the link.
547  if (!search_string.empty() &&
548  (!left || !regex_search(left->ToString(), search_expr)) &&
549  (!right || !regex_search(right->ToString(), search_expr))) {
550  return false;
551  }
552 
553  // If the metadata does not match, do not include the link.
554  if (!metadata.empty() && !regex_search(link->metadata(), metadata_expr)) {
555  return false;
556  }
557 
558  return true;
559 }
560 
561 void ShowIFMapLinkTable::CopyNode(IFMapLinkShowInfo *dest, DBEntryBase *src,
562  IFMapServer *server) {
563  IFMapLink *src_link = static_cast<IFMapLink *>(src);
564 
565  dest->metadata = src_link->metadata();
566  if (src_link->left()) {
567  dest->left = src_link->left()->ToString();
568  }
569  if (src_link->right()) {
570  dest->right = src_link->right()->ToString();
571  }
572 
573  // Get the interests and advertised from state
574  IFMapLinkState *state = server->exporter()->LinkStateLookup(src_link);
575  if (state) {
576  dest->interests = state->interest().ToNumberedString();
577  dest->advertised = state->advertised().ToNumberedString();
578  } else {
579  dest->dbentryflags.append("No state, ");
580  }
581 
582  if (src_link->IsDeleted()) {
583  dest->dbentryflags.append("Deleted, ");
584  }
585  if (src_link->is_onlist()) {
586  dest->dbentryflags.append("OnList");
587  }
588  if (src_link->IsOnRemoveQ()) {
589  dest->dbentryflags.append("OnRemoveQ");
590  }
591  dest->last_modified = src_link->last_change_at_str();
592 
593  for (std::vector<IFMapLink::LinkOriginInfo>::const_iterator iter =
594  src_link->origin_info_.begin(); iter != src_link->origin_info_.end();
595  ++iter) {
596  const IFMapLink::LinkOriginInfo *origin_info = iter.operator->();
597  IFMapLinkOriginShowInfo dest_origin;
598  dest_origin.sequence_number = origin_info->sequence_number;
599  dest_origin.origin = origin_info->origin.ToString();
600  dest->origins.push_back(dest_origin);
601  }
602 }
603 
604 // Format of link_info string:
605 // search_string||metadata||last_link_name
606 // search_string: original input. Could be empty.
607 // metadata: original input. Could be empty.
608 // last_link_name: name of last link that was printed in the previous round
610  const IFMapLinkTableShowReqIterate *req_iterate,
611  IFMapLinkTableShowReq *req, string *last_link_name) {
612  // First, set the context from the original request since we might return
613  // due to parsing errors.
614  req->set_context(req_iterate->context());
615 
616  string link_info = req_iterate->get_link_info();
617  size_t sep_size = kShowIterSeparator.size();
618 
619  // search_string
620  size_t pos1 = link_info.find(kShowIterSeparator);
621  if (pos1 == string::npos) {
622  return false;
623  }
624  string search_string = link_info.substr(0, pos1);
625 
626  // metadata
627  size_t pos2 = link_info.find(kShowIterSeparator, (pos1 + sep_size));
628  if (pos2 == string::npos) {
629  return false;
630  }
631  string metadata = link_info.substr((pos1 + sep_size),
632  pos2 - (pos1 + sep_size));
633 
634  // last_link_name
635  *last_link_name = link_info.substr(pos2 + sep_size);
636 
637  // Fill up the fields of IFMapLinkTableShowReq appropriately.
638  req->set_search_string(search_string);
639  req->set_metadata(metadata);
640  return true;
641 }
642 
643 bool ShowIFMapLinkTable::BufferStageCommon(const IFMapLinkTableShowReq *request,
645  const string &last_link_name) {
646  bool buffer_full = false;
647  IFMapSandeshContext *sctx =
648  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
649 
650  IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
651  sctx->ifmap_server()->database()->FindTable("__ifmap_metadata__.0"));
652  if (table) {
653  regex search_expr(request->get_search_string());
654  regex metadata_expr(request->get_metadata());
655  ShowData *show_data = static_cast<ShowData *>(data);
656  uint32_t page_limit = GetPageLimit(sctx);
657  show_data->send_buffer.reserve(page_limit);
658  show_data->table_size = table->Size();
659 
660  DBEntryBase *src = NULL;
661  DBTablePartBase *partition = table->GetTablePartition(0);
662  if (last_link_name.length()) {
663  src = table->FindNextLink(last_link_name);
664  } else {
665  src = partition->GetFirst();
666  }
667  for (; src != NULL; src = partition->GetNext(src)) {
668  if (IncludeLink(src, request->get_search_string(), search_expr,
669  request->get_metadata(), metadata_expr)) {
670  IFMapLinkShowInfo dest;
671  CopyNode(&dest, src, sctx->ifmap_server());
672  show_data->send_buffer.push_back(dest);
673  // If we have picked up enough links for this round...
674  uint32_t page_limit = GetPageLimit(sctx);
675  if (show_data->send_buffer.size() == page_limit) {
676  IFMapLink *src_link = static_cast<IFMapLink *>(src);
677  show_data->last_link_name = src_link->link_name();
678  buffer_full = true;
679  break;
680  }
681  }
682  }
683  } else {
684  IFMAP_WARN(IFMapTblNotFound, "Cant show/find ", "link table");
685  }
686 
687  return buffer_full;
688 }
689 
691  const RequestPipeline::PipeSpec ps,
692  int stage, int instNum,
694  const IFMapLinkTableShowReq *request =
695  static_cast<const IFMapLinkTableShowReq *>(ps.snhRequest_.get());
696  string last_link_name;
697  BufferStageCommon(request, data, last_link_name);
698  return true;
699 }
700 
702  const RequestPipeline::PipeSpec ps,
703  int stage, int instNum,
705  const IFMapLinkTableShowReqIterate *request_iterate =
706  static_cast<const IFMapLinkTableShowReqIterate *>(ps.snhRequest_.get());
707 
708  IFMapLinkTableShowReq *request = new IFMapLinkTableShowReq;
709  string last_link_name;
710  bool success = ConvertReqIterateToReq(request_iterate, request,
711  &last_link_name);
712  if (success) {
713  BufferStageCommon(request, data, last_link_name);
714  }
715  request->Release();
716  return true;
717 }
718 
719 void ShowIFMapLinkTable::SendStageCommon(const IFMapLinkTableShowReq *request,
720  const RequestPipeline::PipeSpec ps,
721  IFMapLinkTableShowResp *response) {
722  const RequestPipeline::StageData *prev_stage_data = ps.GetStageData(0);
723  const ShowIFMapLinkTable::ShowData &show_data =
724  static_cast<const ShowIFMapLinkTable::ShowData&>
725  (prev_stage_data->at(0));
726 
727  vector<IFMapLinkShowInfo> dest_buffer;
728  dest_buffer = show_data.send_buffer;
729 
730  // If we have filled the buffer, set next_batch with all the values we will
731  // need in the next round.
732  string next_batch;
733  IFMapSandeshContext *sctx =
734  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
735  uint32_t page_limit = GetPageLimit(sctx);
736  if (dest_buffer.size() == page_limit) {
737  next_batch = request->get_search_string() + kShowIterSeparator +
738  request->get_metadata() + kShowIterSeparator +
739  show_data.last_link_name;
740  }
741 
742  response->set_table_size(show_data.table_size);
743  response->set_ifmap_db(dest_buffer);
744  response->set_next_batch(next_batch);
745 }
746 
748  const RequestPipeline::PipeSpec ps,
749  int stage, int instNum,
751  const IFMapLinkTableShowReq *request =
752  static_cast<const IFMapLinkTableShowReq *>(ps.snhRequest_.get());
753  IFMapLinkTableShowResp *response = new IFMapLinkTableShowResp;
754  SendStageCommon(request, ps, response);
755 
756  response->set_context(request->context());
757  response->set_more(false);
758  response->Response();
759  return true;
760 }
761 
763  const RequestPipeline::PipeSpec ps,
764  int stage, int instNum,
766  const IFMapLinkTableShowReqIterate *request_iterate =
767  static_cast<const IFMapLinkTableShowReqIterate *>(ps.snhRequest_.get());
768 
769  IFMapLinkTableShowResp *response = new IFMapLinkTableShowResp;
770  IFMapLinkTableShowReq *request = new IFMapLinkTableShowReq;
771  string last_link_name;
772  bool success = ConvertReqIterateToReq(request_iterate, request,
773  &last_link_name);
774  if (success) {
775  SendStageCommon(request, ps, response);
776  }
777 
778  response->set_context(request->context());
779  response->set_more(false);
780  response->Response();
781 
782  request->Release();
783  return true;
784 }
785 
786 void IFMapLinkTableShowReq::HandleRequest() const {
787 
790 
791  // 2 stages - first: gather/read, second: send
792 
793  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
796  s0.instances_.push_back(0);
797 
798  // control-node ifmap show command task
799  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
801  s1.instances_.push_back(0);
802 
803  RequestPipeline::PipeSpec ps(this);
804  ps.stages_ = list_of(s0)(s1)
805  .convert_to_container<vector<RequestPipeline::StageSpec> >();
806  RequestPipeline rp(ps);
807 }
808 
809 void IFMapLinkTableShowReqIterate::HandleRequest() const {
810 
813 
814  // 2 stages - first: gather/read, second: send
815 
816  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
819  s0.instances_.push_back(0);
820 
821  // control-node ifmap show command task
822  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
824  s1.instances_.push_back(0);
825 
826  RequestPipeline::PipeSpec ps(this);
827  ps.stages_ = list_of(s0)(s1)
828  .convert_to_container\
829  <vector<RequestPipeline::StageSpec> >();
830  RequestPipeline rp(ps);
831 }
832 
834  const RequestPipeline::PipeSpec ps,
835  int stage, int instNum,
837  const IFMapNodeShowReq *request =
838  static_cast<const IFMapNodeShowReq *>(ps.snhRequest_.get());
839  IFMapSandeshContext *sctx =
840  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
841 
842  IFMapNodeShowResp *response = new IFMapNodeShowResp();
843 
844  string fq_node_name = request->get_fq_node_name();
845  // EG: "virtual-network:my:virtual:network" i.e. type:name
846  size_t type_length = fq_node_name.find(":");
847  if (type_length != string::npos) {
848  string node_type = fq_node_name.substr(0, type_length);
849  // +1 to go to the next character after ':'
850  string node_name = fq_node_name.substr(type_length + 1);
851 
852  DB *db = sctx->ifmap_server()->database();
853  IFMapTable *table = IFMapTable::FindTable(db, node_type);
854  if (table) {
855  IFMapNode *src = table->FindNode(node_name);
856  if (src) {
857  IFMapNodeShowInfo dest;
858  IFMapNodeCopier copyNode(&dest, src, sctx->ifmap_server());
859  response->set_node_info(dest);
860  } else {
861  IFMAP_WARN(IFMapIdentifierNotFound, "Cant find identifier",
862  node_name);
863  }
864  } else {
865  IFMAP_WARN(IFMapTblNotFound, "Cant show/find table with node-type",
866  node_type);
867  }
868  }
869 
870  response->set_context(request->context());
871  response->set_more(false);
872  response->Response();
873 
874  // Return 'true' so that we are not called again
875  return true;
876 }
877 
878 void IFMapNodeShowReq::HandleRequest() const {
879 
882 
883  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
885  s0.instances_.push_back(0);
886 
887  RequestPipeline::PipeSpec ps(this);
888  ps.stages_ = list_of(s0)
889  .convert_to_container\
890  <vector<RequestPipeline::StageSpec> >();
891  RequestPipeline rp(ps);
892 }
893 
895 public:
896  static const uint32_t kMaxElementsPerRound = 50;
897 
898  static int GetPageLimit(IFMapSandeshContext *sctx) {
899  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
900  }
901 
903  vector<IFMapPerClientNodesShowInfo> send_buffer;
906  };
907 
909  return static_cast<RequestPipeline::InstData *>(new ShowData);
910  }
911 
912  static bool ConvertReqIterateToReq(
913  const IFMapPerClientNodesShowReqIterate *req_iterate,
914  IFMapPerClientNodesShowReq *req, string *next_table_name,
915  string *last_node_name);
916  static bool CopyNode(IFMapPerClientNodesShowInfo *dest, IFMapNode *src,
917  IFMapServer *server, int client_index);
918  static bool TableToBuffer(const IFMapPerClientNodesShowReq *request,
919  IFMapTable *table, IFMapServer *server,
920  const string &last_node_name, int client_index,
921  ShowData *show_data);
922  static bool BufferStageCommon(const IFMapPerClientNodesShowReq *request,
924  const string &next_table_name,
925  const string &last_node_name);
926  static bool BufferStage(const Sandesh *sr,
927  const RequestPipeline::PipeSpec ps, int stage,
928  int instNum, RequestPipeline::InstData *data);
929  static bool BufferStageIterate(const Sandesh *sr,
930  const RequestPipeline::PipeSpec ps,
931  int stage, int instNum,
933  static void SendStageCommon(const IFMapPerClientNodesShowReq *request,
934  const RequestPipeline::PipeSpec ps,
935  IFMapPerClientNodesShowResp *response);
936  static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps,
937  int stage, int instNum,
939  static bool SendStageIterate(const Sandesh *sr,
940  const RequestPipeline::PipeSpec ps, int stage,
941  int instNum, RequestPipeline::InstData *data);
942 };
943 
944 // Format of node_info string:
945 // client_index_or_name||search_string||next_table_name||last_node_name
946 // client_index_or_name: original input
947 // search_string: original input; can be empty
948 // next_table_name: next table to lookup in
949 // last_node_name: name of last node that was printed in the previous round
951  const IFMapPerClientNodesShowReqIterate *req_iterate,
952  IFMapPerClientNodesShowReq *req, string *next_table_name,
953  string *last_node_name) {
954  // First, set the context from the original request since we might return
955  // due to parsing errors.
956  req->set_context(req_iterate->context());
957 
958  string node_info = req_iterate->get_node_info();
959  size_t sep_size = kShowIterSeparator.size();
960 
961  // client_index_or_name
962  size_t pos1 = node_info.find(kShowIterSeparator);
963  if (pos1 == string::npos) {
964  return false;
965  }
966  string client_index_or_name = node_info.substr(0, pos1);
967 
968  // search_string
969  size_t pos2 = node_info.find(kShowIterSeparator, (pos1 + sep_size));
970  if (pos2 == string::npos) {
971  return false;
972  }
973  string search_string = node_info.substr((pos1 + sep_size),
974  pos2 - (pos1 + sep_size));
975 
976  // next_table_name
977  size_t pos3 = node_info.find(kShowIterSeparator, (pos2 + sep_size));
978  if (pos3 == string::npos) {
979  return false;
980  }
981  *next_table_name = node_info.substr((pos2 + sep_size),
982  pos3 - (pos2 + sep_size));
983 
984  // last_node_name
985  *last_node_name = node_info.substr(pos3 + sep_size);
986 
987  // Fill up the fields of IFMapTableShowReq appropriately.
988  req->set_client_index_or_name(client_index_or_name);
989  req->set_search_string(search_string);
990  return true;
991 }
992 
993 bool ShowIFMapPerClientNodes::CopyNode(IFMapPerClientNodesShowInfo *dest,
994  IFMapNode *src, IFMapServer *server,
995  int client_index) {
996  IFMapNodeState *state = server->exporter()->NodeStateLookup(src);
997 
998  if (state && state->interest().test(client_index)) {
999  dest->node_name = src->ToString();
1000  if (state->advertised().test(client_index)) {
1001  dest->sent = "Yes";
1002  } else {
1003  dest->sent = "No";
1004  }
1005  if (server->exporter()->ClientHasConfigTracker(
1006  IFMapExporter::INTEREST, client_index)) {
1007  if (server->exporter()->ClientConfigTrackerHasState(
1008  IFMapExporter::INTEREST, client_index, state)) {
1009  dest->interest_tracked = "Yes";
1010  } else {
1011  dest->interest_tracked = "No";
1012  }
1013  } else {
1014  dest->interest_tracked = "No tracker";
1015  }
1016  if (server->exporter()->ClientHasConfigTracker(
1017  IFMapExporter::ADVERTISED, client_index)) {
1018  if (server->exporter()->ClientConfigTrackerHasState(
1019  IFMapExporter::ADVERTISED, client_index, state)) {
1020  dest->advertised_tracked = "Yes";
1021  } else {
1022  dest->advertised_tracked = "No";
1023  }
1024  } else {
1025  dest->advertised_tracked = "No tracker";
1026  }
1027  return true;
1028  } else {
1029  return false;
1030  }
1031 }
1032 
1034  const IFMapPerClientNodesShowReq *request, IFMapTable *table,
1035  IFMapServer *ifmap_server, const string &last_node_name,
1036  int client_index, ShowData *show_data) {
1037 
1038  DBEntryBase *src = NULL;
1039  if (last_node_name.length()) {
1040  // If the last_node_name is set, it was the last node printed in the
1041  // previous round. Search for the node 'after' last_node_name and start
1042  // this round with it. If there is no next node, we are done with this
1043  // table.
1044  IFMapNode *last_node = table->FindNextNode(last_node_name);
1045  if (last_node) {
1046  src = last_node;
1047  } else {
1048  return false;
1049  }
1050  }
1051 
1052  bool buffer_full = false;
1053  string search_string = request->get_search_string();
1054  DBTablePartBase *partition = table->GetTablePartition(0);
1055  if (!src) {
1056  src = partition->GetFirst();
1057  }
1058  for (; src != NULL; src = partition->GetNext(src)) {
1059  IFMapNode *src_node = static_cast<IFMapNode *>(src);
1060  if (!search_string.empty() &&
1061  (src_node->ToString().find(search_string) == string::npos)) {
1062  continue;
1063  }
1064  IFMapPerClientNodesShowInfo dest;
1065  bool send = CopyNode(&dest, src_node, ifmap_server, client_index);
1066  if (send) {
1067  show_data->send_buffer.push_back(dest);
1068 
1069  IFMapSandeshContext *sctx =
1070  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1071  uint32_t page_limit = sctx->page_limit() ?
1072  sctx->page_limit() : kMaxElementsPerRound;
1073  // If we have picked up enough nodes for this round...
1074  if (show_data->send_buffer.size() == page_limit) {
1075  // Save the values needed for the next round. When we come
1076  // back, we will use the 'names' to lookup the elements since
1077  // the 'names' are the keys in the respective tables.
1078  show_data->next_table_name = table->name();
1079  show_data->last_node_name = src_node->name();
1080  buffer_full = true;
1081  break;
1082  }
1083  }
1084  }
1085 
1086  return buffer_full;
1087 }
1088 
1090  const IFMapPerClientNodesShowReq *request,
1091  RequestPipeline::InstData *data, const string &next_table_name,
1092  const string &last_node_name) {
1093  IFMapSandeshContext *sctx =
1094  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1095  IFMapServer *ifmap_server = sctx->ifmap_server();
1096 
1097  // The user gives us either a name or an index. If the input is not a
1098  // number, find the client's index using its name. If we cant find it,
1099  // we cant process this request. If we have the index, continue processing.
1100  string client_index_or_name = request->get_client_index_or_name();
1101  int client_index;
1102  if (!stringToInteger(client_index_or_name, client_index)) {
1103  if (!ifmap_server->ClientNameToIndex(client_index_or_name,
1104  &client_index)) {
1105  return true;
1106  }
1107  }
1108 
1109  string last_name = last_node_name;
1110  string search_string = request->get_search_string();
1111  DB *db = ifmap_server->database();
1112 
1113  DB::iterator iter;
1114  if (next_table_name.empty()) {
1115  iter = db->lower_bound("__ifmap__.");
1116  } else {
1117  iter = db->FindTableIter(next_table_name);
1118  }
1119 
1120  uint32_t page_limit = GetPageLimit(sctx);
1121  ShowData *show_data = static_cast<ShowData *>(data);
1122  show_data->send_buffer.reserve(page_limit);
1123  for (; iter != db->end(); ++iter) {
1124  if (iter->first.find("__ifmap__.") != 0) {
1125  break;
1126  }
1127  IFMapTable *table = static_cast<IFMapTable *>(iter->second);
1128  bool buffer_full = TableToBuffer(request, table, ifmap_server,
1129  last_name, client_index, show_data);
1130  if (buffer_full) {
1131  break;
1132  }
1133  // last_node_name is only relevant for the first iteration.
1134  last_name.clear();
1135  }
1136 
1137  return true;
1138 }
1139 
1141  const RequestPipeline::PipeSpec ps,
1142  int stage, int instNum,
1143  RequestPipeline::InstData *data) {
1144  const IFMapPerClientNodesShowReq *request =
1145  static_cast<const IFMapPerClientNodesShowReq *>(ps.snhRequest_.get());
1146 
1147  // If neither the client index nor the name has been provided, we are done.
1148  if (request->get_client_index_or_name().empty()) {
1149  return true;
1150  }
1151 
1152  string next_table_name;
1153  string last_node_name;
1154  return BufferStageCommon(request, data, next_table_name, last_node_name);
1155 }
1156 
1158  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1159  int instNum, RequestPipeline::InstData *data) {
1160  const IFMapPerClientNodesShowReqIterate *request_iterate =
1161  static_cast<const IFMapPerClientNodesShowReqIterate *>
1162  (ps.snhRequest_.get());
1163 
1164  string next_table_name;
1165  string last_node_name;
1166  IFMapPerClientNodesShowReq *request = new IFMapPerClientNodesShowReq;
1167  bool success = ConvertReqIterateToReq(request_iterate, request,
1168  &next_table_name, &last_node_name);
1169  if (success) {
1170  BufferStageCommon(request, data, next_table_name, last_node_name);
1171  }
1172  request->Release();
1173  return true;
1174 }
1175 
1177  const IFMapPerClientNodesShowReq *request,
1178  const RequestPipeline::PipeSpec ps,
1179  IFMapPerClientNodesShowResp *response) {
1180  const RequestPipeline::StageData *prev_stage_data = ps.GetStageData(0);
1181  const ShowIFMapPerClientNodes::ShowData &show_data =
1182  static_cast<const ShowIFMapPerClientNodes::ShowData&>
1183  (prev_stage_data->at(0));
1184 
1185  vector<IFMapPerClientNodesShowInfo> dest_buffer;
1186  dest_buffer = show_data.send_buffer;
1187 
1188  // If we have filled the buffer, set next_batch with all the values we will
1189  // need in the next round.
1190  string next_batch;
1191  IFMapSandeshContext *sctx =
1192  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1193  uint32_t page_limit = GetPageLimit(sctx);
1194  if (dest_buffer.size() == page_limit) {
1195  next_batch = request->get_client_index_or_name() + kShowIterSeparator +
1196  request->get_search_string() + kShowIterSeparator +
1197  show_data.next_table_name + kShowIterSeparator +
1198  show_data.last_node_name;
1199  }
1200 
1201  response->set_node_db(dest_buffer);
1202  response->set_next_batch(next_batch);
1203 }
1204 
1206  const RequestPipeline::PipeSpec ps,
1207  int stage, int instNum,
1208  RequestPipeline::InstData *data) {
1209  const IFMapPerClientNodesShowReq *request =
1210  static_cast<const IFMapPerClientNodesShowReq *>(ps.snhRequest_.get());
1211  IFMapPerClientNodesShowResp *response = new IFMapPerClientNodesShowResp;
1212  SendStageCommon(request, ps, response);
1213 
1214  response->set_context(request->context());
1215  response->set_more(false);
1216  response->Response();
1217  return true;
1218 }
1219 
1221  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1222  int instNum, RequestPipeline::InstData *data) {
1223  const IFMapPerClientNodesShowReqIterate *request_iterate =
1224  static_cast<const IFMapPerClientNodesShowReqIterate *>
1225  (ps.snhRequest_.get());
1226 
1227  string next_table_name;
1228  string last_node_name;
1229 
1230  IFMapPerClientNodesShowResp *response = new IFMapPerClientNodesShowResp;
1231  IFMapPerClientNodesShowReq *request = new IFMapPerClientNodesShowReq;
1232  bool success = ConvertReqIterateToReq(request_iterate, request,
1233  &next_table_name, &last_node_name);
1234  if (success) {
1235  SendStageCommon(request, ps, response);
1236  }
1237 
1238  response->set_context(request->context());
1239  response->set_more(false);
1240  response->Response();
1241 
1242  request->Release();
1243  return true;
1244 }
1245 
1246 void IFMapPerClientNodesShowReq::HandleRequest() const {
1247 
1250 
1251  // 2 stages - first: gather/read, second: send
1252 
1253  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1256  s0.instances_.push_back(0);
1257 
1258  // control-node ifmap show command task
1259  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
1261  s1.instances_.push_back(0);
1262 
1263  RequestPipeline::PipeSpec ps(this);
1264  ps.stages_ = list_of(s0)(s1)
1265  .convert_to_container\
1266  <vector<RequestPipeline::StageSpec> >();
1267  RequestPipeline rp(ps);
1268 }
1269 
1270 void IFMapPerClientNodesShowReqIterate::HandleRequest() const {
1271 
1274 
1275  // 2 stages - first: gather/read, second: send
1276 
1277  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1280  s0.instances_.push_back(0);
1281 
1282  // control-node ifmap show command task
1283  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
1285  s1.instances_.push_back(0);
1286 
1287  RequestPipeline::PipeSpec ps(this);
1288  ps.stages_ = list_of(s0)(s1)
1289  .convert_to_container\
1290  <vector<RequestPipeline::StageSpec> >();
1291  RequestPipeline rp(ps);
1292 }
1293 
1295 public:
1296  static const uint32_t kMaxElementsPerRound = 50;
1297 
1298  static int GetPageLimit(IFMapSandeshContext *sctx) {
1299  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
1300  }
1301 
1302  static bool HandleRequest(const Sandesh *sr,
1303  const RequestPipeline::PipeSpec ps,
1304  int stage, int instNum,
1306  static bool HandleRequestIterate(const Sandesh *sr,
1307  const RequestPipeline::PipeSpec ps,
1308  int stage, int instNum,
1310  static bool ConvertReqIterateToReq(
1311  const IFMapPerClientLinksShowReqIterate *req_iterate,
1312  IFMapPerClientLinksShowReq *req, string *last_node_name);
1313  static bool SkipLink(IFMapLink *src, const string &search_string);
1314  static bool CopyNode(IFMapPerClientLinksShowInfo *dest, IFMapLink *src,
1315  IFMapServer *server, int client_index);
1316  static void BufferTable(const IFMapPerClientLinksShowReq *request,
1317  const string &last_link_name,
1318  IFMapPerClientLinksShowResp *response);
1319 };
1320 
1321 bool ShowIFMapPerClientLinkTable::CopyNode(IFMapPerClientLinksShowInfo *dest,
1322  IFMapLink *src, IFMapServer *server,
1323  int client_index) {
1324  IFMapLinkState *state = server->exporter()->LinkStateLookup(src);
1325 
1326  if (state && state->interest().test(client_index)) {
1327  dest->metadata = src->metadata();
1328  dest->left = src->left()->ToString();
1329  dest->right = src->right()->ToString();
1330  if (state->advertised().test(client_index)) {
1331  dest->sent = "Yes";
1332  } else {
1333  dest->sent = "No";
1334  }
1335  if (server->exporter()->ClientHasConfigTracker(
1336  IFMapExporter::INTEREST, client_index)) {
1337  if (server->exporter()->ClientConfigTrackerHasState(
1338  IFMapExporter::INTEREST, client_index, state)) {
1339  dest->interest_tracked = "Yes";
1340  } else {
1341  dest->interest_tracked = "No";
1342  }
1343  } else {
1344  dest->interest_tracked = "No tracker";
1345  }
1346  if (server->exporter()->ClientHasConfigTracker(
1347  IFMapExporter::ADVERTISED, client_index)) {
1348  if (server->exporter()->ClientConfigTrackerHasState(
1349  IFMapExporter::ADVERTISED, client_index, state)) {
1350  dest->advertised_tracked = "Yes";
1351  } else {
1352  dest->advertised_tracked = "No";
1353  }
1354  } else {
1355  dest->advertised_tracked = "No tracker";
1356  }
1357  return true;
1358  } else {
1359  return false;
1360  }
1361 }
1362 
1364  const string &search_string) {
1365  if (search_string.empty()) {
1366  return false;
1367  }
1368  IFMapNode *left = src_link->left();
1369  IFMapNode *right = src_link->right();
1370  // If we do not find the search string in the metadata or the names of
1371  // either of the 2 ends, skip the src_link.
1372  if ((src_link->metadata().find(search_string) == string::npos) &&
1373  (!left || (left->ToString().find(search_string) == string::npos)) &&
1374  (!right || (right->ToString().find(search_string) == string::npos))) {
1375  return true;
1376  }
1377  return false;
1378 }
1379 
1380 // Format of node_info string:
1381 // client_index_or_name||search_string||last_node_name
1382 // client_index_or_name: original input
1383 // search_string: original input; can be empty
1384 // last_node_name: name of last node that was printed in the previous round
1386  const IFMapPerClientLinksShowReqIterate *req_iterate,
1387  IFMapPerClientLinksShowReq *req, string *last_node_name) {
1388  // First, set the context from the original request since we might return
1389  // due to parsing errors.
1390  req->set_context(req_iterate->context());
1391 
1392  string node_info = req_iterate->get_link_info();
1393  size_t sep_size = kShowIterSeparator.size();
1394 
1395  // client_index_or_name
1396  size_t pos1 = node_info.find(kShowIterSeparator);
1397  if (pos1 == string::npos) {
1398  return false;
1399  }
1400  string client_index_or_name = node_info.substr(0, pos1);
1401 
1402  // search_string
1403  size_t pos2 = node_info.find(kShowIterSeparator, (pos1 + sep_size));
1404  if (pos2 == string::npos) {
1405  return false;
1406  }
1407  string search_string = node_info.substr((pos1 + sep_size),
1408  pos2 - (pos1 + sep_size));
1409 
1410  // last_node_name
1411  *last_node_name = node_info.substr(pos2 + sep_size);
1412 
1413  // Fill up the fields of IFMapTableShowReq appropriately.
1414  req->set_client_index_or_name(client_index_or_name);
1415  req->set_search_string(search_string);
1416  return true;
1417 }
1418 
1420  const IFMapPerClientLinksShowReq *request, const string &last_link_name,
1421  IFMapPerClientLinksShowResp *response) {
1422  IFMapSandeshContext *sctx =
1423  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1424 
1425  string client_index_or_name = request->get_client_index_or_name();
1426  if (client_index_or_name.empty()) {
1427  return;
1428  }
1429  // The user gives us either a name or an index. If the input is not a
1430  // number, find the client's index using its name. If we cant find it,
1431  // we cant process this request. If we have the index, continue processing.
1432  int client_index;
1433  if (!stringToInteger(client_index_or_name, client_index)) {
1434  if (!sctx->ifmap_server()->ClientNameToIndex(client_index_or_name,
1435  &client_index)) {
1436  return;
1437  }
1438  }
1439 
1440  IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
1441  sctx->ifmap_server()->database()->FindTable("__ifmap_metadata__.0"));
1442 
1443  uint32_t page_limit = GetPageLimit(sctx);
1444  if (table) {
1445  vector<IFMapPerClientLinksShowInfo> dest_buffer;
1446  dest_buffer.reserve(page_limit);
1447 
1448  DBEntryBase *src = NULL;
1449  DBTablePartBase *partition = table->GetTablePartition(0);
1450  if (last_link_name.length()) {
1451  src = table->FindNextLink(last_link_name);
1452  } else {
1453  src = partition->GetFirst();
1454  }
1455  for (; src != NULL; src = partition->GetNext(src)) {
1456  IFMapLink *src_link = static_cast<IFMapLink *>(src);
1457  if (SkipLink(src_link, request->get_search_string())) {
1458  continue;
1459  }
1460  IFMapPerClientLinksShowInfo dest;
1461  bool send = CopyNode(&dest, src_link, sctx->ifmap_server(),
1462  client_index);
1463  if (send) {
1464  dest_buffer.push_back(dest);
1465  if (dest_buffer.size() == page_limit) {
1466  string next_batch = request->get_client_index_or_name() +
1467  kShowIterSeparator + request->get_search_string() +
1468  kShowIterSeparator + src_link->link_name();
1469  response->set_next_batch(next_batch);
1470  break;
1471  }
1472  }
1473  }
1474  response->set_link_db(dest_buffer);
1475  } else {
1476  IFMAP_WARN(IFMapTblNotFound, "Cant show/find ", "link table");
1477  }
1478 }
1479 
1481  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1482  int instNum, RequestPipeline::InstData *data) {
1483  const IFMapPerClientLinksShowReq *request =
1484  static_cast<const IFMapPerClientLinksShowReq *>(ps.snhRequest_.get());
1485 
1486  string last_link_name;
1487  IFMapPerClientLinksShowResp *response = new IFMapPerClientLinksShowResp();
1488  BufferTable(request, last_link_name, response);
1489 
1490  response->set_context(request->context());
1491  response->set_more(false);
1492  response->Response();
1493 
1494  // Return 'true' so that we are not called again
1495  return true;
1496 }
1497 
1499  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1500  int instNum, RequestPipeline::InstData *data) {
1501  const IFMapPerClientLinksShowReqIterate *request_iterate =
1502  static_cast<const IFMapPerClientLinksShowReqIterate *>
1503  (ps.snhRequest_.get());
1504 
1505  string last_link_name;
1506  IFMapPerClientLinksShowReq *request = new IFMapPerClientLinksShowReq();
1507  IFMapPerClientLinksShowResp *response = new IFMapPerClientLinksShowResp();
1508  bool success = ConvertReqIterateToReq(request_iterate, request,
1509  &last_link_name);
1510  if (success) {
1511  BufferTable(request, last_link_name, response);
1512  }
1513 
1514  response->set_context(request->context());
1515  response->set_more(false);
1516  response->Response();
1517 
1518  request->Release();
1519  // Return 'true' so that we are not called again
1520  return true;
1521 }
1522 
1523 void IFMapPerClientLinksShowReq::HandleRequest() const {
1526 
1527  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1529  s0.instances_.push_back(0);
1530 
1531  RequestPipeline::PipeSpec ps(this);
1532  ps.stages_ = list_of(s0)
1533  .convert_to_container\
1534  <vector<RequestPipeline::StageSpec> >();
1535  RequestPipeline rp(ps);
1536 }
1537 
1538 void IFMapPerClientLinksShowReqIterate::HandleRequest() const {
1541 
1542  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1544  s0.instances_.push_back(0);
1545 
1546  RequestPipeline::PipeSpec ps(this);
1547  ps.stages_ = list_of(s0)
1548  .convert_to_container\
1549  <vector<RequestPipeline::StageSpec> >();
1550  RequestPipeline rp(ps);
1551 }
1552 
1554 public:
1555  static const int kMaxElementsPerRound = 50;
1556 
1557  static int GetPageLimit(IFMapSandeshContext *sctx) {
1558  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
1559  }
1560 
1561  static bool ProcessRequestCommon(const IFMapUuidToNodeMappingReq *req,
1562  const string &last_uuid);
1563 
1564  static bool ProcessRequest(
1565  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1566  int instNum, RequestPipeline::InstData *data);
1567 
1568  static bool ProcessRequestIterate(
1569  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1570  int instNum, RequestPipeline::InstData *data);
1571 };
1572 
1574  const IFMapUuidToNodeMappingReq *req, const string &last_uuid) {
1575  IFMapSandeshContext *sctx =
1576  static_cast<IFMapSandeshContext *>(req->module_context("IFMap"));
1577  uint32_t page_limit = GetPageLimit(sctx);
1578  IFMapVmUuidMapper *mapper = sctx->ifmap_server()->vm_uuid_mapper();
1579  IFMapUuidMapper &uuid_mapper = mapper->uuid_mapper_;
1580 
1581  vector<IFMapUuidToNodeMappingEntry> dest_buffer;
1582  IFMapUuidMapper::UuidNodeMap::const_iterator iter;
1583  if (last_uuid.size()) {
1584  iter = uuid_mapper.uuid_node_map_.upper_bound(last_uuid);
1585  } else {
1586  iter = uuid_mapper.uuid_node_map_.begin();
1587  }
1588  for (uint32_t iter_count = 0; (iter_count != page_limit) &&
1589  (iter != uuid_mapper.uuid_node_map_.end()); iter++, iter_count++) {
1590  IFMapUuidToNodeMappingEntry dest;
1591  dest.set_uuid(iter->first);
1592  IFMapNode *node = static_cast<IFMapNode *>(iter->second);
1593  dest.set_node_name(node->ToString());
1594  dest_buffer.push_back(dest);
1595  }
1596 
1597  IFMapUuidToNodeMappingResp *response = new IFMapUuidToNodeMappingResp();
1598  response->set_map_count(dest_buffer.size());
1599  response->set_uuid_to_node_map(dest_buffer);
1600  if (iter++ != uuid_mapper.uuid_node_map_.end()) {
1601  response->set_next_batch(dest_buffer.back().get_uuid());
1602  }
1603  response->set_context(req->context());
1604  response->set_more(false);
1605  response->Response();
1606  return true;
1607 }
1608 
1610  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1611  int instNum, RequestPipeline::InstData *data) {
1612  const IFMapUuidToNodeMappingReqIterate *request_iterate =
1613  static_cast<const IFMapUuidToNodeMappingReqIterate *>
1614  (ps.snhRequest_.get());
1615  IFMapUuidToNodeMappingReq *request = new IFMapUuidToNodeMappingReq;
1616  request->set_context(request_iterate->context());
1617  string last_uuid = request_iterate->get_uuid_info();
1618  ProcessRequestCommon(request, last_uuid);
1619  request->Release();
1620  return true;
1621 }
1622 
1624  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1625  int instNum, RequestPipeline::InstData *data) {
1626  const IFMapUuidToNodeMappingReq *request =
1627  static_cast<const IFMapUuidToNodeMappingReq *>(ps.snhRequest_.get());
1628  string last_uuid;
1629  ProcessRequestCommon(request, last_uuid);
1630  return true;
1631 }
1632 
1633 
1634 void IFMapUuidToNodeMappingReq::HandleRequest() const {
1635 
1638 
1639  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1641  s0.instances_.push_back(0);
1642 
1643  RequestPipeline::PipeSpec ps(this);
1644  ps.stages_ = boost::assign::list_of(s0)
1645  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1646  RequestPipeline rp(ps);
1647 }
1648 
1649 void IFMapUuidToNodeMappingReqIterate::HandleRequest() const {
1650 
1653 
1654  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1656  s0.instances_.push_back(0);
1657 
1658  RequestPipeline::PipeSpec ps(this);
1659  ps.stages_ = boost::assign::list_of(s0)
1660  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1661  RequestPipeline rp(ps);
1662 }
1663 
1665 public:
1666  static const int kMaxElementsPerRound = 50;
1667 
1668  static int GetPageLimit(IFMapSandeshContext *sctx) {
1669  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
1670  }
1671 
1672  static bool ProcessRequestCommon(const IFMapNodeToUuidMappingReq *req,
1673  const string &last_uuid);
1674 
1675  static bool ProcessRequest(
1676  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1677  int instNum, RequestPipeline::InstData *data);
1678 
1679  static bool ProcessRequestIterate(
1680  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1681  int instNum, RequestPipeline::InstData *data);
1682 };
1683 
1685  const IFMapNodeToUuidMappingReq *req, const string &last_uuid) {
1686  IFMapSandeshContext *sctx =
1687  static_cast<IFMapSandeshContext *>(req->module_context("IFMap"));
1688  uint32_t page_limit = GetPageLimit(sctx);
1689 
1690  IFMapVmUuidMapper *mapper = sctx->ifmap_server()->vm_uuid_mapper();
1691 
1692  vector<IFMapNodeToUuidMappingEntry> dest_buffer;
1693  IFMapVmUuidMapper::NodeUuidMap::const_iterator iter;
1694  if (last_uuid.size()) {
1695  IFMapNode *vm = mapper->GetVmNodeByUuid(last_uuid);
1696  iter = mapper->node_uuid_map_.upper_bound(vm);
1697  } else {
1698  iter = mapper->node_uuid_map_.begin();
1699  }
1700  IFMapNode *node;
1701  for (uint32_t iter_count = 0; (iter_count != page_limit) &&
1702  (iter != mapper->node_uuid_map_.end()); iter++, iter_count++) {
1703  IFMapNodeToUuidMappingEntry dest;
1704  node = static_cast<IFMapNode *>(iter->first);
1705  dest.set_node_name(node->ToString());
1706  dest.set_uuid(iter->second);
1707  dest_buffer.push_back(dest);
1708  }
1709  IFMapNodeToUuidMappingResp *response = new IFMapNodeToUuidMappingResp();
1710  response->set_map_count(dest_buffer.size());
1711  response->set_node_to_uuid_map(dest_buffer);
1712  if (iter != mapper->node_uuid_map_.end()) {
1713  string next_batch = iter->second;
1714  response->set_next_batch(next_batch);
1715  }
1716  response->set_context(req->context());
1717  response->set_more(false);
1718  response->Response();
1719  return true;
1720 }
1721 
1723  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1724  int instNum, RequestPipeline::InstData *data) {
1725  const IFMapNodeToUuidMappingReqIterate *request_iterate =
1726  static_cast<const IFMapNodeToUuidMappingReqIterate
1727  *>(ps.snhRequest_.get());
1728  IFMapNodeToUuidMappingReq *request = new IFMapNodeToUuidMappingReq;
1729  request->set_context(request_iterate->context());
1730  string last_uuid = request_iterate->get_uuid_info();
1731  ProcessRequestCommon(request, last_uuid);
1732  request->Release();
1733  return true;
1734 }
1735 
1737  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1738  int instNum, RequestPipeline::InstData *data) {
1739  const IFMapNodeToUuidMappingReq *request =
1740  static_cast<const IFMapNodeToUuidMappingReq *>(ps.snhRequest_.get());
1741  string last_uuid;
1742  ProcessRequestCommon(request, last_uuid);
1743  return true;
1744 }
1745 
1746 void IFMapNodeToUuidMappingReq::HandleRequest() const {
1747 
1750 
1751  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1753  s0.instances_.push_back(0);
1754 
1755  RequestPipeline::PipeSpec ps(this);
1756  ps.stages_ = boost::assign::list_of(s0)
1757  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1758  RequestPipeline rp(ps);
1759 }
1760 
1761 void IFMapNodeToUuidMappingReqIterate::HandleRequest() const {
1762 
1765 
1766  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1768  s0.instances_.push_back(0);
1769 
1770  RequestPipeline::PipeSpec ps(this);
1771  ps.stages_ = boost::assign::list_of(s0)
1772  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1773  RequestPipeline rp(ps);
1774 }
1775 
1777 public:
1778  static const int kMaxElementsPerRound = 50;
1779 
1780  static int GetPageLimit(IFMapSandeshContext *sctx) {
1781  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
1782  }
1783 
1785  vector<IFMapPendingVmRegEntry> send_buffer;
1786  };
1787 
1789  return static_cast<RequestPipeline::InstData *>(new ShowData);
1790  }
1791 
1793  // init as 1 indicates we need to init 'first' to begin() since there is
1794  // no way to initialize an iterator here.
1795  TrackerData() : init(1) { }
1796  int init;
1797  vector<IFMapPendingVmRegEntry>::const_iterator first;
1798  };
1799 
1801  return static_cast<RequestPipeline::InstData *>(new TrackerData);
1802  }
1803 
1804  static bool BufferStage(const Sandesh *sr,
1805  const RequestPipeline::PipeSpec ps, int stage,
1806  int instNum, RequestPipeline::InstData *data);
1807  static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps,
1808  int stage, int instNum,
1810 };
1811 
1813  const RequestPipeline::PipeSpec ps,
1814  int stage, int instNum,
1815  RequestPipeline::InstData *data) {
1816  const IFMapPendingVmRegReq *request =
1817  static_cast<const IFMapPendingVmRegReq *>(ps.snhRequest_.get());
1818  IFMapSandeshContext *sctx =
1819  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1820  ShowData *show_data = static_cast<ShowData *>(data);
1821 
1822  IFMapVmUuidMapper *mapper = sctx->ifmap_server()->vm_uuid_mapper();
1823 
1824  show_data->send_buffer.reserve(mapper->PendingVmRegCount());
1825  for (IFMapVmUuidMapper::PendingVmRegMap::const_iterator iter =
1826  mapper->pending_vmreg_map_.begin();
1827  iter != mapper->pending_vmreg_map_.end(); ++iter) {
1828  IFMapPendingVmRegEntry dest;
1829  dest.set_vm_uuid(iter->first);
1830  dest.set_vr_name(iter->second);
1831  show_data->send_buffer.push_back(dest);
1832  }
1833 
1834  return true;
1835 }
1836 
1837 // Can be called multiple times i.e. approx total/kMaxElementsPerRound
1839  const RequestPipeline::PipeSpec ps,
1840  int stage, int instNum,
1841  RequestPipeline::InstData *data) {
1842  const RequestPipeline::StageData *prev_stage_data = ps.GetStageData(0);
1843  const ShowIFMapPendingVmReg::ShowData &show_data =
1844  static_cast<const ShowIFMapPendingVmReg::ShowData&>
1845  (prev_stage_data->at(0));
1846  // Data for this stage
1847  TrackerData *tracker_data = static_cast<TrackerData *>(data);
1848 
1849  vector<IFMapPendingVmRegEntry> dest_buffer;
1850  vector<IFMapPendingVmRegEntry>::const_iterator first, last;
1851  bool more = false;
1852 
1853  if (tracker_data->init) {
1854  first = show_data.send_buffer.begin();
1855  tracker_data->init = 0;
1856  } else {
1857  first = tracker_data->first;
1858  }
1859  int rem_num = show_data.send_buffer.end() - first;
1860  const IFMapPendingVmRegReq *request =
1861  static_cast<const IFMapPendingVmRegReq *>(ps.snhRequest_.get());
1862  IFMapSandeshContext *sctx =
1863  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1864  uint32_t page_limit = GetPageLimit(sctx);
1865  int send_num = (rem_num < (int)page_limit) ? rem_num : (int)page_limit;
1866  last = first + send_num;
1867  copy(first, last, back_inserter(dest_buffer));
1868  // Decide if we want to be called again.
1869  if ((rem_num - send_num) > 0) {
1870  more = true;
1871  } else {
1872  more = false;
1873  }
1874  IFMapPendingVmRegResp *response = new IFMapPendingVmRegResp();
1875  response->set_map_count(dest_buffer.size());
1876  response->set_vm_reg_map(dest_buffer);
1877  response->set_context(request->context());
1878  response->set_more(more);
1879  response->Response();
1880  tracker_data->first = first + send_num;
1881 
1882  // Return 'false' to be called again
1883  return (!more);
1884 }
1885 
1886 void IFMapPendingVmRegReq::HandleRequest() const {
1887 
1890 
1891  // 2 stages - first: gather/read, second: send
1892 
1893  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1896  s0.instances_.push_back(0);
1897 
1898  // control-node ifmap show command task
1899  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
1902  s1.instances_.push_back(0);
1903 
1904  RequestPipeline::PipeSpec ps(this);
1905  ps.stages_ = list_of(s0)(s1)
1906  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1907  RequestPipeline rp(ps);
1908 }
1909 
1911  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1912  int instNum, RequestPipeline::InstData *data) {
1913  const IFMapServerClientShowReq *request =
1914  static_cast<const IFMapServerClientShowReq *>(ps.snhRequest_.get());
1915  IFMapSandeshContext *sctx =
1916  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1917 
1918  IFMapServerClientShowResp *response = new IFMapServerClientShowResp();
1919  string search_string = request->get_search_string();
1920 
1921  IFMapServerShowClientMap name_list;
1922  sctx->ifmap_server()->FillClientMap(&name_list, search_string);
1923  IFMapServerShowIndexMap index_list;
1924  sctx->ifmap_server()->FillIndexMap(&index_list, search_string);
1925  IFMapServerClientHistoryList history_list;
1926  sctx->ifmap_server()->FillClientHistory(&history_list, search_string);
1927 
1928  response->set_name_list(name_list);
1929  response->set_index_list(index_list);
1930  response->set_history_list(history_list);
1931  response->set_context(request->context());
1932  response->set_more(false);
1933  response->Response();
1934 
1935  // Return 'true' so that we are not called again
1936  return true;
1937 }
1938 
1939 void IFMapServerClientShowReq::HandleRequest() const {
1940 
1943 
1944  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1946  s0.instances_.push_back(0);
1947 
1948  RequestPipeline::PipeSpec ps(this);
1949  ps.stages_ = boost::assign::list_of(s0)
1950  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1951  RequestPipeline rp(ps);
1952 }
1953 
1955  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
1956  int instNum, RequestPipeline::InstData *data) {
1957  const IFMapNodeTableListShowReq *request =
1958  static_cast<const IFMapNodeTableListShowReq *>(ps.snhRequest_.get());
1959  IFMapSandeshContext *sctx =
1960  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
1961 
1962  vector<IFMapNodeTableListShowEntry> dest_buffer;
1964  &dest_buffer);
1965 
1966  IFMapNodeTableListShowResp *response = new IFMapNodeTableListShowResp();
1967  response->set_table_list(dest_buffer);
1968  response->set_context(request->context());
1969  response->set_more(false);
1970  response->Response();
1971 
1972  // Return 'true' so that we are not called again
1973  return true;
1974 }
1975 
1976 void IFMapNodeTableListShowReq::HandleRequest() const {
1977 
1980 
1981  s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
1983  s0.instances_.push_back(0);
1984 
1985  RequestPipeline::PipeSpec ps(this);
1986  ps.stages_ = boost::assign::list_of(s0)
1987  .convert_to_container<vector<RequestPipeline::StageSpec> >();
1988  RequestPipeline rp(ps);
1989 }
1990 
1992 public:
1993  static const uint32_t kMaxElementsPerRound = 50;
1994 
1995  static int GetPageLimit(IFMapSandeshContext *sctx) {
1996  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
1997  }
1998 
2000  vector<ConfigDBUUIDCacheEntry> send_buffer;
2001  };
2002 
2004  return static_cast<RequestPipeline::InstData *>(new ShowData);
2005  }
2006 
2007  static bool BufferStageCommon(const ConfigDBUUIDCacheReq *request,
2008  int instNum, RequestPipeline::InstData *data,
2009  const string &last_uuid);
2010  static bool BufferStage(const Sandesh *sr,
2011  const RequestPipeline::PipeSpec ps, int stage,
2012  int instNum, RequestPipeline::InstData *data);
2013  static bool BufferStageIterate(const Sandesh *sr,
2014  const RequestPipeline::PipeSpec ps, int stage,
2015  int instNum, RequestPipeline::InstData *data);
2016  static void SendStageCommon(const ConfigDBUUIDCacheReq *request,
2017  const RequestPipeline::PipeSpec ps,
2018  ConfigDBUUIDCacheResp *response);
2019  static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps,
2020  int stage, int instNum,
2022  static bool SendStageIterate(const Sandesh *sr,
2023  const RequestPipeline::PipeSpec ps, int stage,
2024  int instNum, RequestPipeline::InstData *data);
2025  static bool SortList(const ConfigDBUUIDCacheEntry &lhs,
2026  const ConfigDBUUIDCacheEntry &rhs);
2027  static bool ConvertReqIterateToReq(
2028  const ConfigDBUUIDCacheReqIterate *req_iterate,
2029  ConfigDBUUIDCacheReq *req, string *last_uuid);
2030 };
2031 
2033  const ConfigDBUUIDCacheEntry &lhs,
2034  const ConfigDBUUIDCacheEntry &rhs) {
2035  BOOL_KEY_COMPARE(lhs.uuid, rhs.uuid);
2036  return false;
2037 }
2038 
2039 // Format of uuid_info string:
2040 // search_string||last_uuid
2041 // search_string: original input. Could be empty.
2042 // last_uuid : uuid of last UUIDToFQName entry that was printed in the
2043 // previous round
2045  const ConfigDBUUIDCacheReqIterate *req_iterate,
2046  ConfigDBUUIDCacheReq *req, string *last_uuid) {
2047  // First, set the context from the original request since we might return
2048  // due to parsing errors.
2049  req->set_context(req_iterate->context());
2050 
2051  string uuid_info = req_iterate->get_uuid_info();
2052  size_t sep_size = kShowIterSeparator.size();
2053 
2054  // search_string
2055  size_t pos1 = uuid_info.find(kShowIterSeparator);
2056  if (pos1 == string::npos) {
2057  return false;
2058  }
2059  string search_string = uuid_info.substr(0, pos1);
2060 
2061  // last_uuid
2062  *last_uuid = uuid_info.substr((pos1 + sep_size));
2063 
2064  // Fill up the fields of ConfigDBUUIDCacheReq appropriately.
2065  req->set_search_string(search_string);
2066  return true;
2067 }
2068 
2069 
2071  const ConfigDBUUIDCacheReq *req, int instNum,
2072  RequestPipeline::InstData *data, const string &last_uuid) {
2073  IFMapSandeshContext *sctx =
2074  static_cast<IFMapSandeshContext *>(req->module_context("IFMap"));
2076  ShowData *show_data = static_cast<ShowData *>(data);
2077  uint32_t page_limit = GetPageLimit(sctx);
2078  show_data->send_buffer.reserve(page_limit);
2079  ccmgr->config_db_client()->UUIDToObjCacheShow(req->get_search_string(),
2080  instNum,
2081  last_uuid, page_limit,
2082  &show_data->send_buffer);
2083  return true;
2084 }
2085 
2087  const RequestPipeline::PipeSpec ps,
2088  int stage, int instNum,
2089  RequestPipeline::InstData *data) {
2090  const ConfigDBUUIDCacheReq *request =
2091  static_cast<const ConfigDBUUIDCacheReq *>(ps.snhRequest_.get());
2092  string last_uuid;
2093  return BufferStageCommon(request, instNum, data, last_uuid);
2094 }
2095 
2097  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
2098  int instNum, RequestPipeline::InstData *data) {
2099  const ConfigDBUUIDCacheReqIterate *request_iterate =
2100  static_cast<const ConfigDBUUIDCacheReqIterate *>(ps.snhRequest_.get());
2101 
2102  ConfigDBUUIDCacheReq *request = new ConfigDBUUIDCacheReq;
2103  string last_uuid;
2104  bool success = ConvertReqIterateToReq(request_iterate, request,
2105  &last_uuid);
2106  if (success) {
2107  BufferStageCommon(request, instNum, data, last_uuid);
2108  }
2109  request->Release();
2110  return true;
2111 }
2112 
2113 void ShowConfigDBUUIDCache::SendStageCommon(const ConfigDBUUIDCacheReq *request,
2114  const RequestPipeline::PipeSpec ps,
2115  ConfigDBUUIDCacheResp *response) {
2116  const RequestPipeline::StageData *prev_stage_data = ps.GetStageData(0);
2117 
2118  vector<ConfigDBUUIDCacheEntry> uuid_cache_list;
2119  for (size_t i = 0; i < prev_stage_data->size(); ++i) {
2120  const ShowConfigDBUUIDCache::ShowData &show_data = static_cast
2121  <const ShowConfigDBUUIDCache::ShowData&>(prev_stage_data->at(i));
2122  if (show_data.send_buffer.size()) {
2123  size_t list_size = uuid_cache_list.size();
2124  uuid_cache_list.reserve(list_size + show_data.send_buffer.size());
2125  copy(show_data.send_buffer.begin(),
2126  show_data.send_buffer.end(),
2127  std::back_inserter(uuid_cache_list));
2128  if (list_size) {
2129  std::inplace_merge(uuid_cache_list.begin(),
2130  uuid_cache_list.begin() + list_size,
2131  uuid_cache_list.end(),
2133  }
2134  }
2135  }
2136 
2137  // If we have filled the buffer, set next_batch with all the values we will
2138  // need in the next round.
2139  string next_batch;
2140  IFMapSandeshContext *sctx =
2141  static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
2142  uint32_t page_limit = GetPageLimit(sctx);
2143  if (uuid_cache_list.size() > page_limit) {
2144  vector<ConfigDBUUIDCacheEntry> ouput_list(uuid_cache_list.begin(),
2145  uuid_cache_list.begin()
2146  + page_limit);
2147  response->set_uuid_cache(ouput_list);
2148  next_batch = request->get_search_string() + kShowIterSeparator
2149  + ouput_list.back().uuid;
2150  } else {
2151  response->set_uuid_cache(uuid_cache_list);
2152  }
2153 
2154  response->set_next_batch(next_batch);
2155 }
2156 
2158  const RequestPipeline::PipeSpec ps,
2159  int stage, int instNum,
2160  RequestPipeline::InstData *data) {
2161  const ConfigDBUUIDCacheReq *request =
2162  static_cast<const ConfigDBUUIDCacheReq *>(ps.snhRequest_.get());
2163  ConfigDBUUIDCacheResp *response = new ConfigDBUUIDCacheResp;
2164  SendStageCommon(request, ps, response);
2165  response->set_context(request->context());
2166  response->set_more(false);
2167  response->Response();
2168  return true;
2169 }
2170 
2172  const RequestPipeline::PipeSpec ps,
2173  int stage, int instNum,
2174  RequestPipeline::InstData *data) {
2175  const ConfigDBUUIDCacheReqIterate *request_iterate =
2176  static_cast<const ConfigDBUUIDCacheReqIterate *>(ps.snhRequest_.get());
2177 
2178  ConfigDBUUIDCacheResp *response = new ConfigDBUUIDCacheResp;
2179  ConfigDBUUIDCacheReq *request = new ConfigDBUUIDCacheReq;
2180  string last_uuid;
2181  bool success = ConvertReqIterateToReq(request_iterate, request,
2182  &last_uuid);
2183  if (success) {
2184  SendStageCommon(request, ps, response);
2185  }
2186 
2187  response->set_context(request->context());
2188  response->set_more(false);
2189  response->Response();
2190 
2191  request->Release();
2192  return true;
2193 }
2194 
2195 void ConfigDBUUIDCacheReq::HandleRequest() const {
2196 
2199 
2200  // 2 stages - first: gather/read, second: send
2201 
2202  s0.taskId_ = scheduler->GetTaskId("config_client::Reader");
2205  for (int i = 0; i < ConfigClientManager::GetNumConfigReader(); ++i) {
2206  s0.instances_.push_back(i);
2207  }
2208 
2209  // control-node ifmap show command task
2210  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
2212  s1.instances_.push_back(0);
2213 
2214  RequestPipeline::PipeSpec ps(this);
2215  ps.stages_ = list_of(s0)(s1)
2216  .convert_to_container<vector<RequestPipeline::StageSpec> >();
2217  RequestPipeline rp(ps);
2218 }
2219 
2220 void ConfigDBUUIDCacheReqIterate::HandleRequest() const {
2221 
2224 
2225  // 2 stages - first: gather/read, second: send
2226 
2227  s0.taskId_ = scheduler->GetTaskId("config_client::Reader");
2230  for (int i = 0; i < ConfigClientManager::GetNumConfigReader(); ++i) {
2231  s0.instances_.push_back(i);
2232  }
2233 
2234  // control-node ifmap show command task
2235  s1.taskId_ = scheduler->GetTaskId("ifmap::ShowCommandSendStage");
2237  s1.instances_.push_back(0);
2238 
2239  RequestPipeline::PipeSpec ps(this);
2240  ps.stages_ = list_of(s0)(s1)
2241  .convert_to_container\
2242  <vector<RequestPipeline::StageSpec> >();
2243  RequestPipeline rp(ps);
2244 }
2245 
2247 public:
2248  static const int kMaxElementsPerRound = 50;
2249 
2250  static int GetPageLimit(IFMapSandeshContext *sctx) {
2251  return (sctx->page_limit() ? sctx->page_limit() : kMaxElementsPerRound);
2252  }
2253 
2254  static bool ProcessRequestCommon(const ConfigDBUUIDToFQNameReq *req,
2255  const string &last_uuid);
2256 
2257  static bool ProcessRequest(
2258  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
2259  int instNum, RequestPipeline::InstData *data);
2260 
2261  static bool ProcessRequestIterate(
2262  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
2263  int instNum, RequestPipeline::InstData *data);
2264 
2265  static bool ConvertReqIterateToReq(
2266  const ConfigDBUUIDToFQNameReqIterate *req_iterate,
2267  ConfigDBUUIDToFQNameReq *req, string *last_uuid);
2268 };
2269 
2270 // Format of uuid_info string:
2271 // search_string||last_uuid
2272 // search_string: original input. Could be empty.
2273 // last_uuid : uuid of last UUIDToFQName entry that was printed in the
2274 // previous round
2276  const ConfigDBUUIDToFQNameReqIterate *req_iterate,
2277  ConfigDBUUIDToFQNameReq *req, string *last_uuid) {
2278  // First, set the context from the original request since we might return
2279  // due to parsing errors.
2280  req->set_context(req_iterate->context());
2281 
2282  string uuid_info = req_iterate->get_uuid_info();
2283  size_t sep_size = kShowIterSeparator.size();
2284 
2285  // search_string
2286  size_t pos1 = uuid_info.find(kShowIterSeparator);
2287  if (pos1 == string::npos) {
2288  return false;
2289  }
2290  string search_string = uuid_info.substr(0, pos1);
2291 
2292  // last_uuid
2293  *last_uuid = uuid_info.substr((pos1 + sep_size));
2294 
2295  // Fill up the fields of ConfigDBUUIDToFQNameReq appropriately.
2296  req->set_search_string(search_string);
2297  return true;
2298 }
2299 
2301  const ConfigDBUUIDToFQNameReq *req, const string &last_uuid) {
2302  IFMapSandeshContext *sctx =
2303  static_cast<IFMapSandeshContext *>(req->module_context("IFMap"));
2304  uint32_t page_limit = GetPageLimit(sctx);
2306  vector<ConfigDBFQNameCacheEntry> dest_buffer;
2307  bool more = ccmgr->config_db_client()->UUIDToFQNameShow(
2308  req->get_search_string(), last_uuid, page_limit, &dest_buffer);
2309  string next_batch;
2310  ConfigDBUUIDToFQNameResp *response = new ConfigDBUUIDToFQNameResp();
2311  if (more) {
2312  next_batch = req->get_search_string()
2313  + kShowIterSeparator + dest_buffer.back().get_uuid();
2314  }
2315  response->set_fqname_cache(dest_buffer);
2316  response->set_next_batch(next_batch);
2317  response->set_context(req->context());
2318  response->set_more(false);
2319  response->Response();
2320  return true;
2321 }
2322 
2324  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
2325  int instNum, RequestPipeline::InstData *data) {
2326  const ConfigDBUUIDToFQNameReqIterate *request_iterate =
2327  static_cast<const ConfigDBUUIDToFQNameReqIterate
2328  *>(ps.snhRequest_.get());
2329  ConfigDBUUIDToFQNameReq *request = new ConfigDBUUIDToFQNameReq;
2330  string last_uuid;
2331  bool success = ConvertReqIterateToReq(request_iterate, request,
2332  &last_uuid);
2333  if (success) {
2334  ProcessRequestCommon(request, last_uuid);
2335  }
2336  request->Release();
2337  return true;
2338 }
2339 
2341  const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage,
2342  int instNum, RequestPipeline::InstData *data) {
2343  const ConfigDBUUIDToFQNameReq *request =
2344  static_cast<const ConfigDBUUIDToFQNameReq*>(ps.snhRequest_.get());
2345  string last_uuid;
2346  ProcessRequestCommon(request, last_uuid);
2347  return true;
2348 }
2349 
2350 void ConfigDBUUIDToFQNameReq::HandleRequest() const {
2351 
2354 
2355  s0.taskId_ = scheduler->GetTaskId("config_client::Reader");
2357  s0.instances_.push_back(0);
2358 
2359  RequestPipeline::PipeSpec ps(this);
2360  ps.stages_ = boost::assign::list_of(s0)
2361  .convert_to_container\
2362  <vector<RequestPipeline::StageSpec> >();
2363  RequestPipeline rp(ps);
2364 }
2365 
2366 void ConfigDBUUIDToFQNameReqIterate::HandleRequest() const {
2367 
2370 
2371  s0.taskId_ = scheduler->GetTaskId("config_client::Reader");
2373  s0.instances_.push_back(0);
2374 
2375  RequestPipeline::PipeSpec ps(this);
2376  ps.stages_ = boost::assign::list_of(s0)
2377  .convert_to_container
2378  <vector<RequestPipeline::StageSpec> >();
2379  RequestPipeline rp(ps);
2380 }
std::string ToNumberedString() const
Definition: bitset.cc:593
bool test(size_t pos) const
Definition: bitset.cc:146
ConfigDbClient * config_db_client() const
virtual bool UUIDToObjCacheShow(const std::string &search_string, int inst_num, const std::string &last_uuid, uint32_t num_entries, std::vector< ConfigDBUUIDCacheEntry > *entries) const =0
virtual bool UUIDToFQNameShow(const std::string &search_string, const std::string &last_uuid, uint32_t num_entries, std::vector< ConfigDBFQNameCacheEntry > *entries) const
const std::string last_change_at_str() const
Definition: db_entry.cc:123
bool IsOnRemoveQ()
Definition: db_entry.h:57
bool IsDeleted() const
Definition: db_entry.h:48
bool is_onlist()
Definition: db_entry.h:52
adjacency_iterator end(DBGraph *graph)
adjacency_iterator begin(DBGraph *graph)
const std::string & name() const
Definition: db_table.h:110
virtual DBEntryBase * GetNext(const DBEntryBase *)=0
virtual DBEntryBase * GetFirst()=0
virtual size_t Size() const
Definition: db_table.cc:533
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:462
Definition: db.h:24
iterator lower_bound(const std::string &name)
Definition: db.h:70
iterator end()
Definition: db.h:69
TableMap::iterator iterator
Definition: db.h:29
DBTableBase * FindTable(const std::string &name)
Definition: db.cc:68
iterator FindTableIter(const std::string &name)
Definition: db.cc:77
IFMapLinkState * LinkStateLookup(IFMapLink *link)
bool ClientConfigTrackerHasState(TrackerType tracker_type, int index, IFMapState *state)
bool ClientHasConfigTracker(TrackerType tracker_type, int index)
IFMapNodeState * NodeStateLookup(IFMapNode *node)
IFMapLink * FindNextLink(const std::string &name)
string GetIFMapObjectData(const IFMapObject *src_obj)
IFMapNodeCopier(IFMapNodeShowInfo *dest, DBEntryBase *src, IFMapServer *server)
const std::string & name() const
Definition: ifmap_node.h:48
ObjectList list_
Definition: ifmap_node.h:64
virtual std::string ToString() const
Definition: ifmap_node.cc:31
IFMapOrigin origin() const
Definition: ifmap_object.h:38
uint64_t sequence_number()
Definition: ifmap_object.h:33
virtual void EncodeUpdate(pugi::xml_node *parent) const =0
IFMapServer * ifmap_server()
uint32_t page_limit() const
void FillClientMap(IFMapServerShowClientMap *out_map, const std::string &search_string)
DB * database()
Definition: ifmap_server.h:82
ConfigClientManager * get_config_manager()
Definition: ifmap_server.h:92
IFMapExporter * exporter()
Definition: ifmap_server.h:86
IFMapVmUuidMapper * vm_uuid_mapper()
Definition: ifmap_server.h:87
void FillClientHistory(IFMapServerClientHistoryList *out_list, const std::string &search_string)
void FillIndexMap(IFMapServerShowIndexMap *out_map, const std::string &search_string)
DBGraph * graph()
Definition: ifmap_server.h:83
bool ClientNameToIndex(const std::string &id, int *index)
const BitSet & interest() const
Definition: ifmap_update.h:129
const BitSet & advertised() const
Definition: ifmap_update.h:130
static IFMapTable * FindTable(DB *db, const std::string &element_type)
Definition: ifmap_table.cc:39
IFMapNode * FindNode(const std::string &name)
Definition: ifmap_table.cc:23
static void FillNodeTableList(DB *db, std::vector< IFMapNodeTableListShowEntry > *table_list)
Definition: ifmap_table.cc:57
IFMapNode * FindNextNode(const std::string &name)
Definition: ifmap_table.cc:31
UuidNodeMap uuid_node_map_
IFMapUuidMapper uuid_mapper_
PendingVmRegMap pending_vmreg_map_
PendingVmRegMap::size_type PendingVmRegCount()
IFMapNode * GetVmNodeByUuid(const std::string &vm_uuid)
NodeUuidMap node_uuid_map_
boost::ptr_vector< InstData > StageData
static bool SortList(const ConfigDBUUIDCacheEntry &lhs, const ConfigDBUUIDCacheEntry &rhs)
static RequestPipeline::InstData * AllocBuffer(int stage)
static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static int GetPageLimit(IFMapSandeshContext *sctx)
static void SendStageCommon(const ConfigDBUUIDCacheReq *request, const RequestPipeline::PipeSpec ps, ConfigDBUUIDCacheResp *response)
static bool BufferStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ConvertReqIterateToReq(const ConfigDBUUIDCacheReqIterate *req_iterate, ConfigDBUUIDCacheReq *req, string *last_uuid)
static bool SendStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool BufferStageCommon(const ConfigDBUUIDCacheReq *request, int instNum, RequestPipeline::InstData *data, const string &last_uuid)
static bool BufferStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ProcessRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ConvertReqIterateToReq(const ConfigDBUUIDToFQNameReqIterate *req_iterate, ConfigDBUUIDToFQNameReq *req, string *last_uuid)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool ProcessRequestIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ProcessRequestCommon(const ConfigDBUUIDToFQNameReq *req, const string &last_uuid)
static bool BufferStageCommon(const IFMapLinkTableShowReq *request, RequestPipeline::InstData *data, const string &last_link_name)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool ConvertReqIterateToReq(const IFMapLinkTableShowReqIterate *req_iterate, IFMapLinkTableShowReq *req, string *last_link_name)
static bool SendStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static void CopyNode(IFMapLinkShowInfo *dest, DBEntryBase *src, IFMapServer *server)
static bool BufferStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool IncludeLink(DBEntryBase *src, const string &search_string, const regex &search_expr, const string &metadata, const regex &metadata_expr)
static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool BufferStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static RequestPipeline::InstData * AllocBuffer(int stage)
static void SendStageCommon(const IFMapLinkTableShowReq *request, const RequestPipeline::PipeSpec ps, IFMapLinkTableShowResp *response)
static bool ProcessRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ProcessRequestCommon(const IFMapNodeToUuidMappingReq *req, const string &last_uuid)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool ProcessRequestIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static RequestPipeline::InstData * AllocBuffer(int stage)
static bool BufferStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static RequestPipeline::InstData * AllocTracker(int stage)
static void BufferTable(const IFMapPerClientLinksShowReq *request, const string &last_link_name, IFMapPerClientLinksShowResp *response)
static bool HandleRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ConvertReqIterateToReq(const IFMapPerClientLinksShowReqIterate *req_iterate, IFMapPerClientLinksShowReq *req, string *last_node_name)
static bool CopyNode(IFMapPerClientLinksShowInfo *dest, IFMapLink *src, IFMapServer *server, int client_index)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool HandleRequestIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool SkipLink(IFMapLink *src, const string &search_string)
static RequestPipeline::InstData * AllocBuffer(int stage)
static bool BufferStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool CopyNode(IFMapPerClientNodesShowInfo *dest, IFMapNode *src, IFMapServer *server, int client_index)
static void SendStageCommon(const IFMapPerClientNodesShowReq *request, const RequestPipeline::PipeSpec ps, IFMapPerClientNodesShowResp *response)
static bool BufferStageCommon(const IFMapPerClientNodesShowReq *request, RequestPipeline::InstData *data, const string &next_table_name, const string &last_node_name)
static bool SendStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool TableToBuffer(const IFMapPerClientNodesShowReq *request, IFMapTable *table, IFMapServer *server, const string &last_node_name, int client_index, ShowData *show_data)
static bool BufferStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ConvertReqIterateToReq(const IFMapPerClientNodesShowReqIterate *req_iterate, IFMapPerClientNodesShowReq *req, string *next_table_name, string *last_node_name)
static bool BufferStageCommon(const IFMapTableShowReq *request, RequestPipeline::InstData *data, const string &next_table_name, const string &last_node_name)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool BufferStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static void SendStageCommon(const IFMapTableShowReq *request, const RequestPipeline::PipeSpec ps, IFMapTableShowResp *response)
static bool BufferOneTable(const IFMapTableShowReq *request, RequestPipeline::InstData *data, const string &last_node_name)
static bool BufferAllTables(const IFMapTableShowReq *req, RequestPipeline::InstData *data, const string &next_table_name, const string &last_node_name)
static bool TableToBuffer(const IFMapTableShowReq *request, IFMapTable *table, IFMapServer *server, const string &last_node_name, ShowData *show_data, uint32_t page_limit)
static RequestPipeline::InstData * AllocBuffer(int stage)
static bool ConvertReqIterateToReq(const IFMapTableShowReqIterate *req_iterate, IFMapTableShowReq *req, string *next_table_name, string *last_node_name)
static bool SendStage(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool SendStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool BufferStageIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static int GetPageLimit(IFMapSandeshContext *sctx)
static bool ProcessRequestCommon(const IFMapUuidToNodeMappingReq *req, const string &last_uuid)
static bool ProcessRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool ProcessRequestIterate(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:304
int GetTaskId(const std::string &name)
Definition: task.cc:861
static TaskScheduler * GetInstance()
Definition: task.cc:554
#define IFMAP_WARN(obj,...)
Definition: ifmap_log.h:72
const string kShowIterSeparator
static bool IFMapNodeShowReqHandleRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool IFMapNodeTableListShowReqHandleRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
static bool IFMapServerClientShowReqHandleRequest(const Sandesh *sr, const RequestPipeline::PipeSpec ps, int stage, int instNum, RequestPipeline::InstData *data)
void init()
Definition: bgp_log.cc:37
static bool regex_search(const std::string &input, const regex &regex)
Definition: regex.h:25
static bool regex_match(const std::string &input, const regex &regex)
Definition: regex.h:34
bool stringToInteger(const std::string &str, NumberType &num)
Definition: string_util.h:71
std::string ToString() const
Definition: ifmap_origin.h:22
boost::shared_ptr< const SandeshRequest > snhRequest_
const StageData * GetStageData(int stage) const
std::vector< int > instances_
vector< ConfigDBUUIDCacheEntry > send_buffer
vector< IFMapLinkShowInfo > send_buffer
vector< IFMapPendingVmRegEntry > send_buffer
vector< IFMapPendingVmRegEntry >::const_iterator first
vector< IFMapPerClientNodesShowInfo > send_buffer
vector< IFMapNodeShowInfo > send_buffer
#define BOOL_KEY_COMPARE(x, y)
Definition: util.h:64