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