LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-analytics/contrail-collector - structured_syslog_config.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 27 478 5.6 %
Date: 2026-11-09 02:10:49 Functions: 3 29 10.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : 
       7             : #include <sstream>
       8             : #include <boost/make_shared.hpp>
       9             : #include <boost/asio.hpp>
      10             : #include <analytics/analytics_types.h>
      11             : #include "base/regex.h"
      12             : #include "analytics_types.h"
      13             : #include "structured_syslog_config.h"
      14             : #include "options.h"
      15             : #include <base/logging.h>
      16             : #include <boost/bind/bind.hpp>
      17             : #include "rapidjson/document.h"
      18             : #include "rapidjson/writer.h"
      19             : #include "rapidjson/stringbuffer.h"
      20             : 
      21             : using boost::regex_error;
      22             : using contrail::regex;
      23             : using contrail::regex_match;
      24             : using contrail::regex_search;
      25             : using namespace boost::placeholders;
      26             : 
      27          11 : StructuredSyslogConfig::StructuredSyslogConfig(ConfigClientCollector *config_client, uint64_t structured_syslog_active_session_map_limit) {
      28          11 :     activeSessionConfigMapLIMIT = structured_syslog_active_session_map_limit;
      29          11 :     LOG(INFO, "StructuredSyslogConfig:Num of active session LIMIT in session config map: " << activeSessionConfigMapLIMIT);
      30          11 :     if (config_client) {
      31           0 :         config_client->RegisterConfigReceive("structured-systemlog", boost::bind(
      32             :                                  &StructuredSyslogConfig::ReceiveConfig, this, _1, _2));
      33             :     }
      34          11 : }
      35             : 
      36          11 : StructuredSyslogConfig::~StructuredSyslogConfig() {
      37          11 :     hostname_records_.erase(hostname_records_.begin(),
      38          11 :                             hostname_records_.end());
      39          11 :     tenant_records_.erase(tenant_records_.begin(),
      40          11 :                             tenant_records_.end());
      41          11 :     application_records_.erase(application_records_.begin(),
      42          11 :                                application_records_.end());
      43          11 :     tenant_application_records_.erase(tenant_application_records_.begin(),
      44          11 :                                       tenant_application_records_.end());
      45          11 :     networks_map_.erase(networks_map_.begin(), networks_map_.end());
      46          11 :     session_config_map_.erase(session_config_map_.begin(),
      47          11 :                                 session_config_map_.end());
      48          11 : }
      49             : 
      50             : 
      51             : bool 
      52           0 : StructuredSyslogConfig::AddSyslogSessionCounter(const std::string session_unique_key, 
      53             :                                                 std::map<std::string, uint64_t> session_traffic_counters) {
      54             :     try {
      55           0 :         SyslogSessionConfig::iterator it = session_config_map_.find(session_unique_key);
      56           0 :         if (it != session_config_map_.end()) {
      57           0 :             LOG(DEBUG, "Session key found in session counter map.");
      58             :         }
      59             :         else {
      60           0 :             LOG(DEBUG, "Session key NOT found in session counter map.");
      61             :             //Put a Limit to num of session entries in the map.
      62           0 :             if(session_config_map_.size() >= activeSessionConfigMapLIMIT) {
      63           0 :                 LOG(ERROR, "active sessions Config Map LIMIT reached. Current active session count: "<< session_config_map_.size());
      64           0 :                 return false;
      65             :             }
      66             :         }
      67           0 :         LOG(DEBUG, "Adding/Replacing session traffic counters for session key " << session_unique_key);
      68           0 :         session_config_map_[session_unique_key] = session_traffic_counters;
      69           0 :         return true;
      70             :     }
      71           0 :     catch (std::exception &e) {
      72           0 :         LOG(ERROR, "Adding session traffic counters failed for session key: " << session_unique_key);
      73           0 :         return false;
      74           0 :     }
      75             :  }
      76             : 
      77             : int 
      78           0 : StructuredSyslogConfig::RemoveSyslogSessionCounter(const std::string &session_unique_key) {
      79             :     try {
      80           0 :         LOG(DEBUG, "Removing Syslog Session Counter for " << session_unique_key);
      81           0 :         return session_config_map_.erase(session_unique_key);
      82             :     }
      83           0 :     catch (std::exception &e) {
      84           0 :         LOG(ERROR, "Removing session traffic counters failed for session key: " << session_unique_key);
      85           0 :         return 0;
      86           0 :     }
      87             : }
      88             : 
      89             : bool
      90           0 : StructuredSyslogConfig::FetchSyslogSessionCounters(const std::string &session_unique_key,
      91             :                                                     std::map<std::string, uint64_t> &session_traffic_counters) {
      92             :     try {
      93           0 :         SyslogSessionConfig::iterator itr = session_config_map_.find(session_unique_key);
      94           0 :         if (itr != session_config_map_.end()) {
      95           0 :             session_traffic_counters = itr->second;
      96           0 :             return true;
      97             :         }
      98             :         else{
      99           0 :             LOG(DEBUG, "Session counters not found for session key: " << session_unique_key);
     100           0 :             return false;
     101             :         }
     102             :     }
     103           0 :     catch (std::exception &e) {
     104           0 :         LOG(ERROR, "ERROR in fetching Session traffic counters for session key: " << session_unique_key);
     105           0 :         return false;
     106           0 :     }
     107             : }
     108             : 
     109             : /*  Return int 4 when IP belongs to protocol IPv4 or
     110             :     Return int 6 when IP belongs to protocol IPv6, otherwise
     111             :     Return int -1 if IP is not valid */
     112             : int
     113           0 : StructuredSyslogConfig::get_ip_version (const std::string ip) {
     114           0 :     int version = -1;
     115             :     try {
     116           0 :         boost::asio::ip::address addr = boost::asio::ip::address::from_string(ip);
     117           0 :         if (addr.is_v4())
     118           0 :             version = 4;
     119           0 :         else if (addr.is_v6())
     120           0 :             version = 6;
     121             :     }
     122           0 :     catch (std::exception &e){
     123           0 :         LOG(ERROR, "IP : "<< ip <<" found while checking IP protocol is invalid. ERROR: " << e.what());
     124           0 :     }
     125           0 :     return version;
     126             : }
     127             : 
     128             : uint32_t
     129           0 : StructuredSyslogConfig::IPToUInt(std::string ip) {
     130             :     int a, b, c, d;
     131           0 :     uint32_t addr = 0;
     132             : 
     133           0 :     if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
     134           0 :         return 0;
     135             : 
     136           0 :     addr = a << 24;
     137           0 :     addr |= b << 16;
     138           0 :     addr |= c << 8;
     139           0 :     addr |= d;
     140           0 :     return addr;
     141             : }
     142             : 
     143             : std::vector<std::string>
     144           0 : StructuredSyslogConfig::split_into_vector(std::string  str, char delimiter) {
     145           0 :     std::vector<std::string> list;
     146           0 :     std::stringstream ss(str);
     147           0 :     std::string s;
     148           0 :     while(getline(ss, s, delimiter)){
     149           0 :         list.push_back(s);
     150             :     }
     151           0 :     return list;
     152           0 : }
     153             : 
     154             : 
     155             : 
     156             : bool
     157           0 : StructuredSyslogConfig::AddNetwork(const std::string& key, const std::string& network, const std::string& mask, const std::string& location)
     158             : {
     159           0 :     uint32_t network_addr = IPToUInt(network);
     160           0 :     uint32_t mask_addr = IPToUInt(mask);
     161             : 
     162           0 :     uint32_t net_lower = (network_addr & mask_addr);
     163           0 :     uint32_t net_upper = (net_lower | (~mask_addr));
     164             : 
     165           0 :     std::string id = location;
     166           0 :     IPNetwork net(net_lower, net_upper, id);
     167           0 :     std::scoped_lock lock(networks_map_refresh_mutex);
     168             : 
     169           0 :     IPNetworks_map::iterator it = networks_map_.find(key);
     170           0 :     if (it  != networks_map_.end()) {
     171           0 :         LOG(DEBUG, "VPN name found in Networks MAP while adding network. Appending to existing values of VPN key... ");
     172             :         //sorted insertion into vector
     173           0 :         it->second.insert(std::upper_bound(it->second.begin(), it->second.end(), net), net);
     174           0 :         LOG(DEBUG, "IPNetwork with destination address " << network_addr << " added in networks_map with VPN key " << key);
     175             :     } else {
     176           0 :         LOG(DEBUG, "VPN name NOT found in Networks MAP while adding network. Creating a new entry in Networks MAP ...");
     177           0 :         IPNetworks  new_network;
     178           0 :         new_network.push_back(net);
     179           0 :         networks_map_.insert(std::make_pair(key, new_network) );
     180           0 :         LOG(DEBUG, "IPNetwork with destination address " << network_addr << " added in networks_map with VPN key " << key);
     181           0 :     }
     182           0 :     return true;
     183           0 : }
     184             : 
     185             : 
     186             : bool
     187           0 : StructuredSyslogConfig::RefreshNetworksMap(const std::string location){
     188             : 
     189           0 :     std::scoped_lock lock(networks_map_refresh_mutex);
     190           0 :     for(IPNetworks_map::iterator it = networks_map_.begin(); it != networks_map_.end(); it++){
     191           0 :         std::vector<int> indexes_to_be_deleted;
     192           0 :         for(IPNetworks::iterator i = it->second.begin(); i != it->second.end(); i++) {
     193           0 :             if (location == i->id){
     194           0 :                 LOG(DEBUG, "Location " << i->id << " to be deleted from Networks MAP with VPN " << it->first );
     195           0 :                 indexes_to_be_deleted.push_back(i - it->second.begin());
     196             :             }
     197             :         }
     198           0 :         for(std::vector<int>::reverse_iterator v = indexes_to_be_deleted.rbegin(); v != indexes_to_be_deleted.rend(); ++v) {
     199           0 :             IPNetworks::iterator i = it->second.begin();
     200           0 :             it->second.erase(*v + i);
     201             :         }
     202           0 :     }
     203           0 :     LOG(INFO, "Networks MAP Refreshed!" );
     204           0 :     return true;
     205           0 : }
     206             : 
     207             : std::string
     208           0 : StructuredSyslogConfig::FindNetwork(std::string ip,  std::string key, std::string src_location)
     209             : {
     210           0 :     uint32_t network_addr = IPToUInt(ip);
     211           0 :     IPNetwork ip_network(network_addr, 0, ip);
     212           0 :     std::string unknown_location;
     213             : 
     214           0 :     IPNetworks_map::iterator it = networks_map_.find(key);
     215           0 :     if (it  != networks_map_.end()) {
     216           0 :         IPNetworks::iterator upper = std::upper_bound(it->second.begin(), it->second.end(), ip_network);
     217             : 
     218           0 :         uint32_t idx = upper - it->second.begin();
     219           0 :         if (idx <= it->second.size() && idx != 0){
     220           0 :             IPNetwork found_network_obj(0, 0, unknown_location);
     221           0 :             uint32_t min_range = UINT32_MAX;
     222             :             //check for last idx (idx-1) before upper_bound idx.
     223             :             //check for overlapping IP ranges in loop.
     224             :             //network with min. range should take priority.
     225           0 :             for (int i = idx - 1; i >= 0; i--) {
     226           0 :                 IPNetwork possible_network_obj = it->second[i];
     227           0 :                 LOG(DEBUG, "Checking for possible network-range match location " << possible_network_obj.id);
     228           0 :                 uint32_t possible_network_range = possible_network_obj.address_end - possible_network_obj.address_begin;
     229           0 :                 if ((network_addr >= possible_network_obj.address_begin)
     230           0 :                     && (network_addr <= possible_network_obj.address_end)) {
     231           0 :                     if (possible_network_range < min_range) {
     232           0 :                         if (possible_network_obj.id != src_location) {
     233           0 :                             found_network_obj = possible_network_obj;
     234           0 :                             min_range = possible_network_range;
     235           0 :                             LOG(DEBUG, "Possible Network found for " << ip << " from Tenant::VPN " <<  key << 
     236             :                                 " in Site : " << found_network_obj.id  << " with range : " << possible_network_range);
     237             :                         }
     238             :                     }
     239             :                 }
     240             : 
     241           0 :             }
     242           0 :             if (!(found_network_obj.id.empty())) {
     243           0 :                 LOG(DEBUG, "Network found for " << ip << " from Tenant::VPN " <<  key << 
     244             :                     " in Site : " << found_network_obj.id );
     245           0 :                 return found_network_obj.id;
     246             :             }
     247             :             else {
     248           0 :                 LOG(DEBUG,"Network address "<< ip <<" doesnt not belong to the found range " 
     249             :                     << found_network_obj.address_begin << " - " << found_network_obj.address_end << " in Tenant::VPN " << key);
     250             :             }
     251           0 :         }
     252             :         else{
     253           0 :             LOG(DEBUG,"Network range not found for " << ip << " in Tenant::VPN " << key );
     254             :         }
     255             :     }
     256             :     else {
     257           0 :         LOG(DEBUG, "Tenant::VPN "<< key << " NOT found in Network MAP!");
     258             :     }
     259           0 :     return unknown_location;
     260           0 :  }
     261             : 
     262             : void
     263           0 : StructuredSyslogConfig::HostnameRecordsHandler(const contrail_rapidjson::Document &jdoc,
     264             :                                                bool add_update) {
     265           0 :     if (jdoc.IsObject() && jdoc.HasMember("structured_syslog_hostname_record")) {
     266           0 :         const contrail_rapidjson::Value& hr = jdoc["structured_syslog_hostname_record"];
     267           0 :         std::string name, hostaddr, tenant, location, device, tags;
     268           0 :         std::map< std::string, std::string > linkmap;
     269           0 :         bool location_exists = false;
     270             : 
     271           0 :         if (hr.HasMember("fq_name")) {
     272           0 :             const contrail_rapidjson::Value& fq_name = hr["fq_name"];
     273           0 :             contrail_rapidjson::SizeType sz = fq_name.Size();
     274           0 :             name = fq_name[sz-1].GetString();
     275           0 :             LOG(DEBUG, "NAME got from fq_name: " << name);
     276             :         }
     277           0 :         if (hr.HasMember("structured_syslog_hostaddr")) {
     278           0 :             hostaddr = hr["structured_syslog_hostaddr"].GetString();
     279             :         }
     280           0 :         if (hr.HasMember("structured_syslog_tenant")) {
     281           0 :             tenant = hr["structured_syslog_tenant"].GetString();
     282             :         }
     283           0 :         if (hr.HasMember("structured_syslog_location")) {
     284           0 :             location = hr["structured_syslog_location"].GetString();
     285             :         }
     286           0 :         if (hr.HasMember("structured_syslog_device")) {
     287           0 :             device = hr["structured_syslog_device"].GetString();
     288             :         }
     289           0 :         if (hr.HasMember("structured_syslog_hostname_tags")) {
     290           0 :             tags = hr["structured_syslog_hostname_tags"].GetString();
     291             :         }
     292           0 :         if (hr.HasMember("structured_syslog_linkmap")) {
     293           0 :             const contrail_rapidjson::Value& linkmap_fields = hr["structured_syslog_linkmap"];
     294           0 :             const contrail_rapidjson::Value& links_array = linkmap_fields["links"];
     295           0 :             assert(links_array.IsArray());
     296           0 :             for (contrail_rapidjson::SizeType i = 0; i < links_array.Size(); i++) {
     297           0 :                 std::string underlay = links_array[i]["underlay"].GetString();
     298           0 :                 std::string link_type = links_array[i]["link_type"].GetString() ;
     299           0 :                 std::string traffic_destination = links_array[i]["traffic_destination"].GetString() ; 
     300           0 :                 std::string link_metadata = links_array[i]["metadata"].GetString() ;
     301           0 :                 std::string overlay_link_data = underlay + "@" + link_type + "@" + traffic_destination + "@" + link_metadata ;
     302           0 :                 linkmap.insert(std::make_pair(links_array[i]["overlay"].GetString(),
     303             :                 overlay_link_data));
     304           0 :                 LOG(DEBUG, "Adding HostnameRecord: " << name << " linkmap: "
     305             :                 << links_array[i]["overlay"].GetString() << " : "
     306             :                 << overlay_link_data);
     307           0 :             }
     308             :         }
     309           0 :         if (hr.HasMember("structured_syslog_lan_segment_list")) {
     310           0 :             const contrail_rapidjson::Value& LANSegmentList_fields = hr["structured_syslog_lan_segment_list"];
     311           0 :             const contrail_rapidjson::Value& LANSegmentList_array = LANSegmentList_fields["LANSegmentList"];
     312           0 :             assert(LANSegmentList_array.IsArray());
     313           0 :             for (Chr_t::iterator it = hostname_records_.begin();it != hostname_records_.end(); it++){
     314           0 :                     if (location == (it->second->location())) {
     315           0 :                         LOG(DEBUG,"location already exists in hostname_records !!");
     316           0 :                         location_exists = true;
     317           0 :                         break;
     318             :                     }
     319             :             }
     320           0 :             if (location_exists) {
     321           0 :                 LOG(DEBUG, "Refresh LAN MAP for location : "<<location);
     322           0 :                 RefreshNetworksMap(location);
     323             :             }
     324           0 :             for (contrail_rapidjson::SizeType i = 0; i < LANSegmentList_array.Size(); i++) {
     325           0 :                 std::string vpn = LANSegmentList_array[i]["vpn"].GetString();
     326           0 :                 std::string network_ranges = LANSegmentList_array[i]["network_ranges"].GetString();
     327           0 :                 LOG(DEBUG, "Adding networks map with VPN: " << LANSegmentList_array[i]["vpn"].GetString()
     328             :                  << " LANSegmentList: " << LANSegmentList_array[i]["network_ranges"].GetString());
     329             : 
     330           0 :                 std::vector<std::string> network_range_list = split_into_vector(network_ranges,',');
     331           0 :                 for (std::vector<std::string>::iterator iter = network_range_list.begin();
     332           0 :                     iter != network_range_list.end(); iter++){
     333           0 :                     std::vector<std::string> ip_and_subnet = split_into_vector(*iter,'/');
     334           0 :                     std::string network_key = tenant + "::" + vpn;
     335           0 :                     AddNetwork (network_key, ip_and_subnet[0], ip_and_subnet[1], location);
     336           0 :                 }
     337           0 :             }
     338             :         }
     339           0 :         if (add_update) {
     340           0 :             LOG(DEBUG, "Adding HostnameRecord: " << name);
     341           0 :             AddHostnameRecord(name, hostaddr, tenant,
     342             :                                  location, device, tags, linkmap);
     343             :         } else {
     344           0 :             Chr_t::iterator cit = hostname_records_.find(name);
     345           0 :             if (cit != hostname_records_.end()) {
     346           0 :                 LOG(DEBUG, "Erasing LAN MAP for location : "<< cit->second->location());
     347           0 :                 if (!cit->second->location().empty()){
     348           0 :                    RefreshNetworksMap(location);
     349             :                 }
     350           0 :                 LOG(DEBUG, "Erasing HostnameRecord: " << cit->second->name());
     351           0 :                 hostname_records_.erase(cit);
     352             :             }
     353             :         }
     354           0 :         return;
     355           0 :     }
     356             : }
     357             : 
     358             : void
     359           0 : StructuredSyslogConfig::TenantRecordsHandler(const contrail_rapidjson::Document &jdoc,
     360             :                                                bool add_update) {
     361           0 :     if (jdoc.IsObject() && jdoc.HasMember("structured_syslog_tenant_record")) {
     362           0 :         const contrail_rapidjson::Value& hr = jdoc["structured_syslog_tenant_record"];
     363           0 :         std::string name, tenantaddr, tenant, tags;
     364           0 :         std::map< std::string, std::string > dscpmap_ipv4;
     365           0 :         std::map< std::string, std::string > dscpmap_ipv6;
     366             : 
     367           0 :         if (hr.HasMember("fq_name")) {
     368           0 :             const contrail_rapidjson::Value& fq_name = hr["fq_name"];
     369           0 :             contrail_rapidjson::SizeType sz = fq_name.Size();
     370           0 :             name = fq_name[sz-1].GetString();
     371           0 :             LOG(DEBUG, "NAME got from fq_name: " << name);
     372             :         }
     373           0 :         if (hr.HasMember("structured_syslog_tenantaddr")) {
     374           0 :             tenantaddr = hr["structured_syslog_tenantaddr"].GetString();
     375             :         }
     376           0 :         if (hr.HasMember("structured_syslog_tenant")) {
     377           0 :             tenant = hr["structured_syslog_tenant"].GetString();
     378             :         }
     379           0 :         if (hr.HasMember("structured_syslog_tenant_tags")) {
     380           0 :             tags = hr["structured_syslog_tenant_tags"].GetString();
     381             :         }
     382           0 :         if (hr.HasMember("structured_syslog_dscpmap")) {
     383           0 :             const contrail_rapidjson::Value& dscpmap_fields = hr["structured_syslog_dscpmap"];
     384           0 :             const contrail_rapidjson::Value& dscpmapipv4_array = dscpmap_fields["dscpListIPv4"];
     385           0 :             const contrail_rapidjson::Value& dscpmapipv6_array = dscpmap_fields["dscpListIPv6"];
     386           0 :             assert(dscpmapipv6_array.IsArray());
     387           0 :             assert(dscpmapipv4_array.IsArray());
     388           0 :             for (contrail_rapidjson::SizeType i = 0; i < dscpmapipv4_array.Size(); i++) {
     389           0 :                 dscpmap_ipv4.insert(std::make_pair<std::string,
     390           0 :                 std::string >(dscpmapipv4_array[i]["dscp_value"].GetString(),
     391           0 :                 dscpmapipv4_array[i]["alias_code"].GetString()));
     392           0 :                 LOG(DEBUG, "Adding TenantRecord: " << name << " dscpmap ipv4: "
     393             :                 << dscpmapipv4_array[i]["dscp_value"].GetString() << " : "
     394             :                 << dscpmapipv4_array[i]["alias_code"].GetString());
     395             :             }
     396           0 :             for (contrail_rapidjson::SizeType i = 0; i < dscpmapipv6_array.Size(); i++) {
     397           0 :                 dscpmap_ipv6.insert(std::make_pair<std::string,
     398           0 :                 std::string >(dscpmapipv6_array[i]["dscp_value"].GetString(),
     399           0 :                 dscpmapipv6_array[i]["alias_code"].GetString()));
     400           0 :                 LOG(DEBUG, "Adding TenantRecord: " << name << " dscpmap ipv6: "
     401             :                 << dscpmapipv6_array[i]["dscp_value"].GetString() << " : "
     402             :                 << dscpmapipv6_array[i]["alias_code"].GetString());
     403             :             }
     404             :         }
     405           0 :         if (add_update) {
     406           0 :             LOG(DEBUG, "Adding TenantRecord: " << name);
     407           0 :             AddTenantRecord(name, tenantaddr, tenant,
     408             :                                 tags, dscpmap_ipv4, dscpmap_ipv6);
     409             :         } else {
     410           0 :             Ctr_t::iterator cit = tenant_records_.find(name);
     411           0 :             if (cit != tenant_records_.end()) {
     412           0 :                 LOG(DEBUG, "Erasing TenantRecord: " << cit->second->name());
     413           0 :                 tenant_records_.erase(cit);
     414             :             }
     415             :         }
     416           0 :         return;
     417           0 :     }
     418             : }
     419             : 
     420             : 
     421             : void
     422           0 : StructuredSyslogConfig::ApplicationRecordsHandler(const contrail_rapidjson::Document &jdoc,
     423             :                                                   bool add_update) {
     424           0 :     if (jdoc.IsObject() && jdoc.HasMember("structured_syslog_application_record")) {
     425           0 :         const contrail_rapidjson::Value& ar = jdoc["structured_syslog_application_record"];
     426           0 :         std::string name, app_category, app_subcategory,
     427           0 :                     app_groups, app_risk, app_service_tags;
     428             : 
     429           0 :         if (ar.HasMember("fq_name")) {
     430           0 :             const contrail_rapidjson::Value& fq_name = ar["fq_name"];
     431           0 :             contrail_rapidjson::SizeType sz = fq_name.Size();
     432           0 :             name = fq_name[sz-1].GetString();
     433           0 :             LOG(DEBUG, "NAME got from fq_name: " << name);
     434             :         }
     435             : 
     436           0 :         if (ar.HasMember("structured_syslog_app_category")) {
     437           0 :             app_category = ar["structured_syslog_app_category"].GetString();
     438             :         }
     439           0 :         if (ar.HasMember("structured_syslog_app_subcategory")) {
     440           0 :             app_subcategory = ar["structured_syslog_app_subcategory"].GetString();
     441             :         }
     442           0 :         if (ar.HasMember("structured_syslog_app_groups")) {
     443           0 :             app_groups = ar["structured_syslog_app_groups"].GetString();
     444             :         }
     445           0 :         if (ar.HasMember("structured_syslog_app_risk")) {
     446           0 :             app_risk = ar["structured_syslog_app_risk"].GetString();
     447             :         }
     448           0 :         if (ar.HasMember("structured_syslog_app_service_tags")) {
     449           0 :             app_service_tags = ar["structured_syslog_app_service_tags"].GetString();
     450             :         }
     451             : 
     452           0 :         const contrail_rapidjson::Value& fq_name = ar["fq_name"];
     453           0 :         std::string tenant_name = fq_name[1].GetString();
     454           0 :         if (tenant_name.compare("default-global-analytics-config") == 0) {
     455           0 :             if (add_update) {
     456           0 :                 LOG(DEBUG, "Adding ApplicationRecord: " << name);
     457           0 :                 AddApplicationRecord(name, app_category, app_subcategory,
     458             :                                         app_groups, app_risk, app_service_tags);
     459             :             } else {
     460           0 :                 Car_t::iterator cit = application_records_.find(name);
     461           0 :                 if (cit != application_records_.end()) {
     462           0 :                     LOG(DEBUG, "Erasing ApplicationRecord: " << cit->second->name());
     463           0 :                     application_records_.erase(cit);
     464             :                 }
     465             :            }
     466             :         }
     467             :         else {
     468           0 :             std::string apprec_name;
     469           0 :             apprec_name =  tenant_name + '/' + name;
     470           0 :             if (add_update) {
     471           0 :                 LOG(DEBUG, "Adding TenantApplicationRecord: " << apprec_name);
     472           0 :                 AddTenantApplicationRecord(apprec_name, app_category, app_subcategory,
     473             :                                         app_groups, app_risk, app_service_tags);
     474             :             } else {
     475           0 :                 Ctar_t::iterator ctit = tenant_application_records_.find(apprec_name);
     476           0 :                 if (ctit != tenant_application_records_.end()) {
     477           0 :                     LOG(DEBUG, "Erasing TenantApplicationRecord: " << ctit->second->name());
     478           0 :                     tenant_application_records_.erase(ctit);
     479             :                 }
     480             :             }
     481           0 :         }
     482             : 
     483           0 :         return;
     484           0 :     }
     485             : }
     486             : 
     487             : void
     488           0 : StructuredSyslogConfig::MessageConfigsHandler(const contrail_rapidjson::Document &jdoc,
     489             :                                               bool add_update) {
     490           0 :     if (jdoc.IsObject() && jdoc.HasMember("structured_syslog_message")) {
     491           0 :         const contrail_rapidjson::Value& hr = jdoc["structured_syslog_message"];
     492           0 :         std::vector< std::string > ints;
     493           0 :         std::vector< std::string > tags;
     494           0 :         std::string name, forward;
     495           0 :         bool process_and_store = false;
     496           0 :         bool process_and_summarize = false;
     497           0 :         bool process_and_summarize_user = false;
     498             : 
     499           0 :         if (hr.HasMember("fq_name")) {
     500           0 :             const contrail_rapidjson::Value& fq_name = hr["fq_name"];
     501           0 :             contrail_rapidjson::SizeType sz = fq_name.Size();
     502           0 :             name = fq_name[sz-1].GetString();
     503           0 :             LOG(DEBUG, "NAME got from fq_name: " << name);
     504             :         }
     505             : 
     506           0 :         if (hr.HasMember("structured_syslog_message_tagged_fields")) {
     507           0 :             const contrail_rapidjson::Value& tagged_fields = hr["structured_syslog_message_tagged_fields"];
     508           0 :             const contrail_rapidjson::Value& tag_array = tagged_fields["field_names"];
     509           0 :             assert(tag_array.IsArray());
     510           0 :             for (contrail_rapidjson::SizeType i = 0; i < tag_array.Size(); i++)
     511           0 :                 tags.push_back(tag_array[i].GetString());
     512             :         }
     513           0 :         if (hr.HasMember("structured_syslog_message_integer_fields")) {
     514           0 :             const contrail_rapidjson::Value& integer_fields = hr["structured_syslog_message_integer_fields"];
     515           0 :             const contrail_rapidjson::Value& int_array = integer_fields["field_names"];
     516           0 :             assert(int_array.IsArray());
     517           0 :             for (contrail_rapidjson::SizeType i = 0; i < int_array.Size(); i++)
     518           0 :                 ints.push_back(int_array[i].GetString());
     519             :         }
     520           0 :         if (hr.HasMember("structured_syslog_message_forward")) {
     521           0 :             forward = hr["structured_syslog_message_forward"].GetString();
     522             :         }
     523           0 :         if (hr.HasMember("structured_syslog_message_process_and_store")) {
     524           0 :             process_and_store = hr["structured_syslog_message_process_and_store"].GetBool();
     525             :         }
     526           0 :         if (hr.HasMember("structured_syslog_message_process_and_summarize")) {
     527           0 :             process_and_summarize = hr["structured_syslog_message_process_and_summarize"].GetBool();
     528             :         }
     529           0 :         if (hr.HasMember("structured_syslog_message_process_and_summarize_user")) {
     530           0 :             process_and_summarize_user = hr["structured_syslog_message_process_and_summarize_user"].GetBool();
     531             :         }
     532           0 :         if (add_update) {
     533           0 :             LOG(DEBUG, "Adding MessageConfig: " << name);
     534           0 :             AddMessageConfig(name, tags, ints, process_and_store, forward, process_and_summarize, process_and_summarize_user);
     535             :         } else {
     536           0 :             Cmc_t::iterator cit = message_configs_.find(name);
     537           0 :             if (cit != message_configs_.end()) {
     538           0 :                 LOG(DEBUG, "Erasing MessageConfig: " << cit->second->name());
     539           0 :                 message_configs_.erase(cit);
     540             :             }
     541             :         }
     542           0 :         return;
     543           0 :     }
     544             : 
     545             : }
     546             : 
     547             : void
     548           0 : StructuredSyslogConfig::SlaProfileRecordsHandler(const contrail_rapidjson::Document &jdoc,
     549             :                                                  bool add_update) {
     550           0 :     if (jdoc.IsObject() && jdoc.HasMember("structured_syslog_sla_profile")) {
     551           0 :         const contrail_rapidjson::Value& slar = jdoc["structured_syslog_sla_profile"];
     552           0 :         std::string name, sla_params, tenant_name, slarec_name;
     553             : 
     554           0 :         if (slar.HasMember("fq_name")) {
     555           0 :             const contrail_rapidjson::Value& fq_name = slar["fq_name"];
     556           0 :             contrail_rapidjson::SizeType sz = fq_name.Size();
     557           0 :             name = fq_name[sz-1].GetString();
     558           0 :             tenant_name = fq_name[1].GetString();
     559           0 :             slarec_name =  tenant_name + '/' + name;
     560           0 :             LOG(DEBUG, "NAME got from fq_name: " << name);
     561             :         }
     562           0 :         if (slar.HasMember("structured_syslog_sla_params")) {
     563           0 :             sla_params = slar["structured_syslog_sla_params"].GetString();
     564             :         }
     565           0 :         if (add_update) {
     566           0 :             LOG(DEBUG, "Adding SlaProfileRecord: " << slarec_name);
     567           0 :             AddSlaProfileRecord(slarec_name, sla_params);
     568             :         } else {
     569           0 :             Csr_t::iterator cit = sla_profile_records_.find(slarec_name);
     570           0 :             if (cit != sla_profile_records_.end()) {
     571           0 :                 LOG(DEBUG, "Erasing SlaProfileRecord: " << cit->second->name());
     572           0 :                 sla_profile_records_.erase(cit);
     573             :             }
     574             :         }
     575           0 :         return;
     576           0 :     }
     577             : }
     578             : 
     579             : void
     580           0 : StructuredSyslogConfig::ReceiveConfig(const contrail_rapidjson::Document &jdoc, bool add_change) {
     581           0 :     HostnameRecordsHandler(jdoc, add_change);
     582           0 :     TenantRecordsHandler(jdoc, add_change);
     583           0 :     ApplicationRecordsHandler(jdoc, add_change);
     584           0 :     MessageConfigsHandler(jdoc, add_change);
     585           0 :     SlaProfileRecordsHandler(jdoc, add_change);
     586           0 : }
     587             : 
     588             : boost::shared_ptr<HostnameRecord>
     589           0 : StructuredSyslogConfig::GetHostnameRecord(const std::string &name) {
     590           0 :     Chr_t::iterator it = hostname_records_.find(name);
     591           0 :     if (it  != hostname_records_.end()) {
     592           0 :         return it->second;
     593             :     }
     594           0 :     return boost::shared_ptr<HostnameRecord>();
     595             : }
     596             : 
     597             : void
     598           0 : StructuredSyslogConfig::AddHostnameRecord(const std::string &name,
     599             :         const std::string &hostaddr, const std::string &tenant,
     600             :         const std::string &location, const std::string &device,
     601             :         const std::string &tags, const std::map< std::string, std::string > &linkmap) {
     602           0 :     Chr_t::iterator it = hostname_records_.find(name);
     603           0 :     if (it  != hostname_records_.end()) {
     604           0 :         it->second->Refresh(name, hostaddr, tenant, location,
     605             :                            device, tags, linkmap);
     606             :     } else {
     607             :         boost::shared_ptr<HostnameRecord> c(new HostnameRecord(
     608           0 :                     name, hostaddr, tenant, location, device, tags, linkmap));
     609           0 :         hostname_records_.insert(std::make_pair(name, c));
     610           0 :     }
     611           0 : }
     612             : 
     613             : boost::shared_ptr<TenantRecord>
     614           0 : StructuredSyslogConfig::GetTenantRecord(const std::string &name) {
     615           0 :     Ctr_t::iterator it = tenant_records_.find(name);
     616           0 :     if (it  != tenant_records_.end()) {
     617           0 :         return it->second;
     618             :     }
     619           0 :     return boost::shared_ptr<TenantRecord>();
     620             : }
     621             : 
     622             : void
     623           0 : StructuredSyslogConfig::AddTenantRecord(const std::string &name,
     624             :         const std::string &tenantaddr, const std::string &tenant,
     625             :         const std::string &tags, const std::map< std::string, std::string > &dscpmap_ipv4,
     626             :         const std::map< std::string, std::string > &dscpmap_ipv6) {
     627           0 :     Ctr_t::iterator it = tenant_records_.find(name);
     628           0 :     if (it  != tenant_records_.end()) {
     629           0 :         it->second->Refresh(name, tenantaddr, tenant, tags, dscpmap_ipv4, dscpmap_ipv6);
     630             :     } else {
     631             :         boost::shared_ptr<TenantRecord> c(new TenantRecord(
     632           0 :                     name, tenantaddr, tenant, tags, dscpmap_ipv4, dscpmap_ipv6));
     633           0 :         tenant_records_.insert(std::make_pair(name, c));
     634           0 :     }
     635           0 : }
     636             : 
     637             : boost::shared_ptr<ApplicationRecord>
     638           0 : StructuredSyslogConfig::GetApplicationRecord(const std::string &name) {
     639           0 :     Car_t::iterator it = application_records_.find(name);
     640           0 :     if (it  != application_records_.end()) {
     641           0 :         return it->second;
     642             :     }
     643           0 :     return boost::shared_ptr<ApplicationRecord>();
     644             : }
     645             : 
     646             : void
     647           0 : StructuredSyslogConfig::AddApplicationRecord(const std::string &name,
     648             :         const std::string &app_category, const std::string &app_subcategory,
     649             :         const std::string &app_groups, const std::string &app_risk,
     650             :         const std::string &app_service_tags) {
     651           0 :     Car_t::iterator it = application_records_.find(name);
     652           0 :     if (it  != application_records_.end()) {
     653           0 :         it->second->Refresh(name, app_category, app_subcategory, app_groups,
     654             :                            app_risk, app_service_tags);
     655             :     } else {
     656             :         boost::shared_ptr<ApplicationRecord> c(new ApplicationRecord(
     657             :                     name, app_category, app_subcategory, app_groups,
     658           0 :                     app_risk, app_service_tags));
     659           0 :         application_records_.insert(std::make_pair(name, c));
     660           0 :     }
     661           0 : }
     662             : 
     663             : boost::shared_ptr<TenantApplicationRecord>
     664           0 : StructuredSyslogConfig::GetTenantApplicationRecord(const std::string &name) {
     665           0 :     Ctar_t::iterator it = tenant_application_records_.find(name);
     666           0 :     if (it  != tenant_application_records_.end()) {
     667           0 :         return it->second;
     668             :     }
     669           0 :     return boost::shared_ptr<TenantApplicationRecord>();
     670             : }
     671             : 
     672             : void
     673           0 : StructuredSyslogConfig::AddTenantApplicationRecord(const std::string &name,
     674             :         const std::string &tenant_app_category, const std::string &tenant_app_subcategory,
     675             :         const std::string &tenant_app_groups, const std::string &tenant_app_risk,
     676             :         const std::string &tenant_app_service_tags) {
     677           0 :     Ctar_t::iterator it = tenant_application_records_.find(name);
     678           0 :     if (it  != tenant_application_records_.end()) {
     679           0 :         it->second->Refresh(name, tenant_app_category, tenant_app_subcategory,
     680             :                         tenant_app_groups, tenant_app_risk, tenant_app_service_tags);
     681             :     } else {
     682             :         boost::shared_ptr<TenantApplicationRecord> c(new TenantApplicationRecord(
     683             :                     name, tenant_app_category, tenant_app_subcategory,
     684           0 :                     tenant_app_groups, tenant_app_risk, tenant_app_service_tags));
     685           0 :         tenant_application_records_.insert(std::make_pair(name, c));
     686           0 :     }
     687           0 : }
     688             : 
     689             : boost::shared_ptr<SlaProfileRecord>
     690           0 : StructuredSyslogConfig::GetSlaProfileRecord(const std::string &name) {
     691           0 :     Csr_t::iterator it = sla_profile_records_.find(name);
     692           0 :     if (it  != sla_profile_records_.end()) {
     693           0 :         return it->second;
     694             :     }
     695           0 :     return boost::shared_ptr<SlaProfileRecord>();
     696             : }
     697             : 
     698             : void
     699           0 : StructuredSyslogConfig::AddSlaProfileRecord(const std::string &name,
     700             :         const std::string &sla_params) {
     701           0 :     Csr_t::iterator it = sla_profile_records_.find(name);
     702           0 :     if (it  != sla_profile_records_.end()) {
     703           0 :         it->second->Refresh(name, sla_params);
     704             :     } else {
     705             :         boost::shared_ptr<SlaProfileRecord> c(new SlaProfileRecord(
     706           0 :                     name, sla_params));
     707           0 :         sla_profile_records_.insert(std::make_pair(name, c));
     708           0 :     }
     709           0 : }
     710             : 
     711             : boost::shared_ptr<MessageConfig>
     712          30 : StructuredSyslogConfig::GetMessageConfig(const std::string &name) {
     713          30 :     Cmc_t::iterator it = message_configs_.find(name);
     714          30 :     if (it  != message_configs_.end()) {
     715             :         /* exact match */
     716           0 :         return it->second;
     717             :     }
     718             :     /* no exact match, look for match based on regex */
     719          30 :     Cmc_t::iterator cit = message_configs_.begin();
     720          30 :     Cmc_t::iterator end = message_configs_.end();
     721          30 :     Cmc_t::iterator match = end;
     722          30 :     while (cit != end) {
     723           0 :         regex pattern;
     724           0 :         Cmc_t::iterator dit = cit++;
     725           0 :         boost::match_results<std::string::const_iterator> what;
     726           0 :         boost::match_flag_type flags = boost::match_default;
     727           0 :         std::string::const_iterator name_start = name.begin(), name_end = name.end();
     728             :         try {
     729           0 :             pattern = regex(dit->second->name());
     730             :         }
     731           0 :         catch (regex_error &e) {
     732           0 :             LOG(DEBUG, "skipping invalid regex pattern: " << dit->second->name());
     733           0 :             continue;
     734           0 :         }
     735           0 :         if(regex_search(name_start, name_end, what, pattern, flags)) {
     736           0 :             if ((match == end) || (match->second->name().length() < dit->second->name().length())) {
     737           0 :                 match = dit;
     738             :             }
     739             :         }
     740           0 :     }
     741          30 :     if (match != end) {
     742           0 :         return match->second;
     743             :     }
     744             :     /* no match */
     745          30 :     return boost::shared_ptr<MessageConfig>();
     746             : }
     747             : 
     748             : void
     749           0 : StructuredSyslogConfig::AddMessageConfig(const std::string &name,
     750             :         const std::vector< std::string > &tags, const std::vector< std::string > &ints,
     751             :         bool process_and_store, const std::string &forward_action, bool process_and_summarize, 
     752             :         bool process_and_summarize_user) {
     753           0 :     bool forward = false, process_before_forward = false;
     754           0 :     if (forward_action == "forward-unprocessed") {
     755           0 :         forward = true;
     756             :     }
     757           0 :     if (forward_action == "forward-processed") {
     758           0 :         forward = true;
     759           0 :         process_before_forward = true;
     760             :     }
     761           0 :     Cmc_t::iterator it = message_configs_.find(name);
     762           0 :     if (it  != message_configs_.end()) {
     763           0 :         it->second->Refresh(name, tags, ints, process_and_store, forward, process_before_forward, 
     764             :                             process_and_summarize, process_and_summarize_user);
     765             :     } else {
     766             :         boost::shared_ptr<MessageConfig> c(new MessageConfig(
     767             :                     name, tags, ints, process_and_store, forward, process_before_forward, 
     768           0 :                     process_and_summarize, process_and_summarize_user));
     769           0 :         message_configs_.insert(std::make_pair(name, c));
     770           0 :     }
     771           0 : }

Generated by: LCOV version 1.14