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