Line data Source code
1 : /* 2 : * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "config_db_client.h" 6 : 7 : #include <boost/tokenizer.hpp> 8 : 9 : #include "base/string_util.h" 10 : #include "config_client_options.h" 11 : #include "config_client_log.h" 12 : #include "config_client_log_types.h" 13 : #include "config_client_show_types.h" 14 : 15 : using contrail::regex; 16 : using contrail::regex_match; 17 : using contrail::regex_search; 18 : 19 : using namespace std; 20 : 21 3673 : ConfigDbClient::ConfigDbClient(ConfigClientManager *mgr, 22 : EventManager *evm, 23 3673 : const ConfigClientOptions &options) 24 3673 : : mgr_(mgr), evm_(evm), 25 3673 : config_db_user_(options.config_db_username), 26 3673 : config_db_password_(options.config_db_password) { 27 : 28 3673 : for (vector<string>::const_iterator iter = 29 3673 : options.config_db_server_list.begin(); 30 3673 : iter != options.config_db_server_list.end(); iter++) { 31 0 : string server_info(*iter); 32 : typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 33 0 : boost::char_separator<char> sep(":"); 34 0 : tokenizer tokens(server_info, sep); 35 0 : tokenizer::iterator tit = tokens.begin(); 36 0 : string ip(*tit); 37 0 : config_db_ips_.push_back(ip); 38 0 : ++tit; 39 0 : string port_str(*tit); 40 : int port; 41 0 : stringToInteger(port_str, port); 42 0 : config_db_ports_.push_back(port); 43 0 : } 44 3673 : } 45 : 46 3673 : ConfigDbClient::~ConfigDbClient() { 47 3673 : } 48 : 49 3673 : const string& ConfigDbClient::config_db_user() const { 50 3673 : return config_db_user_; 51 : } 52 : 53 3673 : const string& ConfigDbClient::config_db_password() const { 54 3673 : return config_db_password_; 55 : } 56 : 57 7409 : const vector<string>& ConfigDbClient::config_db_ips() const { 58 7409 : return config_db_ips_; 59 : } 60 : 61 3673 : int ConfigDbClient::GetFirstConfigDbPort() const { 62 3673 : return !config_db_ports_.empty() ? config_db_ports_[0] : 0; 63 : } 64 : 65 0 : string ConfigDbClient::uuid_str(const string &uuid) { 66 0 : return uuid; 67 : } 68 : 69 1600 : uint32_t ConfigDbClient::GetNumReadRequestToBunch() const { 70 : static bool init_ = false; 71 : static uint32_t num_read_req_to_bunch = 0; 72 : 73 1600 : if (!init_) { 74 : // XXX To be used for testing purposes only. 75 8 : char *count_str = getenv("CONFIG_NUM_DB_READ_REQ_TO_BUNCH"); 76 8 : if (count_str) { 77 0 : num_read_req_to_bunch = strtol(count_str, NULL, 0); 78 : } else { 79 8 : num_read_req_to_bunch = kNumEntriesToRead; 80 : } 81 8 : init_ = true; 82 : } 83 1600 : return num_read_req_to_bunch; 84 : } 85 : 86 23642 : void ConfigDbClient::AddFQNameCache(const string &uuid, 87 : const string &obj_type, 88 : const string &fq_name) { 89 23642 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true); 90 47284 : FQNameCacheType cache_obj(obj_type, fq_name); 91 23642 : fq_name_cache_.insert(make_pair(uuid, cache_obj)); 92 47284 : return; 93 23642 : } 94 : 95 140 : void ConfigDbClient::InvalidateFQNameCache(const string &uuid) { 96 140 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true); 97 140 : FQNameCacheMap::iterator it = fq_name_cache_.find(uuid); 98 140 : if (it != fq_name_cache_.end()) { 99 110 : it->second.deleted = true; 100 : } 101 280 : return; 102 140 : } 103 : 104 21192 : void ConfigDbClient::PurgeFQNameCache(const string &uuid) { 105 21192 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true); 106 21193 : fq_name_cache_.erase(uuid); 107 21193 : } 108 : 109 432 : string ConfigDbClient::FindFQName(const string &uuid) const { 110 432 : ObjTypeFQNPair obj_type_fq_name_pair = UUIDToFQName(uuid); 111 864 : return obj_type_fq_name_pair.second; 112 432 : } 113 : 114 34961 : ConfigDbClient::ObjTypeFQNPair ConfigDbClient::UUIDToFQName( 115 : const string &uuid, bool deleted_ok) const { 116 34961 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false); 117 34959 : FQNameCacheMap::const_iterator it = fq_name_cache_.find(uuid); 118 34956 : if (it != fq_name_cache_.end()) { 119 23983 : if (!it->second.deleted || (it->second.deleted && deleted_ok)) { 120 23983 : return make_pair(it->second.obj_type, it->second.fq_name); 121 : } 122 : } 123 21946 : return make_pair("ERROR", "ERROR"); 124 34962 : } 125 : 126 36 : void ConfigDbClient::FillFQNameCacheInfo(const string &uuid, 127 : FQNameCacheMap::const_iterator it, ConfigDBFQNameCacheEntry *entry) const { 128 36 : entry->set_uuid(it->first); 129 36 : entry->set_obj_type(it->second.obj_type); 130 36 : entry->set_fq_name(it->second.fq_name); 131 36 : entry->set_deleted(it->second.deleted); 132 36 : } 133 : 134 18 : bool ConfigDbClient::UUIDToFQNameShow( 135 : const string &search_string, const string &last_uuid, 136 : uint32_t num_entries, 137 : vector<ConfigDBFQNameCacheEntry> *entries) const { 138 18 : uint32_t count = 0; 139 18 : bool more = false; 140 18 : regex search_expr(search_string); 141 18 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false); 142 18 : for (FQNameCacheMap::const_iterator it = 143 18 : fq_name_cache_.upper_bound(last_uuid); 144 64 : it != fq_name_cache_.end(); it++) { 145 48 : if (regex_search(it->first, search_expr) || 146 62 : regex_search(it->second.obj_type, search_expr) || 147 14 : regex_search(it->second.fq_name, search_expr)) { 148 38 : if (++count > num_entries) { 149 2 : more = true; 150 2 : break; 151 : } 152 36 : ConfigDBFQNameCacheEntry entry; 153 36 : FillFQNameCacheInfo(it->first, it, &entry); 154 36 : entries->push_back(entry); 155 36 : } 156 : } 157 18 : return more; 158 18 : } 159 : 160 3673 : void ConfigDbClient::InitConnectionInfo() { 161 3673 : client_connection_up_ = false; 162 3673 : connection_status_change_at_ = UTCTimestampUsec(); 163 3673 : } 164 : 165 42558 : void ConfigDbClient::UpdateConnectionInfo(bool success, 166 : bool force) { 167 : bool previous_status = 168 42558 : client_connection_up_.exchange(success); 169 42558 : if ((previous_status == success) && !force) { 170 27082 : return; 171 : } 172 : 173 15476 : connection_status_change_at_ = UTCTimestampUsec(); 174 : } 175 : 176 3736 : void ConfigDbClient::GetConnectionInfo(ConfigDBConnInfo &status) const { 177 3736 : status.cluster = boost::algorithm::join(config_db_ips(), ", "); 178 3736 : status.connection_status = client_connection_up_; 179 : status.connection_status_change_at = 180 3736 : UTCUsecToString(connection_status_change_at_); 181 3736 : return; 182 : } 183 : 184 0 : bool ConfigDbClient::IsTaskTriggered() const { 185 0 : return false; 186 : } 187 : 188 0 : void ConfigDbClient::StartWatcher() { 189 0 : }