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