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