LCOV - code coverage report
Current view: top level - ifmap - ifmap_server_show.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 392 1207 32.5 %
Date: 2026-06-22 02:21:21 Functions: 38 95 40.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14