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 522 : void IFMapAgentParser::NodeParse(xml_node &node, DBRequest::DBOperation oper, uint64_t seq) { 27 : 28 522 : const char *name = node.attribute("type").value(); 29 : int msg_type; 30 522 : if (oper == DBRequest::DB_ENTRY_ADD_CHANGE) 31 285 : msg_type = UPDATE; 32 : else 33 237 : msg_type = DEL; 34 : 35 : IFMapTable *table; 36 522 : table = IFMapTable::FindTable(db_, name); 37 522 : if(!table) { 38 0 : node_parse_errors_[msg_type]++; 39 0 : return; 40 : } 41 : 42 : // Locate the decode function using id_name 43 522 : NodeParseMap::const_iterator loc = node_map_.find(name); 44 522 : if (loc == node_map_.end()) { 45 0 : node_parse_errors_[msg_type]++; 46 0 : return; 47 : } 48 : 49 : IFMapObject *obj; 50 522 : IFMapTable::RequestKey *req_key = new IFMapTable::RequestKey; 51 : 52 : // Invoke the decode routine 53 522 : req_key->id_type = name; 54 522 : req_key->id_seq_num = seq; 55 522 : obj = loc->second(node, db_, &req_key->id_name); 56 522 : if (!obj) { 57 0 : node_parse_errors_[msg_type]++; 58 0 : delete req_key; 59 0 : return; 60 : } 61 : 62 522 : IFMapAgentTable::IFMapAgentData *req_data = new IFMapAgentTable::IFMapAgentData; 63 522 : req_data->content.reset(obj); 64 : 65 522 : unique_ptr<DBRequest> request(new DBRequest); 66 522 : request->oper = oper; 67 522 : request->data.reset(req_data); 68 522 : request->key.reset(req_key); 69 522 : table->Enqueue(request.get()); 70 522 : } 71 : 72 652 : void IFMapAgentParser::LinkParse(xml_node &link, DBRequest::DBOperation oper, uint64_t seq) { 73 : 74 652 : xml_node first_node; 75 652 : xml_node second_node; 76 652 : xml_node name_node1; 77 652 : 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 652 : if (oper == DBRequest::DB_ENTRY_ADD_CHANGE) 85 330 : msg_type = UPDATE; 86 : else 87 322 : msg_type = DEL; 88 : 89 : link_table = static_cast<IFMapAgentLinkTable *>( 90 652 : db_->FindTable(IFMAP_AGENT_LINK_DB_NAME)); 91 : 92 652 : assert(link_table); 93 : 94 : // Get both first and second node and its corresponding tables 95 652 : first_node = link.first_child(); 96 652 : if (!first_node) { 97 0 : link_parse_errors_[msg_type]++; 98 0 : return; 99 : } 100 : 101 652 : second_node = first_node.next_sibling(); 102 652 : if (!second_node) { 103 0 : link_parse_errors_[msg_type]++; 104 0 : return; 105 : } 106 : 107 652 : name1 = first_node.attribute("type").value(); 108 652 : table = IFMapTable::FindTable(db_, name1); 109 652 : if(!table) { 110 0 : link_parse_errors_[msg_type]++; 111 0 : return; 112 : } 113 : 114 652 : name2 = second_node.attribute("type").value(); 115 652 : table = IFMapTable::FindTable(db_, name2); 116 652 : if(!table) { 117 0 : link_parse_errors_[msg_type]++; 118 0 : return; 119 : } 120 : 121 : // Get id_name of both the nodes 122 652 : name_node1 = first_node.first_child(); 123 652 : if (!name_node1) { 124 0 : link_parse_errors_[msg_type]++; 125 0 : return; 126 : } 127 : 128 652 : if (strcmp(name_node1.name(), "name") != 0) { 129 0 : link_parse_errors_[msg_type]++; 130 0 : return; 131 : } 132 : 133 652 : name_node2 = second_node.first_child(); 134 652 : if (!name_node2) { 135 0 : link_parse_errors_[msg_type]++; 136 0 : return; 137 : } 138 : 139 652 : 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 652 : unique_ptr <IFMapAgentLinkTable::RequestKey> req_key (new IFMapAgentLinkTable::RequestKey); 146 652 : req_key->left_key.id_name = name_node1.child_value(); 147 652 : req_key->left_key.id_type = name1; 148 652 : req_key->left_key.id_seq_num = seq; 149 : 150 652 : req_key->right_key.id_name = name_node2.child_value(); 151 652 : req_key->right_key.id_type = name2; 152 652 : req_key->right_key.id_seq_num = seq; 153 : 154 652 : xml_node metadata = link.child("metadata"); 155 652 : if (metadata) { 156 652 : req_key->metadata = metadata.attribute("type").value(); 157 : } 158 : 159 652 : unique_ptr <DBRequest> req (new DBRequest); 160 652 : req->oper = oper; 161 652 : req->key = std::move(req_key); 162 : 163 652 : link_table->Enqueue(req.get()); 164 652 : } 165 : 166 1114 : void IFMapAgentParser::ConfigParse(const xml_node config, const uint64_t seq) { 167 : 168 : DBRequest::DBOperation oper; 169 : 170 2228 : for (xml_node node = config.first_child(); node; 171 1114 : node = node.next_sibling()) { 172 : 173 : int msg_type; 174 1114 : if (strcmp(node.name(), "update") == 0) { 175 585 : oper = DBRequest::DB_ENTRY_ADD_CHANGE; 176 585 : msg_type = UPDATE; 177 529 : } else if (strcmp(node.name(), "delete") == 0) { 178 529 : oper = DBRequest::DB_ENTRY_DELETE; 179 529 : msg_type = DEL; 180 : } else { 181 0 : continue; 182 : } 183 : 184 2288 : for(xml_node chld = node.first_child(); chld; chld = chld.next_sibling()) { 185 : 186 : // Handle the links between the nodes 187 1174 : if (strcmp(chld.name(), "link") == 0) { 188 652 : links_processed_[msg_type]++; 189 652 : LinkParse(chld, oper, seq); 190 652 : continue; 191 : } 192 : 193 522 : if (strcmp(chld.name(), "node") == 0) { 194 522 : nodes_processed_[msg_type]++; 195 522 : NodeParse(chld, oper, seq); 196 : } 197 : } 198 : } 199 1114 : }