OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
oper_db.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef SRC_VNSW_AGENT_OPER_OPER_DB_H_
6 #define SRC_VNSW_AGENT_OPER_OPER_DB_H_
7 
9 // This file defines set of common agent oper-db class with following
10 // - Support IFMap dependency tracking.
11 // - The IFMapNode for a request is passed in the AgentOperDBData object
12 // - AgentOperDBTable::Add allocates a AgentOperDBEntry and sets the
13 // AgentOperDBEntry allocated as "state" for IFMapNode passed
14 // - AgentOperDBTable::OnChange and AgentOperDBTable::Resync will check
15 // if there is change in IFMapNode for the AgentOperDBEntry. If so,
16 // it will release state from the previous IFMapNode and set state to
17 // the new IFMapNode
18 // - AgentOperDBTable::Delete will release the state added for IFMapNode
20 #include <cmn/agent_cmn.h>
21 #include <cmn/agent_db.h>
22 #include <operdb_init.h>
24 #include <ifmap/ifmap_node.h>
25 
26 struct AgentOperDBKey : public AgentKey {
28  AgentOperDBKey(DBSubOperation sub_op) : AgentKey(sub_op) { }
29  virtual ~AgentOperDBKey() { }
30 };
31 
32 struct AgentOperDBData : public AgentData {
33 
35  AgentData(), agent_(agent) {
36  SetIFMapNode(node);
37  }
38  virtual ~AgentOperDBData() {
39  SetIFMapNode(NULL);
40  }
41 
42 
43  void SetIFMapNode(IFMapNode *node) {
44 
45  if (node == NULL) {
46  ifmap_node_state_ = NULL;
47  return;
48  }
49 
50  assert(agent_);
51 
52  // We dont allow changing the node
53  assert(!ifmap_node_state_);
54 
56  ifmap_node_state_ = dep->SetState(node);
57  }
58 
59  IFMapNode *ifmap_node() const {
60  if (!ifmap_node_state_)
61  return NULL;
62  IFMapNodeState *state = ifmap_node_state_.get();
63  return state->node();
64  }
65  const Agent *agent() const {
66  return agent_;
67  }
68 private:
69  const Agent *agent_;
70  // IFMap Node pointer for the object
72 };
73 
75 public:
77  virtual ~AgentOperDBEntry() { }
78 
79  IFMapNode *ifmap_node() const {
80  if (!ifmap_node_state_)
81  return NULL;
82  IFMapNodeState *state = ifmap_node_state_.get();
83  return state->node();
84  }
85 
87  ifmap_node_state_ = sref;
88  }
89 private:
90  friend class AgentOperDBTable;
93 };
94 
96 public:
97  AgentOperDBTable(DB *db, const std::string &name) :
98  AgentDBTable(db, name) {
99  }
100 
101  AgentOperDBTable(DB *db, const std::string &name,
102  bool del_on_zero_refcount) :
103  AgentDBTable(db, name, del_on_zero_refcount) {
104  }
105  virtual ~AgentOperDBTable() { }
106 
107  // AgentOperDBTable implements Add/OnChange/Delete/Resync APIs for
108  // AgentDBTable. They will in-turn invoke
109  // OperDBAdd/OperDBOnChange/OperDBDelete/OperDBResync correspondingly
110  virtual DBEntry *OperDBAdd(const DBRequest *req) = 0;
111  virtual bool OperDBOnChange(DBEntry *entry, const DBRequest *req) = 0;
112  virtual bool OperDBDelete(DBEntry *entry, const DBRequest *req) = 0;
113  virtual bool OperDBResync(DBEntry *entry, const DBRequest *req) {
114  return false;
115  }
116 
117  // Default callback handler from IFMap Dependency tracker. We invoke
118  // IFNodeToReq to keep all IFMap handling at one place
119 
120  virtual void ConfigEventHandler(IFMapNode *node, DBEntry *entry) {
121  DBRequest req;
123  boost::uuids::uuid new_uuid = boost::uuids::nil_uuid();
124  bool uuid_set = IFNodeToUuid(node, new_uuid);
125  IFMapNodeState *state = dep->IFMapNodeGet(node);
126  boost::uuids::uuid old_uuid = state->uuid();
127 
128  if (!node->IsDeleted()) {
129  if (entry) {
130  if ((old_uuid != new_uuid)) {
131  if (old_uuid != boost::uuids::nil_uuid()) {
133  if (IFNodeToReq(node, req, old_uuid) == true) {
134  assert(req.oper == DBRequest::DB_ENTRY_DELETE);
135  Enqueue(&req);
136  }
137  }
138  }
139  }
140  if (uuid_set && dep->IsNodeIdentifiedByUuid(node)) {
141  assert(new_uuid != boost::uuids::nil_uuid());
142  }
143  state->set_uuid(new_uuid);
144  state->set_oper_db_request_enqueued(true);
146  } else {
148  if (uuid_set && (old_uuid == boost::uuids::nil_uuid()) &&
149  (dep->IsNodeIdentifiedByUuid(node))) {
150  //Node was never added so no point sending delete
151  return;
152  }
153  new_uuid = old_uuid;
154  if (state) {
155  state->set_oper_db_request_enqueued(false);
156  }
157  }
158 
159  if (IFNodeToReq(node, req, new_uuid) == true) {
160  Enqueue(&req);
161  }
162 
163  return;
164  }
165 
166 protected:
167  // Handle change in IFMapNode for a DBEntry
169  if (entry == NULL)
170  return;
171 
172  IFMapNode *old_node = entry->ifmap_node();
173 
174  if (old_node == node)
175  return;
176 
178  if (old_node) {
179  dep->SetObject(old_node, NULL);
180  entry->SetIFMapNodeState(NULL);
181  }
182 
183  if (node) {
184  entry->SetIFMapNodeState(dep->SetState(node));
185  dep->SetObject(node, entry);
186  }
187  }
188 
189  // Implement Add, Delete, OnChange to provide common agent functionality
190  // including,
191  virtual DBEntry *Add(const DBRequest *req) {
192  AgentOperDBEntry *entry = static_cast<AgentOperDBEntry *>
193  (OperDBAdd(req));
194  AgentOperDBData *data = static_cast<AgentOperDBData *>(req->data.get());
195  if (data && data->ifmap_node())
196  UpdateIfMapNode(entry, data->ifmap_node());
197  return entry;
198  }
199 
200  virtual bool OnChange(DBEntry *entry, const DBRequest *req) {
201  AgentOperDBEntry *oper_entry = static_cast<AgentOperDBEntry *>(entry);
202  bool ret = OperDBOnChange(entry, req);
203 
204  AgentOperDBData *data = static_cast<AgentOperDBData *>(req->data.get());
205  if (data && data->ifmap_node())
206  UpdateIfMapNode(oper_entry, data->ifmap_node());
207  return ret;
208  }
209 
210  virtual bool Resync(DBEntry *entry, const DBRequest *req) {
211  AgentOperDBEntry *oper_entry = static_cast<AgentOperDBEntry *>(entry);
212  bool ret = OperDBResync(entry, req);
213 
214  AgentOperDBData *data = static_cast<AgentOperDBData *>(req->data.get());
215  if (data && data->ifmap_node())
216  UpdateIfMapNode(oper_entry, data->ifmap_node());
217  return ret;
218  }
219 
220  virtual bool Delete(DBEntry *entry, const DBRequest *req) {
221  AgentOperDBEntry *oper_entry = static_cast<AgentOperDBEntry *>(entry);
222  bool ret = OperDBDelete(entry, req);
223 
224  UpdateIfMapNode(oper_entry, NULL);
225  return ret;
226  }
227 
228 private:
230 };
231 
232 // Oper-DB works on few IFMap tables which do not have corresponding
233 // oper DBTable.
234 // Example : virtual-router, network-ipam etc...
235 // The IFMap nodes are registered with ifmap-dependency-manager. The class
236 // OperIFMapTable is responsible to manage notifications of such IFMap tables
238 public:
239  typedef std::map<IFMapNode *, IFMapDependencyManager::IFMapNodePtr> Tree;
240  OperIFMapTable(Agent *agent) : agent_(agent), oper_(agent->oper_db()) { }
241  virtual ~OperIFMapTable() {
242  assert(tree_.size() == 0);
243  }
244 
245  Agent *agent() const { return agent_; }
246  OperDB *oper() const { return oper_; }
247  uint32_t Size() const { return tree_.size(); }
248 
249  // Callback from ifmap-dependnecy-manager
250  void ConfigEventHandler(IFMapNode *node, DBEntry *entry) {
251  if (node->IsDeleted()) {
252  ConfigDelete(node);
253  tree_.erase(node);
254  return;
255  }
256 
257  ConfigManagerEnqueue(node);
258  return;
259  }
260 
261  // Callback from config-manager
262  void ProcessConfig(IFMapNode *node) {
263  if (node->IsDeleted()) {
264  return;
265  }
266 
268  tree_.insert(std::make_pair(node, dep->SetState(node)));
269  ConfigAddChange(node);
270  }
271 
272  virtual void ConfigDelete(IFMapNode *node) = 0;
273  virtual void ConfigAddChange(IFMapNode *node) = 0;
274  virtual void ConfigManagerEnqueue(IFMapNode *node) = 0;
275 private:
280 };
281 #endif // SRC_VNSW_AGENT_OPER_OPER_DB_H_
boost::uuids::uuid uuid()
AgentOperDBData(const Agent *agent, IFMapNode *node)
Definition: oper_db.h:34
DISALLOW_COPY_AND_ASSIGN(AgentOperDBTable)
IFMapDependencyManager::IFMapNodePtr ifmap_node_state_
Definition: oper_db.h:91
AgentOperDBTable(DB *db, const std::string &name)
Definition: oper_db.h:97
void UpdateIfMapNode(AgentOperDBEntry *entry, IFMapNode *node)
Definition: oper_db.h:168
Agent * agent() const
Definition: oper_db.h:245
void SetObject(IFMapNode *node, DBEntry *entry)
virtual ~AgentOperDBData()
Definition: oper_db.h:38
Agent * agent_
Definition: oper_db.h:276
IFMapNodeState * IFMapNodeGet(IFMapNode *node)
void set_uuid(const boost::uuids::uuid &u)
bool IsDeleted() const
Definition: db_entry.h:49
Agent * agent() const
Definition: agent_db.h:213
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
void SetIFMapNode(IFMapNode *node)
Definition: oper_db.h:43
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
boost::uuids::uuid uuid
virtual bool OperDBDelete(DBEntry *entry, const DBRequest *req)=0
IFMapNode * ifmap_node() const
Definition: oper_db.h:79
AgentOperDBKey(DBSubOperation sub_op)
Definition: oper_db.h:28
std::map< IFMapNode *, IFMapDependencyManager::IFMapNodePtr > Tree
Definition: oper_db.h:239
AgentOperDBKey()
Definition: oper_db.h:27
DISALLOW_COPY_AND_ASSIGN(OperIFMapTable)
OperDB * oper_db() const
Definition: agent.cc:1013
IFMapDependencyManager * dependency_manager()
Definition: operdb_init.h:61
Definition: db.h:24
AgentOperDBTable(DB *db, const std::string &name, bool del_on_zero_refcount)
Definition: oper_db.h:101
void ConfigEventHandler(IFMapNode *node, DBEntry *entry)
Definition: oper_db.h:250
const Agent * agent_
Definition: oper_db.h:69
Definition: agent.h:358
uint32_t Size() const
Definition: oper_db.h:247
DISALLOW_COPY_AND_ASSIGN(AgentOperDBEntry)
OperDB * oper() const
Definition: oper_db.h:246
virtual void ConfigDelete(IFMapNode *node)=0
virtual DBEntry * OperDBAdd(const DBRequest *req)=0
virtual ~AgentOperDBEntry()
Definition: oper_db.h:77
DBOperation oper
Definition: db_table.h:42
void ProcessConfig(IFMapNode *node)
Definition: oper_db.h:262
virtual void ConfigAddChange(IFMapNode *node)=0
const std::string & name() const
Definition: db_table.h:110
virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &id)
Definition: agent_db.cc:183
bool IsNodeIdentifiedByUuid(const IFMapNode *node)
virtual ~AgentOperDBTable()
Definition: oper_db.h:105
IFMapNodePtr SetState(IFMapNode *node)
IFMapNode * ifmap_node() const
Definition: oper_db.h:59
OperDB * oper_
Definition: oper_db.h:277
virtual bool Resync(DBEntry *entry, const DBRequest *req)
Definition: oper_db.h:210
const Agent * agent() const
Definition: oper_db.h:65
virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req, const boost::uuids::uuid &uuid)
Definition: agent_db.h:167
virtual DBEntry * Add(const DBRequest *req)
Definition: oper_db.h:191
boost::intrusive_ptr< IFMapNodeState > IFMapNodePtr
OperIFMapTable(Agent *agent)
Definition: oper_db.h:240
virtual bool OperDBResync(DBEntry *entry, const DBRequest *req)
Definition: oper_db.h:113
DBSubOperation
Definition: agent_db.h:96
IFMapDependencyManager::IFMapNodePtr ifmap_node_state_
Definition: oper_db.h:71
void set_oper_db_request_enqueued(bool oper_db_request_enqueued)
virtual bool OnChange(DBEntry *entry, const DBRequest *req)
Definition: oper_db.h:200
virtual bool OperDBOnChange(DBEntry *entry, const DBRequest *req)=0
virtual void ConfigEventHandler(IFMapNode *node, DBEntry *entry)
Definition: oper_db.h:120
void SetIFMapNodeState(IFMapDependencyManager::IFMapNodePtr sref)
Definition: oper_db.h:86
virtual ~AgentOperDBKey()
Definition: oper_db.h:29
virtual void ConfigManagerEnqueue(IFMapNode *node)=0
virtual bool Delete(DBEntry *entry, const DBRequest *req)
Definition: oper_db.h:220
virtual ~OperIFMapTable()
Definition: oper_db.h:241