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