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