LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/config-client-mgr - config_cassandra_client.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 25 27 92.6 %
Date: 2026-08-03 02:19:58 Functions: 14 15 93.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef config_cass_client_h
       6             : #define config_cass_client_h
       7             : 
       8             : #include <boost/ptr_container/ptr_map.hpp>
       9             : #include <boost/shared_ptr.hpp>
      10             : 
      11             : #include <atomic>
      12             : #include <list>
      13             : #include <map>
      14             : #include <set>
      15             : #include <string>
      16             : #include <utility>
      17             : #include <vector>
      18             : 
      19             : #include "base/queue_task.h"
      20             : #include "base/timer.h"
      21             : 
      22             : #include "config_db_client.h"
      23             : #include "config_json_parser_base.h"
      24             : #include "config_cassandra_client.h"
      25             : #include "database/gendb_if.h"
      26             : #include "json_adapter_data.h"
      27             : 
      28             : class EventManager;
      29             : class ConfigClientManager;
      30             : struct ConfigDBConnInfo;
      31             : class TaskTrigger;
      32             : class ConfigCassandraClient;
      33             : struct ConfigCassandraParseContext;
      34             : class ConfigDBFQNameCacheEntry;
      35             : class ConfigDBUUIDCacheEntry;
      36             : 
      37             : class ConfigCassandraPartition {
      38             :  public:
      39             :     ConfigCassandraPartition(ConfigCassandraClient *client, size_t idx);
      40             :     virtual ~ConfigCassandraPartition();
      41             : 
      42             :     typedef boost::shared_ptr<WorkQueue<ObjectProcessReq *> >
      43             :         ObjProcessWorkQType;
      44             : 
      45             :     struct FieldTimeStampInfo {
      46             :         uint64_t time_stamp;
      47             :         bool refreshed;
      48             :     };
      49             : 
      50             :     struct cmp_json_key {
      51      627178 :         bool operator()(const JsonAdapterDataType &k1,
      52             :                          const JsonAdapterDataType &k2) const {
      53      627178 :             return k1.key < k2.key;
      54             :         }
      55             :     };
      56             :     typedef std::map<JsonAdapterDataType, FieldTimeStampInfo, cmp_json_key>
      57             :                                                              FieldDetailMap;
      58             :     class ObjCacheEntry : public ObjectCacheEntry {
      59             :      public:
      60       23487 :         ObjCacheEntry(ConfigCassandraPartition *parent,
      61             :                 uint64_t last_read_tstamp)
      62       23487 :             : ObjectCacheEntry(last_read_tstamp),
      63       23487 :               retry_count_(0), retry_timer_(NULL),
      64       23487 :               parent_(parent) {
      65       23487 :         }
      66             : 
      67             :         virtual ~ObjCacheEntry();
      68             : 
      69             :         void EnableCassandraReadRetry(const std::string uuid);
      70             :         void DisableCassandraReadRetry(const std::string uuid);
      71      831249 :         FieldDetailMap &GetFieldDetailMap() { return field_detail_map_; }
      72         194 :         const FieldDetailMap &GetFieldDetailMap() const {
      73         194 :             return field_detail_map_;
      74             :         }
      75         187 :         uint32_t GetRetryCount() const { return retry_count_; }
      76          38 :         bool IsRetryTimerCreated() const { return (retry_timer_ != NULL); }
      77             :         bool IsRetryTimerRunning() const;
      78           4 :         Timer *GetRetryTimer() { return retry_timer_; }
      79             : 
      80             :      private:
      81             :         friend class ConfigCassandraPartitionTest;
      82             :         friend class ConfigCassandraPartitionTest2;
      83             :         friend class ConfigCassandraClientPartitionTest;
      84             : 
      85             :         bool CassReadRetryTimerExpired(const std::string uuid);
      86             :         void CassReadRetryTimerErrorHandler();
      87             :         uint32_t retry_count_;
      88             :         Timer *retry_timer_;
      89             :         FieldDetailMap field_detail_map_;
      90             :         ConfigCassandraPartition *parent_;
      91             :     };
      92             : 
      93             :     static const uint32_t kMaxUUIDRetryTimePowOfTwo = 20;
      94             :     static const uint32_t kMinUUIDRetryTimeMSec = 100;
      95             :     typedef boost::ptr_map<std::string, ObjCacheEntry> ObjectCacheMap;
      96             : 
      97       33696 :     ObjProcessWorkQType obj_process_queue() {
      98       33696 :         return obj_process_queue_;
      99             :     }
     100             : 
     101             :     virtual int UUIDRetryTimeInMSec(const ObjCacheEntry *obj) const;
     102             :     ObjCacheEntry *GetObjCacheEntry(const std::string &uuid);
     103             :     const ObjCacheEntry *GetObjCacheEntry(const std::string &uuid) const;
     104             :     bool StoreKeyIfUpdated(const std::string &uuid,
     105             :                            JsonAdapterDataType *adapter,
     106             :                            uint64_t timestamp,
     107             :                            ConfigCassandraParseContext &context);
     108             :     void ListMapPropReviseUpdateList(const std::string &uuid,
     109             :                                      ConfigCassandraParseContext &context);
     110             :     ObjCacheEntry *MarkCacheDirty(const std::string &uuid);
     111           4 :     void DeleteCacheMap(const std::string &uuid) {
     112           4 :         object_cache_map_.erase(uuid);
     113           4 :     }
     114             :     void Enqueue(ObjectProcessReq *req);
     115             : 
     116             : 
     117             :     bool UUIDToObjCacheShow(
     118             :         const std::string &search_string, const std::string &last_uuid,
     119             :         uint32_t num_entries,
     120             :         std::vector<ConfigDBUUIDCacheEntry> *entries) const;
     121           2 :     int GetInstanceId() const { return worker_id_; }
     122             : 
     123             :     boost::asio::io_context *ioservice();
     124             : 
     125             :     bool IsListOrMapPropEmpty(const string &uuid_key, const string &lookup_key);
     126             :     bool IsTaskTriggered() const;
     127             : protected:
     128             :     virtual bool ReadObjUUIDTable(const std::set<std::string> &uuid_list);
     129             :     bool ProcessObjUUIDTableEntry(const std::string &uuid_key,
     130             :                                   const GenDb::ColList &col_list);
     131             :     virtual void ParseObjUUIDTableEntry(const std::string &uuid,
     132             :         const GenDb::ColList &col_list, CassColumnKVVec *cass_data_vec,
     133             :         ConfigCassandraParseContext &context);
     134             :     void ParseObjUUIDTableEachColumnBuildContext(const std::string &uuid,
     135             :            const std::string &key, const std::string &value,
     136             :            uint64_t timestamp, CassColumnKVVec *cass_data_vec,
     137             :            ConfigCassandraParseContext &context);
     138             :     virtual void HandleObjectDelete(const string &uuid, bool add_change);
     139      821052 :     ConfigCassandraClient *client() { return config_client_; }
     140             : 
     141             : private:
     142             :     friend class ConfigCassandraClient;
     143             : 
     144             :     struct ObjectProcessRequestType {
     145      129608 :         ObjectProcessRequestType(const std::string &in_oper,
     146             :                                  const std::string &in_obj_type,
     147             :                                  const std::string &in_uuid)
     148      129608 :             : oper(in_oper), obj_type(in_obj_type), uuid(in_uuid) {
     149      129607 :         }
     150             :         std::string oper;
     151             :         std::string obj_type;
     152             :         std::string uuid;
     153             :     };
     154             : 
     155             :     typedef std::map<std::string, ObjectProcessRequestType *> UUIDProcessSet;
     156             : 
     157             :     bool RequestHandler(ObjectProcessReq *req);
     158             :     void AddUUIDToRequestList(const std::string &oper,
     159             :                       const std::string &obj_type, const std::string &uuid_str);
     160             :     bool ConfigReader();
     161             :     void RemoveObjReqEntries(std::set<std::string> &req_list);
     162             :     void RemoveObjReqEntry(std::string &uuid);
     163             :     virtual void GenerateAndPushJson(
     164             :             const string &uuid_key, const string &obj_type,
     165             :             const CassColumnKVVec &cass_data_vec, bool add_change);
     166             : 
     167             :     void FillUUIDToObjCacheInfo(const std::string &uuid,
     168             :                                 ObjectCacheMap::const_iterator uuid_iter,
     169             :                                 ConfigDBUUIDCacheEntry *entry) const;
     170             : 
     171             :     ObjProcessWorkQType obj_process_queue_;
     172             :     UUIDProcessSet uuid_read_set_;
     173             :     ObjectCacheMap object_cache_map_;
     174             :     boost::shared_ptr<TaskTrigger> config_reader_;
     175             :     ConfigCassandraClient *config_client_;
     176             :     int worker_id_;
     177             : };
     178             : 
     179             : /*
     180             :  * This class has the functionality to interact with the cassandra servers that
     181             :  * store the user configuration.
     182             :  */
     183             : class ConfigCassandraClient : public ConfigDbClient {
     184             :  public:
     185             :     // Cassandra table names
     186             :     static const std::string kUuidTableName;
     187             :     static const std::string kFqnTableName;
     188             : 
     189             :     // Task names
     190             :     static const std::string kCassClientTaskId;
     191             :     static const std::string kObjectProcessTaskId;
     192             : 
     193             :     // Number of UUIDs to read in one read request
     194             :     static const int kMaxNumUUIDToRead = 64;
     195             : 
     196             :     // Number of FQName entries to read in one read request
     197             :     static const int kNumFQNameEntriesToRead = 4096;
     198             : 
     199             :     typedef boost::scoped_ptr<GenDb::GenDbIf> GenDbIfPtr;
     200             :     typedef std::vector<ConfigCassandraPartition *> PartitionList;
     201             : 
     202             :     ConfigCassandraClient(ConfigClientManager *mgr, EventManager *evm,
     203             :                           const ConfigClientOptions &options,
     204             :                           int num_workers);
     205             :     virtual ~ConfigCassandraClient();
     206             : 
     207             :     virtual void InitDatabase();
     208             :     void BulkSyncDone();
     209             :     ConfigCassandraPartition *GetPartition(const std::string &uuid);
     210             :     const ConfigCassandraPartition *GetPartition(const std::string &uuid) const;
     211             :     const ConfigCassandraPartition *GetPartition(int worker_id) const;
     212             : 
     213             :     void EnqueueUUIDRequest(std::string oper, std::string obj_type,
     214             :                                     std::string uuid_str);
     215             : 
     216             :     virtual bool UUIDToObjCacheShow(
     217             :         const std::string &search_string, int inst_num,
     218             :         const std::string &last_uuid, uint32_t num_entries,
     219             :         std::vector<ConfigDBUUIDCacheEntry> *entries) const;
     220             :     virtual bool IsListOrMapPropEmpty(const string &uuid_key,
     221             :                                       const string &lookup_key);
     222             :     virtual bool IsTaskTriggered() const;
     223             : protected:
     224             :     typedef std::pair<std::string, std::string> ObjTypeUUIDType;
     225             :     typedef std::list<ObjTypeUUIDType> ObjTypeUUIDList;
     226             : 
     227             :     void UpdateFQNameCache(const std::string &key, const std::string &obj_type,
     228             :                            ObjTypeUUIDList &uuid_list);
     229             :     virtual bool BulkDataSync();
     230             :     bool EnqueueDBSyncRequest(const ObjTypeUUIDList &uuid_list);
     231             :     virtual std::string FetchUUIDFromFQNameEntry(const std::string &key) const;
     232             : 
     233             :     virtual int HashUUID(const std::string &uuid_str) const;
     234         627 :     virtual bool SkipTimeStampCheckForTypeAndFQName() const { return true; }
     235           0 :     virtual uint32_t GetFQNameEntriesToRead() const {
     236           0 :         return kNumFQNameEntriesToRead;
     237             :     }
     238             :     int num_workers() const { return num_workers_; }
     239        4212 :     PartitionList &partitions() { return partitions_; }
     240             :     virtual void PostShutdown();
     241             : 
     242             :  private:
     243             :     friend class ConfigCassandraPartition;
     244             : 
     245             :     bool InitRetry();
     246             : 
     247             :     bool FQNameReader();
     248             :     bool ParseFQNameRowGetUUIDList(const std::string &obj_type,
     249             :                const GenDb::ColList &col_list, ObjTypeUUIDList &uuid_list,
     250             :                std::string *last_column);
     251             : 
     252             :     void HandleCassandraConnectionStatus(bool success,
     253             :                                          bool force_update = false);
     254             : 
     255             :     GenDbIfPtr dbif_;
     256             :     int num_workers_;
     257             :     PartitionList partitions_;
     258             :     boost::scoped_ptr<TaskTrigger> fq_name_reader_;
     259             :     std::atomic<long> bulk_sync_status_;
     260             : };
     261             : 
     262             : #endif  // config_cass_client_h

Generated by: LCOV version 1.14