OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ifmap_agent_parser.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include <vector>
8 #include <pugixml/pugixml.hpp>
9 #include "base/logging.h"
10 #include "db/db_entry.h"
12 
13 using namespace std;
14 using namespace pugi;
15 
16 void IFMapAgentParser::NodeRegister(const string &node, NodeParseFn parser) {
17  pair<NodeParseMap::iterator, bool> result =
18  node_map_.insert(make_pair(node, parser));
19  assert(result.second);
20 }
21 
23  node_map_.clear();
24 }
25 
26 void IFMapAgentParser::NodeParse(xml_node &node, DBRequest::DBOperation oper, uint64_t seq) {
27 
28  const char *name = node.attribute("type").value();
29  int msg_type;
31  msg_type = UPDATE;
32  else
33  msg_type = DEL;
34 
35  IFMapTable *table;
36  table = IFMapTable::FindTable(db_, name);
37  if(!table) {
38  node_parse_errors_[msg_type]++;
39  return;
40  }
41 
42  // Locate the decode function using id_name
43  NodeParseMap::const_iterator loc = node_map_.find(name);
44  if (loc == node_map_.end()) {
45  node_parse_errors_[msg_type]++;
46  return;
47  }
48 
49  IFMapObject *obj;
51 
52  // Invoke the decode routine
53  req_key->id_type = name;
54  req_key->id_seq_num = seq;
55  obj = loc->second(node, db_, &req_key->id_name);
56  if (!obj) {
57  node_parse_errors_[msg_type]++;
58  delete req_key;
59  return;
60  }
61 
63  req_data->content.reset(obj);
64 
65  unique_ptr<DBRequest> request(new DBRequest);
66  request->oper = oper;
67  request->data.reset(req_data);
68  request->key.reset(req_key);
69  table->Enqueue(request.get());
70 }
71 
72 void IFMapAgentParser::LinkParse(xml_node &link, DBRequest::DBOperation oper, uint64_t seq) {
73 
74  xml_node first_node;
75  xml_node second_node;
76  xml_node name_node1;
77  xml_node name_node2;
78  const char *name1;
79  const char *name2;
80  IFMapTable *table;
81  IFMapAgentLinkTable *link_table;
82 
83  int msg_type;
85  msg_type = UPDATE;
86  else
87  msg_type = DEL;
88 
89  link_table = static_cast<IFMapAgentLinkTable *>(
90  db_->FindTable(IFMAP_AGENT_LINK_DB_NAME));
91 
92  assert(link_table);
93 
94  // Get both first and second node and its corresponding tables
95  first_node = link.first_child();
96  if (!first_node) {
97  link_parse_errors_[msg_type]++;
98  return;
99  }
100 
101  second_node = first_node.next_sibling();
102  if (!second_node) {
103  link_parse_errors_[msg_type]++;
104  return;
105  }
106 
107  name1 = first_node.attribute("type").value();
108  table = IFMapTable::FindTable(db_, name1);
109  if(!table) {
110  link_parse_errors_[msg_type]++;
111  return;
112  }
113 
114  name2 = second_node.attribute("type").value();
115  table = IFMapTable::FindTable(db_, name2);
116  if(!table) {
117  link_parse_errors_[msg_type]++;
118  return;
119  }
120 
121  // Get id_name of both the nodes
122  name_node1 = first_node.first_child();
123  if (!name_node1) {
124  link_parse_errors_[msg_type]++;
125  return;
126  }
127 
128  if (strcmp(name_node1.name(), "name") != 0) {
129  link_parse_errors_[msg_type]++;
130  return;
131  }
132 
133  name_node2 = second_node.first_child();
134  if (!name_node2) {
135  link_parse_errors_[msg_type]++;
136  return;
137  }
138 
139  if (strcmp(name_node2.name(), "name") != 0) {
140  link_parse_errors_[msg_type]++;
141  return;
142  }
143 
144  // Create both the request keys
145  unique_ptr <IFMapAgentLinkTable::RequestKey> req_key (new IFMapAgentLinkTable::RequestKey);
146  req_key->left_key.id_name = name_node1.child_value();
147  req_key->left_key.id_type = name1;
148  req_key->left_key.id_seq_num = seq;
149 
150  req_key->right_key.id_name = name_node2.child_value();
151  req_key->right_key.id_type = name2;
152  req_key->right_key.id_seq_num = seq;
153 
154  xml_node metadata = link.child("metadata");
155  if (metadata) {
156  req_key->metadata = metadata.attribute("type").value();
157  }
158 
159  unique_ptr <DBRequest> req (new DBRequest);
160  req->oper = oper;
161  req->key = std::move(req_key);
162 
163  link_table->Enqueue(req.get());
164 }
165 
166 void IFMapAgentParser::ConfigParse(const xml_node config, const uint64_t seq) {
167 
169 
170  for (xml_node node = config.first_child(); node;
171  node = node.next_sibling()) {
172 
173  int msg_type;
174  if (strcmp(node.name(), "update") == 0) {
176  msg_type = UPDATE;
177  } else if (strcmp(node.name(), "delete") == 0) {
179  msg_type = DEL;
180  } else {
181  continue;
182  }
183 
184  for(xml_node chld = node.first_child(); chld; chld = chld.next_sibling()) {
185 
186  // Handle the links between the nodes
187  if (strcmp(chld.name(), "link") == 0) {
188  links_processed_[msg_type]++;
189  LinkParse(chld, oper, seq);
190  continue;
191  }
192 
193  if (strcmp(chld.name(), "node") == 0) {
194  nodes_processed_[msg_type]++;
195  NodeParse(chld, oper, seq);
196  }
197  }
198  }
199 }
void LinkParse(pugi::xml_node &node, DBRequest::DBOperation oper, uint64_t seq)
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
void NodeRegister(const std::string &node, NodeParseFn parser)
void ConfigParse(const pugi::xml_node config, uint64_t seq)
void NodeParse(pugi::xml_node &node, DBRequest::DBOperation oper, uint64_t seq)
static IFMapTable * FindTable(DB *db, const std::string &element_type)
Definition: ifmap_table.cc:39
std::unique_ptr< IFMapObject > content
#define IFMAP_AGENT_LINK_DB_NAME
boost::function< IFMapObject *(const pugi::xml_node, DB *, std::string *id_name) > NodeParseFn