OpenSDN source code
ifmap_agent_table.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include <boost/algorithm/string.hpp>
8 #include <boost/bind/bind.hpp>
9 #include <boost/format.hpp>
10 #include "base/logging.h"
11 #include "db/db.h"
12 #include "db/db_graph.h"
13 #include "db/db_table_partition.h"
15 #include "ifmap/ifmap_node.h"
16 #include "ifmap/ifmap_link.h"
17 #include "ifmap/ifmap_agent_types.h"
18 
19 using namespace std;
20 using namespace boost::placeholders;
21 
23 IFMapAgentTraceBuf(SandeshTraceBufferCreate("IFMapAgentTrace", 1000));
24 
25 IFMapAgentTable::IFMapAgentTable(DB *db, const string &name, DBGraph *graph)
26  : IFMapTable(db, name, graph), pre_filter_(NULL) {
27 }
28 
29 unique_ptr<DBEntry> IFMapAgentTable::AllocEntry(const DBRequestKey *key) const {
30  unique_ptr<DBEntry> entry(
31  new IFMapNode(const_cast<IFMapAgentTable *>(this)));
32  entry->SetKey(key);
33  return entry;
34 }
35 
37 
38  IFMapTable *table = FindTable(db, key->id_type);
39  if (!table) {
40  return NULL;
41  }
42 
43  unique_ptr<DBEntry> entry(new IFMapNode(table));
44  entry->SetKey(key);
45  IFMapNode *node = static_cast<IFMapNode *>(table->Find(entry.get()));
46  return node;
47 }
48 
49 
50 IFMapAgentTable* IFMapAgentTable::TableFind(const string &node_name) {
51  string name = node_name;
52  std::replace(name.begin(), name.end(), '-', '_');
53  name = "__ifmap__." + name + ".0";
54  IFMapAgentTable *table =
55  static_cast<IFMapAgentTable *>(database()->FindTable(name));
56  return table;
57 }
58 
60  unique_ptr<DBEntry> key(AllocEntry(request));
61  IFMapNode *node = static_cast<IFMapNode *>(Find(key.get()));
62  return node;
63 }
64 
66 
67  IFMapObject *obj;
68 
69  if (node != NULL) {
70  /* If delete marked, clear it now */
71  if (node->IsDeleted()) {
72  node->ClearDelete();
73  graph()->AddNode(node);
74  }
75 
76  obj = node->GetObject();
77  assert(obj);
78  //We dont accept lesser sequence number updates
79  assert(obj->sequence_number() <= req->id_seq_num);
80 
81  node->Remove(obj);
82 
83  } else {
84  unique_ptr<DBEntry> key(AllocEntry(req));
85  node = const_cast<IFMapNode *>(
86  static_cast<const IFMapNode *>(key.release()));
87  DBTablePartition *partition =
88  static_cast<DBTablePartition *>(GetTablePartition(0));
89  partition->Add(node);
90  graph()->AddNode(node);
91  }
92 
93  return node;
94 }
95 
96 // A node is deleted. Move all links for the node to defer-list
98 
99  IFMapNode *right;
100  DBGraphEdge *edge;
101 
102  IFMapAgentLinkTable *ltable = static_cast<IFMapAgentLinkTable *>
104  assert(ltable != NULL);
105 
107  bool origin_exists;
108  uint64_t seq;
109  for (iter = node->edge_list_begin(graph());
110  iter != node->edge_list_end(graph());) {
111  edge = iter.operator->();
112  IFMapLink *l = static_cast<IFMapLink *>(edge);
113  right = static_cast<IFMapNode *>(iter.target());
114  iter++;
115  seq = l->sequence_number(IFMapOrigin::UNKNOWN, &origin_exists);
116  assert(origin_exists);
117  // Create both the request keys
118  unique_ptr <IFMapAgentLinkTable::RequestKey> req_key (new IFMapAgentLinkTable::RequestKey);
119  req_key->left_key.id_name = node->name();
120  req_key->left_key.id_type = node->table()->Typename();
121  req_key->left_key.id_seq_num = seq;
122 
123  req_key->right_key.id_name = right->name();
124  req_key->right_key.id_type = right->table()->Typename();
125  req_key->right_key.id_seq_num = seq;
126  req_key->metadata = l->metadata();
127 
128  DBRequest req;
130  req.key = std::move(req_key);
131 
132  //Add it to defer list
133  ltable->LinkDefAdd(&req);
134 
135  ltable->DelLink(node, right, edge);
136  }
137 }
138 
140 
141 
142  if ((node->HasAdjacencies(graph()) == true)) {
143  HandlePendingLinks(node);
144  }
145 
146  //Now there should not be any more adjacencies
147  assert((node->HasAdjacencies(graph()) == false));
148 
149  DBTablePartition *partition =
150  static_cast<DBTablePartition *>(GetTablePartition(0));
151  graph()->RemoveNode(node);
152  partition->Delete(node);
153 }
154 
156  DBTablePartition *partition =
157  static_cast<DBTablePartition *>(GetTablePartition(0));
158  partition->Change(node);
159 }
160 
161 // Process link-defer list based for the request.
162 // If request is add, create left->right and right-left defer nodes
163 // If request is delete, remove left->right and right->left defer nodes
164 // The sequence number is valid only in the DeferrendNode entry
166  RequestKey *key = static_cast<RequestKey *>(request->key.get());
167 
168  std::list<DeferredNode>::iterator it;
169 
170  std::list<DeferredNode> *left = NULL;
171  LinkDefMap::iterator left_it = link_def_map_.find(key->left_key);
172  if (link_def_map_.end() != left_it)
173  left = left_it->second;
174 
175  std::list<DeferredNode> *right = NULL;
176  LinkDefMap::iterator right_it = link_def_map_.find(key->right_key);
177  if (link_def_map_.end() != right_it)
178  right = right_it->second;
179 
180  if (request->oper == DBRequest::DB_ENTRY_DELETE) {
181  //We need to delete the old sequence links as well
182  // remove left->right entry
183  if (left) {
184  for(it = left->begin(); it != left->end(); it++) {
185  if (((*it).node_key.id_type == key->right_key.id_type) &&
186  ((*it).node_key.id_name == key->right_key.id_name)) {
187  left->erase(it);
188  break;
189  }
190  }
191  RemoveDefListEntry(&link_def_map_, left_it, NULL);
192  }
193 
194  // remove right->left entry
195  if (right) {
196  for(it = right->begin(); it != right->end(); it++) {
197  if (((*it).node_key.id_type == key->left_key.id_type) &&
198  ((*it).node_key.id_name == key->left_key.id_name)) {
199  right->erase(it);
200  break;
201  }
202  }
203  RemoveDefListEntry(&link_def_map_, right_it, NULL);
204  }
205 
206  return;
207  }
208 
209  bool push_left = true;
210 
211  // Add/Update left->right entry
212  if (left) {
213  // If list already contains, just update the seq number
214  for(it = left->begin(); it != left->end(); it++) {
215  if (((*it).node_key.id_type == key->right_key.id_type) &&
216  ((*it).node_key.id_name == key->right_key.id_name)) {
217  (*it).node_key.id_seq_num = key->right_key.id_seq_num;
218  (*it).link_metadata = key->metadata;
219  push_left = false;
220  break;
221  }
222  }
223  } else {
224  left = new std::list<DeferredNode>();
225  link_def_map_[key->left_key] = left;
226  }
227 
228  bool push_right = true;
229  // Add/Update right->left entry
230  if (right) {
231  // If list already contains, just update the seq number
232  for(it = right->begin(); it != right->end(); it++) {
233  if (((*it).node_key.id_type == key->left_key.id_type) &&
234  ((*it).node_key.id_name == key->left_key.id_name)) {
235  (*it).node_key.id_seq_num = key->left_key.id_seq_num;
236  (*it).link_metadata = key->metadata;
237  push_right = false;
238  break;
239  }
240  }
241  } else {
242  right = new std::list<DeferredNode>();
243  link_def_map_[key->right_key] = right;
244  }
245 
246  // Add it to the end of the list
247  struct DeferredNode dn;
248  dn.link_metadata = key->metadata;
249  if (push_left) {
250  dn.node_key = key->right_key;
251  left->push_back(dn);
252  }
253  if (push_right) {
254  dn.node_key = key->left_key;
255  right->push_back(dn);
256  }
257  return;
258 }
259 
261  DBRequest *request) {
262  RequestKey *key = static_cast<RequestKey *>(request->key.get());
263  IFMapAgentTable *table = NULL;
264  struct IFMapAgentData *req_data;
265  IFMapObject *obj;
266 
267  table = TableFind(key->id_type);
268  if (!table) {
270  "Table " + key->id_type + " not found");
271  return;
272  }
273 
274  IFMapNode *node = EntryLookup(key);
275  if (table->pre_filter_) {
276  DBRequest::DBOperation old_oper = request->oper;
277  if (table->pre_filter_(table, node, request) == false) {
279  "Node " + key->id_name + " neglected as filter"
280  + "suppressed");
281  return;
282  }
283  if ((old_oper != DBRequest::DB_ENTRY_DELETE) &&
284  (request->oper == DBRequest::DB_ENTRY_DELETE)) {
286  "Node " + key->id_name + "ID_PERMS Null");
287  }
288  }
289 
290  if (request->oper == DBRequest::DB_ENTRY_DELETE) {
291  if (node == NULL) {
293  "Node " + key->id_name + " not found in Delete");
294  return;
295  }
296 
297  if (node->IsDeleted()) {
299  "Node " + key->id_name + " already deleted");
300  return;
301  }
302 
303  obj = node->GetObject();
304  //We dont accept lesser sequence number updates
305  assert(obj->sequence_number() <= key->id_seq_num);
306 
307  //Upate the sequence number even for deletion of node
308  obj->set_sequence_number(key->id_seq_num);
309  DeleteNode(node);
310  return;
311  }
312 
313  if (request->oper == DBRequest::DB_ENTRY_NOTIFY) {
314  if (node) {
315  partition->Notify(node);
316  }
317  return;
318  }
319 
320  node = EntryLocate(node, key);
321  assert(node);
322 
323  //Get the data from request key and notify oper tables
324  req_data = static_cast<struct IFMapAgentData *>(request->data.get());
325  obj = static_cast<IFMapObject *>(req_data->content.release());
326 
327  //Set the sequence number of the object
328  obj->set_sequence_number(key->id_seq_num);
329 
330  node->Insert(obj);
331  NotifyNode(node);
332 
333  IFMapAgentLinkTable *link_table = static_cast<IFMapAgentLinkTable *>(
335  link_table->EvalDefLink(key);
336 }
337 
339  assert(!HasListeners());
340  DBTablePartition *partition = static_cast<DBTablePartition *>(
341  GetTablePartition(0));
342  IFMapNode *next = NULL;
343  for (IFMapNode *node = static_cast<IFMapNode *>(partition->GetFirst());
344  node != NULL; node = next) {
345  next = static_cast<IFMapNode *>(partition->GetNext(node));
346  if (node->IsDeleted()) {
347  continue;
348  }
349  graph()->RemoveNode(node);
350  partition->Delete(node);
351  }
352 }
353 
354 
355 // Agent link table routines
357  const std::string &metadata) {
358 
359  IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
361  assert(table != NULL);
362  IFMapLink *link = table->FindLink(metadata, left, right);
363  return (link ? (link->IsDeleted() ? NULL : link) : NULL);
364 }
365 
367  const std::string &metadata,
368  uint64_t seq) {
369 
370  IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
372  assert(table != NULL);
373 
374  IFMapLink *link = table->AddLink(left, right, metadata, seq,
376  graph()->Link(left, right, (DBGraphEdge *)link);
377 }
378 
380  IFMapAgentLinkTable *table = static_cast<IFMapAgentLinkTable *>(
382  assert(table != NULL);
383  table->DeleteLink(static_cast<IFMapLink *>(edge));
384 }
385 
386 IFMapAgentLinkTable::IFMapAgentLinkTable(DB *db, const string &name, DBGraph *graph)
387  : IFMapLinkTable(db, name, graph) {
388 }
389 
390 DBTable *IFMapAgentLinkTable::CreateTable(DB *db, const string &name,
391  DBGraph *graph) {
393  table->Init();
394  return table;
395 }
396 
397 
400  boost::bind(&IFMapAgentLinkTable::CreateTable, _1, _2, graph));
402 }
403 
405  DBRequest *req) {
406 
407  RequestKey *key = static_cast<RequestKey *>(req->key.get());
408 
409  IFMapNode *left;
411  if (!left) {
413  key->left_key.id_type + ":" + key->left_key.id_name +
414  " not present for link to " + key->right_key.id_type +
415  ":" + key->right_key.id_name);
416  LinkDefAdd(req);
417  return;
418  }
419 
420  IFMapNode *right;
422  if (!right) {
424  key->right_key.id_type + " : " + key->right_key.id_name +
425  " not present for link to " + key->left_key.id_type + " : " +
426  key->left_key.id_name);
427  LinkDefAdd(req);
428  return;
429  }
430 
431  if (left->IsDeleted()) {
433  "Adding Link" + key->left_key.id_type + ":" +
434  key->left_key.id_name + "->" + key->right_key.id_type +
435  ":" + key->right_key.id_name + " to defer "
436  "list as left is deleted marked");
437  LinkDefAdd(req);
438  return;
439  }
440 
441  if (right->IsDeleted()) {
443  "Adding Link" + key->left_key.id_type + ":" +
444  key->left_key.id_name + "->" + key->right_key.id_type +
445  ":" + key->right_key.id_name + " to defer "
446  "list as right is deleted marked");
447  LinkDefAdd(req);
448  return;
449  }
450 
451  IFMapObject *obj = left->GetObject();
452  if (obj->sequence_number() < key->left_key.id_seq_num) {
454  "IFMap Link " + left->name() + right->name() +
455  " with wrong seq number");
456  LinkDefAdd(req);
457  return;
458  }
459 
460  obj = right->GetObject();
461  if (obj->sequence_number() < key->left_key.id_seq_num) {
463  "IFMap Link " + left->name() + right->name() +
464  " with wrong seq number");
465  LinkDefAdd(req);
466  return;
467  }
468 
469  DBGraphEdge *link = FindLink(left, right, key->metadata);
470 
471  if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
472  if (link == NULL) {
473  AddLink(left, right, key->metadata, key->left_key.id_seq_num);
474  } else {
476  IFMapLink *l = static_cast<IFMapLink *>(link);
477  l->UpdateProperties(origin, key->left_key.id_seq_num);
478  }
479  } else {
480  if (link == NULL) {
481  return;
482  }
483  DelLink(left, right, link);
484  }
485 }
486 
488  (LinkDefMap *map, LinkDefMap::iterator &map_it,
489  std::list<DeferredNode>::iterator *list_it) {
490 
491  std::list<DeferredNode> *list = map_it->second;
492  if (list_it) {
493  list->erase(*list_it);
494  }
495 
496  if (list->size()) {
497  return false;
498  }
499  map->erase(map_it);
500  delete list;
501  return true;
502 }
503 
504 // For every link there are 2 entries,
505 // left->right
506 // right->left
507 //
508 // If both left and right node are available, remove the entries and try to
509 // add the link
511  LinkDefMap::iterator link_defmap_it = link_def_map_.find(*key);
512  if (link_def_map_.end() == link_defmap_it)
513  return;
514 
515  std::list<DeferredNode> *left_list = link_defmap_it->second;
516  std::list<DeferredNode>::iterator left_it, left_list_entry;
517  for(left_it = left_list->begin(); left_it != left_list->end();) {
518  left_list_entry = left_it++;
519 
520  // If link seq is older, dont consider the link.
521  if ((*left_list_entry).node_key.id_seq_num < key->id_seq_num)
522  continue;
523 
524  // Skip if right-node is not yet present
526  &((*left_list_entry).node_key));
527  if (!node)
528  continue;
529 
530  //If the other end of the node is not from active control node,
531  //dont consider the link
532  IFMapObject *obj = node->GetObject();
533  if (obj->sequence_number() < key->id_seq_num)
534  continue;
535 
536 
537  // left->right entry found defer-list. Find the right->left entry
538  LinkDefMap::iterator right_defmap_it =
539  link_def_map_.find((*left_list_entry).node_key);
540  assert(link_def_map_.end() != right_defmap_it);
541 
542  std::list<DeferredNode> *right_list = right_defmap_it->second;
543  std::list<DeferredNode>::iterator right_it, right_list_entry;
544  bool removed_something = false;
545  for(right_it = right_list->begin(); right_it !=
546  right_list->end(); right_it++) {
547 
548  // If link seq is older, dont consider the link.
549  if ((*right_it).node_key.id_seq_num < key->id_seq_num)
550  continue;
551 
552  if ((*right_it).node_key.id_type == key->id_type &&
553  (*right_it).node_key.id_name == key->id_name) {
554  RemoveDefListEntry(&link_def_map_, right_defmap_it, &right_it);
555  removed_something = true;
556  break;
557  }
558  }
559 
560  //We should have removed something in the above iteration
561  assert(removed_something);
562 
563  //Remove from deferred list before enqueing
564  unique_ptr <RequestKey> req_key (new RequestKey);
565  req_key->left_key = *key;
566  req_key->right_key = (*left_list_entry).node_key;
567  req_key->metadata = (*left_list_entry).link_metadata;
568  // Dont delete left_list_entry. Its passed in req structure
569  left_list->erase(left_list_entry);
570 
571  DBRequest req;
572  req.key = std::move(req_key);
574  Enqueue(&req);
575  }
576 
577  // If list does not have any entries, delete the list
578  RemoveDefListEntry(&link_def_map_, link_defmap_it, NULL);
579 }
580 
582  std::list<DeferredNode> *ent;
583  std::list<DeferredNode>::iterator it, list_entry;
584  IFMapAgentLinkTable::LinkDefMap::iterator dlist_it, temp;
585 
586  for(dlist_it = link_def_map_.begin(); dlist_it != link_def_map_.end(); ) {
587  temp = dlist_it++;
588  ent = temp->second;
589  for(it = ent->begin(); it != ent->end();) {
590  list_entry = it++;
591 
592  //Delete the deferred link if it is old seq
593  if ((*list_entry).node_key.id_seq_num < seq) {
595  &list_entry) == true) {
596  //The list has been deleted. Move to the next map
597  //entry
598  break;
599  }
600  }
601  }
602  }
603 }
604 
605 //Stale Cleaner functionality
607 public:
608 
609  IFMapAgentStaleCleanerWorker(DB *db, DBGraph *graph, uint64_t seq):
610  Task(TaskScheduler::GetInstance()->GetTaskId("db::DBTable"), 0),
611  db_(db), graph_(graph), seq_(seq) {
612  }
613 
614  bool Run() {
616  "IFMap Config Audit start:");
617  //Handle the links first
620  e_iter != graph_->edge_list_end(); e_iter = e_next) {
621 
622  const DBGraph::DBEdgeInfo &tuple = *e_iter;
623 
624  e_next = ++e_iter;
625 
626  IFMapNode *lhs = static_cast<IFMapNode *>(boost::get<0>(tuple));
627  IFMapNode *rhs = static_cast<IFMapNode *>(boost::get<1>(tuple));
628  IFMapLink *link = static_cast<IFMapLink *>(boost::get<2>(tuple));
629  assert(link);
630 
631  bool exists = false;
632  IFMapLink::LinkOriginInfo origin_info =
633  link->GetOriginInfo(IFMapOrigin::UNKNOWN, &exists);
634  if (exists && (origin_info.sequence_number < seq_ )) {
635  IFMapAgentLinkTable *ltable = static_cast<IFMapAgentLinkTable *>(
638  origin_info.sequence_number, "Deleting Link between " +
639  lhs->name() + rhs->name());
640  ltable->DeleteLink(link);
641  }
642  }
643 
644  //Handle the vertices now
647  v_iter != graph_->vertex_list_end(); v_iter = v_next) {
648 
649  IFMapNode *node = static_cast<IFMapNode *>(v_iter.operator->());
650  v_next = ++v_iter;
651 
652  IFMapObject *obj = node->GetObject();
653  assert(obj);
654  if (obj->sequence_number() < seq_) {
655  IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
657  "Deleting node " + node->name());
658  table->DeleteNode(node);
659  }
660  }
661 
662  //Handle deferred list
663  IFMapAgentLinkTable *table = static_cast<IFMapAgentLinkTable *>(
665  table->DestroyDefLink(seq_);
666 
667  return true;
668  }
669  std::string Description() const {
670  return "IFMapAgentStaleCleaner::IFMapAgentStaleCleanerWorker";
671  }
672 
673 private:
674  DB *db_;
676  uint64_t seq_;
677 };
678 
680 }
681 
683  db_(db), graph_(graph) {
684 }
685 
687  seq_ = seq;
690  sch->Enqueue(cleaner);
691  return false;
692 }
693 
695  IFMapLinkTable *table = static_cast<IFMapLinkTable *>(
697  table->Clear();
699 }
void ClearDelete()
Definition: db_entry.h:47
bool IsDeleted() const
Definition: db_entry.h:48
const DBGraph * graph() const
DBGraphVertex * target() const
edge_iterator edge_list_begin(DBGraph *graph)
bool HasAdjacencies(DBGraph *graph) const
edge_iterator edge_list_end(DBGraph *graph)
edge_iterator edge_list_begin()
Definition: db_graph.cc:262
boost::tuple< DBGraphVertex *, DBGraphVertex *, DBGraphEdge * > DBEdgeInfo
Definition: db_graph.h:45
vertex_iterator vertex_list_begin()
Definition: db_graph.cc:293
Edge Link(DBGraphVertex *lhs, DBGraphVertex *rhs, DBGraphEdge *link)
Definition: db_graph.cc:41
edge_iterator edge_list_end()
Definition: db_graph.cc:266
void RemoveNode(DBGraphVertex *entry)
Definition: db_graph.cc:36
vertex_iterator vertex_list_end()
Definition: db_graph.cc:297
void AddNode(DBGraphVertex *entry)
Definition: db_graph.cc:30
bool Enqueue(DBRequest *req)
Definition: db_table.cc:220
bool HasListeners() const
Definition: db_table.cc:260
DB * database()
Definition: db_table.h:107
const std::string & name() const
Definition: db_table.h:110
void Notify(DBEntryBase *entry)
void Delete(DBEntryBase *)
virtual void Change(DBEntry *entry)
virtual void Add(DBEntry *entry)
virtual DBEntry * GetNext(const DBEntryBase *entry)
virtual DBEntry * GetFirst()
void Init()
Definition: db_table.cc:413
DBEntry * Find(const DBEntry *entry)
Definition: db_table.cc:495
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:462
Definition: db.h:24
static void RegisterFactory(const std::string &prefix, CreateFunction create_fn)
Definition: db.cc:24
DBTableBase * FindTable(const std::string &name)
Definition: db.cc:68
DBTableBase * CreateTable(const std::string &name)
Definition: db.cc:99
virtual void Input(DBTablePartition *partition, DBClient *client, DBRequest *req)
std::map< IFMapTable::RequestKey, std::list< DeferredNode > *, comp > LinkDefMap
static DBTable * CreateTable(DB *db, const std::string &name, DBGraph *graph)
IFMapLink * FindLink(IFMapNode *left, IFMapNode *right, const std::string &metadata)
void DestroyDefLink(uint64_t)
bool RemoveDefListEntry(LinkDefMap *map, LinkDefMap::iterator &map_it, std::list< DeferredNode >::iterator *list_it)
void DelLink(IFMapNode *first, IFMapNode *second, DBGraphEdge *edge)
IFMapAgentLinkTable(DB *db, const std::string &name, DBGraph *graph)
void AddLink(IFMapNode *left, IFMapNode *right, const std::string &metadata, uint64_t seq)
void LinkDefAdd(DBRequest *request)
void EvalDefLink(IFMapTable::RequestKey *key)
IFMapAgentStaleCleanerWorker(DB *db, DBGraph *graph, uint64_t seq)
bool Run()
Code to execute in a task. Returns true if task is completed. Return false to reschedule the task.
std::string Description() const
Gives a description of the task.
IFMapAgentStaleCleaner(DB *db, DBGraph *graph)
IFMapNode * EntryLocate(IFMapNode *node, RequestKey *key)
PreFilterFn pre_filter_
IFMapNode * EntryLookup(RequestKey *key)
IFMapAgentTable * TableFind(const std::string &node_name)
virtual void Clear()
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *key) const
void NotifyNode(IFMapNode *node)
static IFMapNode * TableEntryLookup(DB *db, RequestKey *key)
void DeleteNode(IFMapNode *node)
virtual void Input(DBTablePartition *partition, DBClient *client, DBRequest *req)
IFMapAgentTable(DB *db, const std::string &name, DBGraph *graph)
void HandlePendingLinks(IFMapNode *)
IFMapLink * FindLink(const std::string &metadata, IFMapNode *left, IFMapNode *right)
IFMapLink * AddLink(IFMapNode *left, IFMapNode *right, const std::string &metadata, uint64_t sequence_number, const IFMapOrigin &origin)
void DeleteLink(IFMapLink *link, const IFMapOrigin &origin)
IFMapTable * table()
Definition: ifmap_node.h:29
void Remove(IFMapObject *obj)
Definition: ifmap_node.cc:58
const std::string & name() const
Definition: ifmap_node.h:48
IFMapObject * GetObject()
Definition: ifmap_node.cc:63
void Insert(IFMapObject *obj)
Definition: ifmap_node.cc:49
uint64_t sequence_number()
Definition: ifmap_object.h:33
void set_sequence_number(uint64_t sequence_number)
Definition: ifmap_object.h:35
static IFMapTable * FindTable(DB *db, const std::string &element_type)
Definition: ifmap_table.cc:39
virtual const char * Typename() const =0
static void ClearTables(DB *db)
Definition: ifmap_table.cc:46
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:304
void Enqueue(Task *task)
Enqueues a task for running. Starts task if all policy rules are met else puts task in waitq....
Definition: task.cc:642
static TaskScheduler * GetInstance()
Definition: task.cc:554
Task is a class to describe a computational task within OpenSDN control plane applications....
Definition: task.h:79
Definition: trace.h:288
void IFMapAgentLinkTable_Init(DB *db, DBGraph *graph)
SandeshTraceBufferPtr IFMapAgentTraceBuf(SandeshTraceBufferCreate("IFMapAgentTrace", 1000))
#define IFMAP_AGENT_TRACE(obj,...)
#define IFMAP_AGENT_LINK_DB_NAME
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46
DBOperation oper
Definition: db_table.h:42
@ DB_ENTRY_NOTIFY
Definition: db_table.h:40
@ DB_ENTRY_DELETE
Definition: db_table.h:39
@ DB_ENTRY_ADD_CHANGE
Definition: db_table.h:38
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
IFMapTable::RequestKey left_key
IFMapTable::RequestKey right_key
std::unique_ptr< IFMapObject > content