Line data Source code
1 : /* 2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef AGENT_OPER_IFMAP_DEPENDENCY_MANAGER_H__ 6 : #define AGENT_OPER_IFMAP_DEPENDENCY_MANAGER_H__ 7 : 8 : #include <map> 9 : #include <boost/function.hpp> 10 : #include <boost/intrusive_ptr.hpp> 11 : #include <boost/uuid/uuid.hpp> 12 : #include <boost/uuid/nil_generator.hpp> 13 : 14 : #include "db/db_entry.h" 15 : #include "db/db_table.h" 16 : #include "ifmap/ifmap_dependency_tracker.h" 17 : 18 : class Agent; 19 : class DB; 20 : class DBGraph; 21 : class IFMapDependencyTracker; 22 : class IFMapNode; 23 : class TaskTrigger; 24 : class IFMapDependencyManager; 25 : class IFMapDependencyManagerTest; 26 : 27 : //IFMapNodeState is a DBState for IFMapNode with listener ID 28 : // of IFMapDependency Manager. DBState is created when the first 29 : // time SetState is invoked. The caller of SetState gets intrusive 30 : // pointer to IFMapNodeState enabling the caller hold IFMapNode 31 : // till reference is removed. Caller does not need to invoke 32 : // clear state as it gets automatically cleared when references are 33 : // removed. Optionally a DBEntry can be added to this IFMapNodeState 34 : // to trigger the IFMapDependency tracker. 35 : // IFMapDependency tracker also uses the same state, to ensure that 36 : // across the traversal, IFMapNode is not removed. 37 : class IFMapNodeState : public DBState { 38 : public: 39 113 : IFMapNodeState(IFMapDependencyManager *manager, IFMapNode *node) 40 226 : : manager_(manager), node_(node), object_(NULL), 41 226 : uuid_(boost::uuids::nil_uuid()), refcount_(0), 42 113 : notify_(true), oper_db_request_enqueued_(false) { 43 113 : } 44 : 45 2245 : IFMapNode *node() { return node_; } 46 615 : DBEntry *object() { return object_; } 47 47 : void set_object(DBEntry *object) { 48 47 : object_ = object; 49 47 : } 50 : 51 409 : void set_uuid(const boost::uuids::uuid &u) { 52 409 : uuid_ = u; 53 409 : } 54 : 55 12 : void set_notify(bool flag) { 56 12 : notify_ = flag; 57 12 : } 58 : 59 478 : void set_oper_db_request_enqueued(bool oper_db_request_enqueued) { 60 478 : oper_db_request_enqueued_ = oper_db_request_enqueued; 61 478 : } 62 : 63 1016 : bool notify() { return notify_;}; 64 : 65 911 : boost::uuids::uuid uuid() { return uuid_; } 66 : 67 47 : void clear_object() { 68 47 : object_ = NULL; 69 47 : } 70 : 71 495 : bool oper_db_request_enqueued() const { 72 495 : return oper_db_request_enqueued_; 73 : } 74 : 75 : private: 76 : friend void intrusive_ptr_add_ref(IFMapNodeState *state); 77 : friend void intrusive_ptr_release(IFMapNodeState *state); 78 : 79 : IFMapDependencyManager *manager_; 80 : IFMapNode *node_; 81 : DBEntry *object_; 82 : boost::uuids::uuid uuid_; 83 : int refcount_; 84 : bool notify_; 85 : bool oper_db_request_enqueued_; 86 : }; 87 : 88 : 89 : class IFMapDependencyManager { 90 : public: 91 : typedef boost::intrusive_ptr<IFMapNodeState> IFMapNodePtr; 92 : typedef boost::function<void(IFMapNode *, DBEntry *)> ChangeEventHandler; 93 : 94 : struct Link { 95 387 : Link(const std::string &edge, const std::string &vertex, bool interest): 96 387 : edge_(edge), vertex_(vertex), vertex_interest_(interest) { 97 387 : } 98 : std::string edge_; 99 : std::string vertex_; 100 : bool vertex_interest_; 101 : }; 102 : typedef std::vector<Link> Path; 103 : 104 : IFMapDependencyManager(DB *database, DBGraph *graph); 105 : virtual ~IFMapDependencyManager(); 106 : 107 : /* 108 : * Initialize must be called after the ifmap tables are registered 109 : * via <schema>_Agent_ModuleInit. 110 : */ 111 : void Initialize(Agent *agent); 112 : 113 : /* 114 : * Unregister from all tables. 115 : */ 116 : void Terminate(); 117 : 118 : void AddDependencyPath(const std::string &node, Path path); 119 : void InitializeDependencyRules(Agent *agent); 120 : /* 121 : * Register reactor-map for an IFMap node 122 : */ 123 : void RegisterReactionMap(const char *node_name, 124 : const IFMapDependencyTracker::ReactionMap &react); 125 : /* 126 : * Associate an IFMapNode with an object in the operational database. 127 : */ 128 : void SetObject(IFMapNode *node, DBEntry *entry); 129 : 130 : /* 131 : * Add DBState to an IFMapNode 132 : */ 133 : IFMapNodePtr SetState(IFMapNode *node); 134 : void SetNotify(IFMapNode *node, bool notfiy_flag); 135 : void SetRequestEnqueued(IFMapNode *node, bool oper_db_request_enqueued); 136 : IFMapNodeState *IFMapNodeGet(IFMapNode *node); 137 : 138 : /* 139 : * Get DBEntry object set for an IFMapNode 140 : */ 141 : DBEntry *GetObject(IFMapNode *node); 142 : 143 : /* 144 : * Register a notification callback. 145 : */ 146 : void Register(const std::string &type, ChangeEventHandler handler); 147 : 148 : /* 149 : * Unregister a notification callback. 150 : */ 151 : void Unregister(const std::string &type); 152 : 153 0 : IFMapDependencyTracker *tracker() const { return tracker_.get(); } 154 : void PropogateNodeChange(IFMapNode *node); 155 : void PropogateNodeAndLinkChange(IFMapNode *node); 156 : 157 : // Check if a IFMapNode type is registerd with dependency manager 158 : bool IsRegistered(const IFMapNode *node); 159 : bool IsNodeIdentifiedByUuid(const IFMapNode *node); 160 : 161 : //Routines used by unit-test 162 1 : void enable_trigger() {trigger_->set_enable();} 163 1 : void disable_trigger() {trigger_->set_disable();} 164 : 165 : private: 166 : /* 167 : * IFMapNodeState (DBState) should exist: 168 : * a) if the object is set 169 : * b) if the entry is on the change list. 170 : */ 171 : friend void intrusive_ptr_add_ref(IFMapNodeState *state); 172 : friend void intrusive_ptr_release(IFMapNodeState *state); 173 : 174 : typedef std::vector<IFMapNodePtr> ChangeList; 175 : typedef std::map<std::string, DBTable::ListenerId> TableMap; 176 : typedef std::map<std::string, ChangeEventHandler> EventMap; 177 : 178 : bool ProcessChangeList(); 179 : 180 : void NodeObserver(DBTablePartBase *root, DBEntryBase *db_entry); 181 : void LinkObserver(DBTablePartBase *root, DBEntryBase *db_entry); 182 : void ChangeListAdd(IFMapNode *node); 183 : 184 : void IFMapNodeReset(IFMapNode *node); 185 : 186 : Agent *agent_; 187 : DB *database_; 188 : DBGraph *graph_; 189 : std::unique_ptr<IFMapDependencyTracker> tracker_; 190 : std::unique_ptr<TaskTrigger> trigger_; 191 : TableMap table_map_; 192 : EventMap event_map_; 193 : ChangeList change_list_; 194 : }; 195 : 196 : #endif