LCOV - code coverage report
Current view: top level - ifmap - ifmap_xmpp.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 111 323 34.4 %
Date: 2026-11-09 02:10:49 Functions: 20 41 48.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include <sandesh/request_pipeline.h>
       7             : 
       8             : #include "ifmap/ifmap_xmpp.h"
       9             : #include <boost/foreach.hpp>
      10             : #include <boost/assign/list_of.hpp>
      11             : 
      12             : #include "base/util.h"
      13             : #include "base/logging.h"
      14             : 
      15             : #include "ifmap/ifmap_factory.h"
      16             : #include "ifmap/ifmap_log.h"
      17             : #include "ifmap/ifmap_sandesh_context.h"
      18             : #include "ifmap/ifmap_server_show_types.h"
      19             : #include "ifmap/ifmap_log_types.h"
      20             : #include "ifmap/ifmap_update_sender.h"
      21             : 
      22             : #include "xmpp/xmpp_connection.h"
      23             : #include "xmpp/xmpp_server.h"
      24             : 
      25             : const std::string IFMapXmppChannel::NoFqnSet = "NoFqnSet";
      26             : 
      27             : // There are 3 task interactions:
      28             : // "xmpp::StateMachine" gives all the channel triggers.
      29             : // "db::IFMapTable" does all the work related to those triggers - except Ready
      30             : // "bgp::Config" does the final channel-unregister
      31             : //
      32             : // "xmpp::StateMachine" task gives us 5 triggers:
      33             : // 1. Ready/NotReady indicating the channel create/delete
      34             : // 2. VR-subscribe indicating the existence of the agent
      35             : // 3. VM-sub/unsub indicating the create/delete of a virtual-machine
      36             : // Process all the triggers in the context of the db::IFMapTable task - except
      37             : // the 'ready' trigger that is processed right away.
      38             : // #1 must be processed via the IFMapChannelManager.
      39             : // #2/#3 must be processed via the IFMapXmppChannel since they are
      40             : // channel-specific
      41             : //
      42             : // "bgp::Config":
      43             : // The NotReady trigger will cleanup the channel related resources and then
      44             : // Unregister via ProcessChannelUnregister() in the context of bgp::Config.
      45             : class ChannelEventProcTask : public Task {
      46             : public:
      47             :     // To be used for #1
      48           7 :     explicit ChannelEventProcTask(const ChannelEventInfo &ev,
      49             :                                   IFMapChannelManager *mgr)
      50           7 :         : Task(TaskScheduler::GetInstance()->GetTaskId("db::IFMapTable"), 0),
      51           7 :           event_info_(ev), ifmap_channel_manager_(mgr) {
      52           7 :     }
      53             : 
      54             :     // To be used for #2/#3
      55           0 :     explicit ChannelEventProcTask(const ChannelEventInfo &ev,
      56             :                                   IFMapXmppChannel *chnl)
      57           0 :         : Task(TaskScheduler::GetInstance()->GetTaskId("db::IFMapTable"), 0),
      58           0 :           event_info_(ev), ifmap_chnl_(chnl) {
      59           0 :     }
      60             : 
      61           7 :     virtual bool Run() {
      62           7 :         if (event_info_.event == XCE_NOT_READY) {
      63           7 :             ifmap_channel_manager_->ProcessChannelNotReady(event_info_.channel);
      64           0 :         } else if (event_info_.event == XCE_VR_SUBSCRIBE) {
      65           0 :             ifmap_chnl_->ProcessVrSubscribe(event_info_.name);
      66           0 :         } else if (event_info_.event == XCE_VM_SUBSCRIBE) {
      67           0 :             ifmap_chnl_->ProcessVmSubscribe(event_info_.name);
      68           0 :         } else if (event_info_.event == XCE_VM_UNSUBSCRIBE) {
      69           0 :             ifmap_chnl_->ProcessVmUnsubscribe(event_info_.name);
      70             :         }
      71             : 
      72           7 :         return true;
      73             :     }
      74           0 :     std::string Description() const { return "ChannelEventProcTask"; }
      75             : 
      76             : private:
      77             :     ChannelEventInfo event_info_;
      78             :     IFMapChannelManager *ifmap_channel_manager_;
      79             :     IFMapXmppChannel *ifmap_chnl_;
      80             : };
      81             : 
      82             : class IFMapXmppChannel::IFMapSender : public IFMapClient {
      83             : public:
      84             :     IFMapSender(IFMapXmppChannel *parent);
      85             : 
      86             :     virtual bool SendUpdate(const std::string &msg);
      87             : 
      88           0 :     virtual std::string ToString() const { return identifier_; }
      89           7 :     virtual const std::string &identifier() const { return identifier_; }
      90             :     const std::string &hostname() const { return hostname_; }
      91             :     IFMapXmppChannel *parent() { return parent_; }
      92             : 
      93           0 :     void SetIdentifier(const std::string &identifier) {
      94           0 :         identifier_ = identifier;
      95           0 :     }
      96             : 
      97             : private:
      98             :     IFMapXmppChannel *parent_;
      99             :     std::string hostname_;      // hostname
     100             :     std::string identifier_;    // FQN
     101             : };
     102             : 
     103           7 : IFMapXmppChannel::IFMapSender::IFMapSender(IFMapXmppChannel *parent)
     104           7 :     : parent_(parent), hostname_(parent_->channel_->ToString()) {
     105           7 : }
     106             : 
     107           0 : bool IFMapXmppChannel::IFMapSender::SendUpdate(const std::string &msg) {
     108           0 :     bool sent = parent_->channel_->Send(
     109           0 :         reinterpret_cast<const uint8_t *>(msg.data()), msg.size(), &msg,
     110             :         xmps::CONFIG,
     111             :         boost::bind(&IFMapXmppChannel::WriteReadyCb, parent_, _1));
     112             : 
     113           0 :     if (sent) {
     114           0 :         incr_msgs_sent();
     115           0 :         incr_bytes_sent(msg.size());
     116             :     } else {
     117           0 :         set_send_is_blocked(true);
     118           0 :         incr_msgs_blocked();
     119             :     }
     120           0 :     return sent;
     121             : }
     122             : 
     123           0 : void IFMapXmppChannel::WriteReadyCb(const boost::system::error_code &ec) {
     124           0 :     ifmap_client_->set_send_is_blocked(false);
     125           0 :     ifmap_server_->sender()->SendActive(ifmap_client_->index());
     126           0 : }
     127             : 
     128           7 : IFMapXmppChannel::IFMapXmppChannel(XmppChannel *channel, IFMapServer *server,
     129           7 :         IFMapChannelManager *ifmap_channel_manager)
     130           7 :     : peer_id_(xmps::CONFIG), channel_(channel), ifmap_server_(server),
     131           7 :       ifmap_channel_manager_(ifmap_channel_manager),
     132           7 :       ifmap_client_(new IFMapSender(this)), client_added_(false),
     133          14 :       channel_name_(channel->connection()->ToUVEKey()) {
     134             : 
     135           7 :     ifmap_client_->SetName(channel->connection()->ToUVEKey());
     136           7 :     channel_->RegisterReceive(xmps::CONFIG,
     137             :                               boost::bind(&IFMapXmppChannel::ReceiveUpdate,
     138             :                                           this, _1));
     139           7 : }
     140             : 
     141           7 : IFMapXmppChannel::~IFMapXmppChannel() {
     142           7 :     delete ifmap_client_;
     143             :     // Enqueue Unregister and process in the context of bgp::Config task
     144           7 :     channel_->UnRegisterWriteReady(xmps::CONFIG);
     145           7 :     ifmap_channel_manager_->EnqueueChannelUnregister(channel_);
     146           7 : }
     147             : 
     148             : // iqn should be [virtual-router:FQN-of-vr]
     149           0 : std::string IFMapXmppChannel::VrSubscribeGetVrName(const std::string &iqn,
     150             :                                                    bool *valid_message) {
     151           0 :     std::string vr_name;
     152           0 :     size_t tstart = iqn.find("virtual-router:");
     153           0 :     if (tstart == 0) {
     154           0 :         vr_name = std::string(iqn, (sizeof("virtual-router:") - 1));
     155           0 :         *valid_message = true;
     156             :     } else {
     157           0 :         *valid_message = false;
     158             :     }
     159             : 
     160           0 :     return vr_name;
     161           0 : }
     162             : 
     163             : // iqn should be [virtual-machine:UUID-of-vm]
     164           0 : std::string IFMapXmppChannel::VmSubscribeGetVmUuid(const std::string &iqn,
     165             :                                                    bool *valid_message) {
     166           0 :     std::string vm_uuid;
     167           0 :     size_t tstart = iqn.find("virtual-machine:");
     168           0 :     if (tstart == 0) {
     169           0 :         vm_uuid = std::string(iqn, (sizeof("virtual-machine:") - 1));
     170           0 :         *valid_message = true;
     171             :     } else {
     172           0 :         ifmap_channel_manager_->incr_invalid_vm_subscribe_messages();
     173           0 :         *valid_message = false;
     174             :     }
     175             : 
     176           0 :     return vm_uuid;
     177           0 : }
     178             : 
     179             : // If add-client was sent to ifmap_server, we must send delete-client too and
     180             : // vice-versa
     181           7 : bool IFMapXmppChannel::MustProcessChannelNotReady() {
     182           7 :     return client_added_;
     183             : }
     184             : 
     185           7 : const std::string& IFMapXmppChannel::FQName() const {
     186           7 :     if (ifmap_client_) {
     187           7 :         return ifmap_client_->identifier();
     188             :     } else {
     189           0 :         return IFMapXmppChannel::NoFqnSet;
     190             :     }
     191             : }
     192             : 
     193           0 : void IFMapXmppChannel::ProcessVrSubscribe(const std::string &identifier) {
     194             :     // If we have already received a vr-subscribe on this channel...
     195           0 :     if (client_added_) {
     196           0 :         ifmap_channel_manager_->incr_duplicate_vrsub_messages();
     197           0 :         IFMAP_XMPP_WARN(IFMapDuplicateVrSub, channel_name(), FQName());
     198           0 :         return;
     199             :     }
     200             : 
     201           0 :     ifmap_client_->SetIdentifier(identifier);
     202           0 :     bool add_client = true;
     203           0 :     ifmap_server_->ProcessClientWork(add_client, ifmap_client_);
     204           0 :     client_added_ = true;
     205           0 :     IFMAP_XMPP_DEBUG(IFMapXmppVrSubUnsub, "VrSubscribe", channel_name(),
     206             :                      FQName());
     207             : }
     208             : 
     209           0 : void IFMapXmppChannel::ProcessVmSubscribe(const std::string &vm_uuid) {
     210           0 :     if (!client_added_) {
     211             :         // If we didnt receive the vr-subscribe for this vm...
     212           0 :         ifmap_channel_manager_->incr_vmsub_novrsub_messages();
     213           0 :         IFMAP_XMPP_WARN(IFMapNoVrSub, "VmSubscribe", channel_name(), FQName(),
     214             :                         vm_uuid);
     215           0 :         return;
     216             :     }
     217             : 
     218           0 :     if (!ifmap_client_->HasAddedVm(vm_uuid)) {
     219           0 :         ifmap_client_->AddVm(vm_uuid);
     220           0 :         bool subscribe = true;
     221           0 :         ifmap_server_->ProcessVmSubscribe(ifmap_client_->identifier(), vm_uuid,
     222           0 :                                           subscribe, ifmap_client_->HasVms());
     223           0 :         IFMAP_XMPP_DEBUG(IFMapXmppVmSubUnsub, "VmSubscribe", channel_name(),
     224             :                          FQName(), vm_uuid);
     225             :     } else {
     226             :         // If we have already received a subscribe for this vm
     227           0 :         ifmap_channel_manager_->incr_duplicate_vmsub_messages();
     228           0 :         IFMAP_XMPP_WARN(IFMapDuplicateVmSub, channel_name(), FQName(), vm_uuid);
     229             :     }
     230             : }
     231             : 
     232           0 : void IFMapXmppChannel::ProcessVmUnsubscribe(const std::string &vm_uuid) {
     233             :     // If we didnt receive the vr-sub for this vm, ignore the request
     234           0 :     if (!client_added_) {
     235           0 :         ifmap_channel_manager_->incr_vmunsub_novrsub_messages();
     236           0 :         IFMAP_XMPP_WARN(IFMapNoVrSub, "VmUnsubscribe", channel_name(), FQName(),
     237             :                         vm_uuid);
     238           0 :         return;
     239             :     }
     240             : 
     241           0 :     if (ifmap_client_->HasAddedVm(vm_uuid)) {
     242           0 :         ifmap_client_->DeleteVm(vm_uuid);
     243           0 :         bool subscribe = false;
     244           0 :         ifmap_server_->ProcessVmSubscribe(ifmap_client_->identifier(), vm_uuid,
     245           0 :                                           subscribe, ifmap_client_->HasVms());
     246           0 :         IFMAP_XMPP_DEBUG(IFMapXmppVmSubUnsub, "VmUnsubscribe", channel_name(),
     247             :                          FQName(), vm_uuid);
     248             :     } else {
     249             :         // If we didnt receive the subscribe for this vm, ignore the unsubscribe
     250           0 :         ifmap_channel_manager_->incr_vmunsub_novmsub_messages();
     251           0 :         IFMAP_XMPP_WARN(IFMapNoVmSub, channel_name(), FQName(), vm_uuid);
     252             :     }
     253             : }
     254             : 
     255           0 : void IFMapXmppChannel::EnqueueVrSubscribe(const std::string &identifier) {
     256           0 :     ChannelEventInfo info;
     257           0 :     info.event = XCE_VR_SUBSCRIBE;
     258           0 :     info.name = identifier;
     259             : 
     260           0 :     ChannelEventProcTask *proc_task = new ChannelEventProcTask(info, this);
     261           0 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     262           0 :     scheduler->Enqueue(proc_task);
     263           0 : }
     264             : 
     265           0 : void IFMapXmppChannel::EnqueueVmSubUnsub(bool subscribe,
     266             :                                          const std::string &vm_uuid) {
     267           0 :     ChannelEventInfo info;
     268           0 :     info.event = (subscribe == true) ? XCE_VM_SUBSCRIBE : XCE_VM_UNSUBSCRIBE;
     269           0 :     info.name = vm_uuid;
     270             : 
     271           0 :     ChannelEventProcTask *proc_task = new ChannelEventProcTask(info, this);
     272           0 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     273           0 :     scheduler->Enqueue(proc_task);
     274           0 : }
     275             : 
     276             : // This runs in the context of the "xmpp::StateMachine" and queues all requests
     277             : // which are then processed in the context of "db::IFMapTable"
     278           0 : void IFMapXmppChannel::ReceiveUpdate(const XmppStanza::XmppMessage *msg) {
     279             : 
     280           0 :     if (msg->type == XmppStanza::IQ_STANZA) {
     281           0 :         const XmppStanza::XmppMessageIq *iq =
     282             :             static_cast<const XmppStanza::XmppMessageIq *>(msg);
     283             : 
     284           0 :         const char* const vr_string = "virtual-router:";
     285           0 :         const char* const vm_string = "virtual-machine:";
     286           0 :         if ((iq->iq_type.compare("set") == 0) &&
     287           0 :             (iq->action.compare("subscribe") == 0)) {
     288           0 :             if (iq->node.compare(0, strlen(vr_string), vr_string) == 0) {
     289           0 :                 bool valid_message = false;
     290           0 :                 std::string vr_name = VrSubscribeGetVrName(iq->node,
     291           0 :                                                            &valid_message);
     292           0 :                 if (valid_message) {
     293           0 :                     EnqueueVrSubscribe(vr_name);
     294             :                 }
     295           0 :             } else if (iq->node.compare(0, strlen(vm_string), vm_string) == 0) {
     296           0 :                 bool valid_message = false;
     297           0 :                 std::string vm_uuid = VmSubscribeGetVmUuid(iq->node,
     298           0 :                                                            &valid_message);
     299           0 :                 if (valid_message) {
     300           0 :                     bool subscribe = true;
     301           0 :                     EnqueueVmSubUnsub(subscribe, vm_uuid);
     302             :                 }
     303           0 :             } else {
     304           0 :                 ifmap_channel_manager_->incr_unknown_subscribe_messages();
     305           0 :                 IFMAP_XMPP_WARN(IFMapXmppUnknownMessage, iq->iq_type,
     306             :                                 iq->action, iq->node, channel_name());
     307             :             }
     308             :         }
     309           0 :         if ((iq->iq_type.compare("set") == 0) &&
     310           0 :             (iq->action.compare("unsubscribe") == 0)) {
     311           0 :             if (iq->node.compare(0, strlen(vm_string), vm_string) == 0) {
     312           0 :                 bool valid_message = false;
     313           0 :                 std::string vm_uuid = VmSubscribeGetVmUuid(iq->node,
     314           0 :                                                            &valid_message);
     315           0 :                 if (valid_message) {
     316           0 :                     bool subscribe = false;
     317           0 :                     EnqueueVmSubUnsub(subscribe, vm_uuid);
     318             :                 }
     319           0 :             } else {
     320           0 :                 ifmap_channel_manager_->incr_unknown_unsubscribe_messages();
     321           0 :                 IFMAP_XMPP_WARN(IFMapXmppUnknownMessage, iq->iq_type,
     322             :                                 iq->action, iq->node, channel_name());
     323             :             }
     324             :         }
     325             :     }
     326           0 : }
     327             : 
     328           0 : IFMapClient *IFMapXmppChannel::Sender() {
     329           0 :     return ifmap_client_;
     330             : }
     331             : 
     332           0 : uint64_t IFMapXmppChannel::msgs_sent() const {
     333           0 :     return ifmap_client_->msgs_sent();
     334             : }
     335             : 
     336             : // IFMapClient Manager routines
     337           5 : IFMapChannelManager::IFMapChannelManager(XmppServer *xmpp_server,
     338           5 :                                          IFMapServer *ifmap_server)
     339           5 :     : xmpp_server_(xmpp_server), ifmap_server_(ifmap_server),
     340           5 :       config_task_work_queue_(
     341             :           TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
     342             :           0, boost::bind(&IFMapChannelManager::ProcessChannelUnregister,
     343           5 :                          this, _1)) {
     344           5 :     unknown_subscribe_messages = 0;
     345           5 :     unknown_unsubscribe_messages = 0;
     346           5 :     duplicate_channel_ready_messages = 0;
     347           5 :     invalid_channel_not_ready_messages = 0;
     348           5 :     invalid_channel_state_messages = 0;
     349           5 :     invalid_vm_subscribe_messages = 0;
     350           5 :     vmsub_novrsub_messages = 0;
     351           5 :     vmunsub_novrsub_messages = 0;
     352           5 :     vmunsub_novmsub_messages = 0;
     353           5 :     duplicate_vrsub_messages = 0;
     354           5 :     duplicate_vmsub_messages = 0;
     355           5 :     xmpp_server_->RegisterConnectionEvent(xmps::CONFIG,
     356             :         boost::bind(&IFMapChannelManager::IFMapXmppChannelEventCb, this, _1,
     357             :                     _2));
     358           5 : }
     359             : 
     360           8 : IFMapChannelManager::~IFMapChannelManager() {
     361           5 :     std::scoped_lock lock(channel_map_mutex_);
     362           5 :     STLDeleteElements(&channel_map_);
     363           8 : }
     364             : 
     365          14 : IFMapXmppChannel *IFMapChannelManager::FindChannel(XmppChannel *channel) {
     366          14 :     std::scoped_lock lock(channel_map_mutex_);
     367             :     ChannelMap::iterator loc =
     368          14 :         channel_map_.find(const_cast<XmppChannel *>(channel));
     369          14 :     if (loc != channel_map_.end()) {
     370           7 :         return loc->second;
     371             :     }
     372           7 :     return NULL;
     373          14 : }
     374             : 
     375           0 : IFMapXmppChannel *IFMapChannelManager::FindChannel(std::string tostring) {
     376           0 :     std::scoped_lock lock(channel_map_mutex_);
     377           0 :     BOOST_FOREACH(ChannelMap::value_type &i, channel_map_) {
     378           0 :         if (i.second->ToString() == tostring)
     379           0 :             return i.second;
     380             :     }
     381           0 :     return NULL;
     382           0 : }
     383             : 
     384           7 : IFMapXmppChannel *IFMapChannelManager::CreateIFMapXmppChannel(
     385             :         XmppChannel *channel) {
     386             :     IFMapXmppChannel *ifmap_chnl = IfmapStaticObjectFactory::
     387           7 :         Create<IFMapXmppChannel>(channel,
     388             :             ifmap_server_,
     389           7 :             this);
     390           7 :     std::scoped_lock lock(channel_map_mutex_);
     391           7 :     channel_map_.insert(std::make_pair(channel, ifmap_chnl));
     392           7 :     return ifmap_chnl;
     393           7 : }
     394             : 
     395           7 : void IFMapChannelManager::DeleteIFMapXmppChannel(IFMapXmppChannel *ifmap_chnl) {
     396           7 :     std::scoped_lock lock(channel_map_mutex_);
     397           7 :     channel_map_.erase(ifmap_chnl->channel());
     398           7 :     delete ifmap_chnl;
     399           7 : }
     400             : 
     401           7 : void IFMapChannelManager::ProcessChannelReady(XmppChannel *channel) {
     402           7 :     IFMapXmppChannel *ifmap_chnl = FindChannel(channel);
     403           7 :     if (ifmap_chnl == NULL) {
     404           7 :         IFMAP_XMPP_DEBUG(IFMapXmppChannelEvent, "Create",
     405             :             channel->connection()->ToUVEKey(), IFMapXmppChannel::NoFqnSet);
     406           7 :         CreateIFMapXmppChannel(channel);
     407           7 :         ConfigClientManager *client_manager = ifmap_server_->get_config_manager();
     408           7 :         if (client_manager && !client_manager->GetEndOfRibComputed()) {
     409           0 :             IFMAP_XMPP_DEBUG(IFMapXmppChannelEvent, "Close",
     410             :                              channel->connection()->ToUVEKey(),
     411             :                              IFMapXmppChannel::NoFqnSet);
     412           0 :             channel->Close();
     413             :         }
     414             :     } else {
     415           0 :         incr_duplicate_channel_ready_messages();
     416             :     }
     417           7 : }
     418             : 
     419           7 : void IFMapChannelManager::ProcessChannelNotReady(XmppChannel *channel) {
     420           7 :     IFMapXmppChannel *ifmap_chnl = FindChannel(channel);
     421           7 :     if (ifmap_chnl) {
     422             :         // If we have received subscriptions and ifmap_server knows about the
     423             :         // client for this channel, ask ifmap_server to cleanup.
     424           7 :         std::string fq_name = ifmap_chnl->FQName();
     425           7 :         if (ifmap_chnl->MustProcessChannelNotReady()) {
     426           0 :             bool add_client = false;
     427           0 :             ifmap_server_->ProcessClientWork(add_client, ifmap_chnl->Sender());
     428             :         }
     429           7 :         IFMAP_XMPP_DEBUG(IFMapXmppChannelEvent, "Destroy",
     430             :                          channel->connection()->ToUVEKey(), fq_name);
     431           7 :         DeleteIFMapXmppChannel(ifmap_chnl);
     432           7 :     } else {
     433           0 :         incr_invalid_channel_not_ready_messages();
     434             :     }
     435           7 : }
     436             : 
     437           7 : void IFMapChannelManager::EnqueueChannelEvent(XCEvent event,
     438             :                                               XmppChannel *channel) {
     439           7 :     ChannelEventInfo info;
     440           7 :     info.event = event;
     441           7 :     info.channel = channel;
     442             : 
     443           7 :     ChannelEventProcTask *proc_task = new ChannelEventProcTask(info, this);
     444           7 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     445           7 :     scheduler->Enqueue(proc_task);
     446           7 : }
     447             : 
     448             : // This runs in the context of the "xmpp::StateMachine"
     449          14 : void IFMapChannelManager::IFMapXmppChannelEventCb(XmppChannel *channel,
     450             :                                                   xmps::PeerState state) {
     451          14 :     if (state == xmps::READY) {
     452             :         // Process the READY right away
     453           7 :         ProcessChannelReady(channel);
     454           7 :     } else if (state == xmps::NOT_READY) {
     455             :         // Queue the NOT_READY to be processed via the "db::IFMapTable" task
     456           7 :         EnqueueChannelEvent(XCE_NOT_READY, channel);
     457             :     } else {
     458           0 :         incr_invalid_channel_state_messages();
     459             :     }
     460          14 : }
     461             : 
     462             : // This runs in the context of bgp::Config
     463           7 : bool IFMapChannelManager::ProcessChannelUnregister(ConfigTaskQueueEntry entry) {
     464           7 :     IFMAP_XMPP_DEBUG(IFMapChannelUnregisterMessage,
     465             :                      "Unregistering config peer for channel",
     466             :                      entry.channel->connection()->ToUVEKey());
     467           7 :     entry.channel->UnRegisterReceive(xmps::CONFIG);
     468           7 :     return true;
     469             : }
     470             : 
     471           7 : void IFMapChannelManager::EnqueueChannelUnregister(XmppChannel *channel) {
     472             :     // Let ProcessChannelUnregister() unregister in the context of bgp::Config
     473             :     ConfigTaskQueueEntry entry;
     474           7 :     entry.channel = channel;
     475           7 :     config_task_work_queue_.Enqueue(entry);
     476           7 : }
     477             : 
     478           0 : void IFMapChannelManager::FillChannelMap(
     479             :         std::vector<IFMapXmppChannelMapEntry> *out_map) {
     480           0 :     std::scoped_lock lock(channel_map_mutex_);
     481           0 :     for (ChannelMap::iterator iter = channel_map_.begin();
     482           0 :          iter != channel_map_.end(); ++iter) {
     483           0 :         IFMapXmppChannel *ifmap_chnl = iter->second;
     484           0 :         IFMapXmppChannelMapEntry entry;
     485           0 :         entry.set_client_name(ifmap_chnl->FQName());
     486           0 :         entry.set_host_name(ifmap_chnl->channel()->ToString());
     487           0 :         entry.set_channel_name(ifmap_chnl->channel_name());
     488           0 :         entry.set_client_added(ifmap_chnl->get_client_added());
     489           0 :         out_map->push_back(entry);
     490           0 :     }
     491           0 : }
     492             : 
     493           0 : static bool IFMapXmppShowReqHandleRequest(const Sandesh *sr,
     494             :                                           const RequestPipeline::PipeSpec ps,
     495             :                                           int stage, int instNum,
     496             :                                           RequestPipeline::InstData *data) {
     497             :     const IFMapXmppShowReq *request =
     498           0 :         static_cast<const IFMapXmppShowReq *>(ps.snhRequest_.get());
     499             :     IFMapSandeshContext *sctx =
     500           0 :         static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
     501             :     IFMapChannelManager *ifmap_channel_manager =
     502           0 :         sctx->ifmap_server()->get_ifmap_channel_manager();
     503             : 
     504           0 :     IFMapXmppShowResp *response = new IFMapXmppShowResp();
     505           0 :     response->set_context(request->context());
     506           0 :     response->set_more(false);
     507             : 
     508           0 :     if (!ifmap_channel_manager) {
     509           0 :         response->Response();
     510           0 :         return true;
     511             :     }
     512             : 
     513           0 :     IFMapChannelManagerInfo channel_manager_info;
     514           0 :     IFMapChannelManagerStats channel_manager_stats;
     515             : 
     516           0 :     channel_manager_stats.set_unknown_subscribe_messages(
     517             :         ifmap_channel_manager->get_unknown_subscribe_messages());
     518           0 :     channel_manager_stats.set_unknown_unsubscribe_messages(
     519             :         ifmap_channel_manager->get_unknown_unsubscribe_messages());
     520           0 :     channel_manager_stats.set_duplicate_channel_ready_messages(
     521             :         ifmap_channel_manager->get_duplicate_channel_ready_messages());
     522           0 :     channel_manager_stats.set_invalid_channel_not_ready_messages(
     523             :         ifmap_channel_manager->get_invalid_channel_not_ready_messages());
     524           0 :     channel_manager_stats.set_invalid_channel_state_messages(
     525             :         ifmap_channel_manager->get_invalid_channel_state_messages());
     526           0 :     channel_manager_stats.set_invalid_vm_subscribe_messages(
     527             :         ifmap_channel_manager->get_invalid_vm_subscribe_messages());
     528           0 :     channel_manager_stats.set_vmsub_novrsub_messages(
     529             :         ifmap_channel_manager->get_vmsub_novrsub_messages());
     530           0 :     channel_manager_stats.set_vmunsub_novrsub_messages(
     531             :         ifmap_channel_manager->get_vmunsub_novrsub_messages());
     532           0 :     channel_manager_stats.set_vmunsub_novmsub_messages(
     533             :         ifmap_channel_manager->get_vmunsub_novmsub_messages());
     534           0 :     channel_manager_stats.set_duplicate_vrsub_messages(
     535             :         ifmap_channel_manager->get_duplicate_vrsub_messages());
     536           0 :     channel_manager_stats.set_duplicate_vmsub_messages(
     537             :         ifmap_channel_manager->get_duplicate_vmsub_messages());
     538             : 
     539           0 :     IFMapXmppChannelMapList channel_map_list;
     540           0 :     std::vector<IFMapXmppChannelMapEntry> channel_map;
     541           0 :     ifmap_channel_manager->FillChannelMap(&channel_map);
     542           0 :     channel_map_list.set_channel_list(channel_map);
     543           0 :     channel_map_list.set_channel_count(channel_map.size());
     544             : 
     545           0 :     channel_manager_info.set_channel_manager_stats(channel_manager_stats);
     546           0 :     channel_manager_info.set_channel_manager_map(channel_map_list);
     547             : 
     548           0 :     response->set_channel_manager_info(channel_manager_info);
     549           0 :     response->Response();
     550             : 
     551             :     // Return 'true' so that we are not called again
     552           0 :     return true;
     553           0 : }
     554             : 
     555           0 : void IFMapXmppShowReq::HandleRequest() const {
     556             : 
     557           0 :     RequestPipeline::StageSpec s0;
     558           0 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     559             : 
     560           0 :     s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
     561           0 :     s0.cbFn_ = IFMapXmppShowReqHandleRequest;
     562           0 :     s0.instances_.push_back(0);
     563             : 
     564           0 :     RequestPipeline::PipeSpec ps(this);
     565           0 :     ps.stages_= boost::assign::list_of(s0)
     566           0 :         .convert_to_container<std::vector<RequestPipeline::StageSpec> >();
     567           0 :     RequestPipeline rp(ps);
     568           0 : }
     569             : 

Generated by: LCOV version 1.14