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