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