OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
feature_flags.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef BASE_FEATURE_FLAGS_H_
6 #define BASE_FEATURE_FLAGS_H_
7 
8 #include <string>
9 
10 #include <boost/function.hpp>
11 #include <boost/scoped_ptr.hpp>
12 
13 #include <base/logging.h>
14 #include <base/sandesh/process_info_constants.h>
15 #include <base/sandesh/process_info_types.h>
16 
17 #include "rapidjson/document.h"
18 #include "rapidjson/stringbuffer.h"
19 #include "rapidjson/writer.h"
20 
21 #include <tbb/mutex.h>
22 
93 namespace process {
94 
95 class FlagManager;
96 
97 
104 struct FlagState {
105  enum Type {
107  ALPHA = 1,
108  BETA = 2,
112  };
113 
114  static std::string ToString(Type state) {
115  switch (state) {
116  case EXPERIMENTAL:
117  return "Experimental";
118  break;
119  case ALPHA:
120  return "Alpha";
121  break;
122  case BETA:
123  return "Beta";
124  break;
125  case IN_PROGRESS:
126  return "In Progress";
127  break;
128  case PRE_RETIRED:
129  return "Pre Retired";
130  break;
131  case UNKNOWN:
132  return "Unknown";
133  break;
134  }
135  return "Unknown";
136  }
137 
138  static Type FromString(const std::string& type) {
139  if (type == "Experimental") {
140  return EXPERIMENTAL;
141  }
142  if (type == "Alpha") {
143  return ALPHA;
144  }
145  if (type == "Beta") {
146  return BETA;
147  }
148  if (type == "In-Progress") {
149  return IN_PROGRESS;
150  }
151  if (type == "Pre-Retired") {
152  return PRE_RETIRED;
153  }
154  if (type == "Unknown") {
155  return UNKNOWN;
156  }
157  return UNKNOWN;
158  }
159 };
160 
161 struct FlagContext {
162  FlagContext(const std::string& description, const std::string &val)
163  : desc(description),
164  value(val) {}
165 
166  bool operator == (const FlagContext & rhs) const {
167  if (!(desc == rhs.desc))
168  return false;
169  if (!(value == rhs.value))
170  return false;
171  return true;
172  }
173  bool operator != (const FlagContext &rhs) const {
174  return !(*this == rhs);
175  }
176 
177  std::string desc;
178  std::string value;
179 };
180 
181 typedef std::vector<FlagContext> ContextVec;
182 typedef std::vector<FlagContext>::const_iterator context_iterator;
183 typedef std::vector<FlagContext>::size_type context_size;
184 
185 class FlagConfig {
186 public:
187  FlagConfig(const std::string &name,const std::string &version,
189  : name_(name),
190  version_(version),
191  enabled_(enabled),
192  state_(state),
193  context_infos_(context_infos) {}
195 
199  void set_name(const std::string &val) { name_ = val; }
200  const std::string& name() const { return name_; }
201 
202  void set_version(const std::string &val) { version_ = val; }
203  const std::string& version() const { return version_; }
204 
205  void set_enabled(bool val) { enabled_ = val; }
206  bool enabled() const { return enabled_; }
207 
208  void set_state(const FlagState::Type &val) { state_ = val; }
209  const FlagState::Type& state() const { return state_; }
210 
211  void set_context_infos(const ContextVec &val) { context_infos_ = val; }
212  const ContextVec &context_infos() const { return context_infos_; }
213 
214  bool operator == (const FlagConfig &rhs) const {
215  if (!(name_ == rhs.name_))
216  return false;
217  if (!(version_ == rhs.version_))
218  return false;
219  if (!(enabled_ == rhs.enabled_))
220  return false;
221  if (!(state_ == rhs.state_))
222  return false;
223  if (!(context_infos_ == rhs.context_infos_))
224  return false;
225  return true;
226  }
227 
228  bool operator != (const FlagConfig &rhs) const {
229  return !(*this == rhs);
230  }
231 private:
232  std::string name_;
233  std::string version_;
234  bool enabled_;
237 };
238 
239 typedef std::vector<FlagConfig> FlagConfigVec;
240 typedef std::vector<FlagConfig>::const_iterator flag_cfg_itr;
241 
242 
258 class Flag
259 {
260 public:
267  typedef boost::function<void ()> FlagStateCb;
268 
274  Flag(FlagManager *manager, const std::string &name,
275  const std::string &description, bool enabled,
277 
282  Flag(const Flag& flag, FlagStateCb callback);
283 
287  Flag() {};
288  ~Flag();
289 
293  void InvokeCb();
294 
298  void set_name(const std::string &val) { name_ = val; }
299  const std::string& name() const { return name_; }
300 
301  void set_description(const std::string &val) { description_ = val; }
302  const std::string& description() const { return description_; }
303 
304  void set_enabled(const bool val) { enabled_ = val; }
305  const bool enabled() const { return enabled_; }
306 
307  void set_context_infos(const ContextVec &val) { context_infos_ = val; }
308  const ContextVec &context_infos() const { return context_infos_; }
309 
310  bool operator == (const Flag &rhs) const;
311  bool operator != (const Flag &rhs) const;
312 private:
313  std::string name_;
314  std::string description_;
315  bool enabled_;
317 
320 
322 };
323 
324 typedef std::vector<Flag> FlagVec;
325 
339 public:
340  static FlagConfigManager* GetInstance();
341  static void Initialize(const string &build_info);
342 
347  void Set(const std::string &name,const std::string &version_info,
348  bool enabled, FlagState::Type state, ContextVec &context_infos);
349 
353  void Unset(const std::string &name);
354 
355 private:
356  // Singleton
357  FlagConfigManager(FlagManager *manager);
358 
359  static boost::scoped_ptr<FlagConfigManager> instance_;
361 
362  static std::string version_;
363 
365 };
366 
367 // ----------------------------------------------------------------------------
368 
380 public:
381  static FlagUveManager* GetInstance();
382 
394  void SendUVE();
395 
399  FlagConfigVec GetFlagInfos(bool lock) const;
400 private:
402 
408  typedef boost::function<void (void)> FlagUveCb;
409 
410  // Singleton
411  FlagUveManager(FlagManager *manager, FlagUveCb send_uve_cb);
412  static void CreateInstance(FlagManager *mgr, FlagUveCb send_uve_cb);
413 
414  static boost::scoped_ptr<FlagUveManager> instance_;
417 
419 };
420 
421 // ----------------------------------------------------------------------------
422 
446 {
447 public:
448  static FlagManager* GetInstance();
449 
459  void Set(const std::string &name, const std::string &version, bool enabled,
460  FlagState::Type state, ContextVec &context_infos);
461 
465  void Unset(const std::string &name);
466 
472  bool IsFlagEnabled(const std::string &name, bool default_state,
473  const ContextVec &c_vec) const;
474 
478  void ClearFlags();
479 
483  size_t GetFlagMapCount() const;
484 
496  void Register(Flag *flag);
497 
501  void Unregister(const Flag *flag);
502 
506  bool IsRegistered(const Flag *flag) const;
507 
511  size_t GetIntMapCount() const;
512 
523  FlagConfigVec GetFlagInfos() const;
524 
525 private:
526  friend class Flag;
527  friend class FlagConfigManager;
528  friend class FlagUveManager;
529 
531  }
532 
544  typedef std::map<std::string, FlagConfig> FlagMap;
545  typedef std::map<std::string, FlagConfig>::iterator flag_map_itr;
546  typedef std::map<std::string, FlagConfig>::const_iterator flag_map_citr;
547 
562  typedef std::multimap<std::string, Flag *> InterestMap;
563  typedef std::multimap<std::string, Flag *>::const_iterator int_map_const_itr;
564  typedef std::multimap<std::string, Flag *>::iterator int_map_itr;
565 
566  // ==============================================================
567 
569 
570  static boost::scoped_ptr<FlagManager> instance_;
571  mutable tbb::mutex mutex_;
572 
573  FlagMap flag_map_; // map for capability-list/user-config
574  InterestMap int_map_; // map for storing module interest
575 
577 };
578 
579 
580 } // namespace process
581 #endif // BASE_FEATURE_FLAGS_H_
const FlagState::Type & state() const
static void Initialize(const string &build_info)
const std::string & version() const
void Unset(const std::string &name)
void set_name(const std::string &val)
void set_enabled(bool val)
std::string description_
void Set(const std::string &name, const std::string &version, bool enabled, FlagState::Type state, ContextVec &context_infos)
static FlagUveManager * GetInstance()
static boost::scoped_ptr< FlagUveManager > instance_
FlagState::Type state_
size_t GetIntMapCount() const
void Unset(const std::string &name)
std::string name_
bool enabled() const
static FlagConfigManager * GetInstance()
DISALLOW_COPY_AND_ASSIGN(FlagManager)
std::map< std::string, FlagConfig >::const_iterator flag_map_citr
ContextVec context_infos_
bool operator!=(const FlagConfig &rhs) const
FlagConfigVec GetFlagInfos() const
static std::string ToString(Type state)
void Unregister(const Flag *flag)
std::map< std::string, FlagConfig > FlagMap
const ContextVec & context_infos() const
boost::function< void(void)> FlagUveCb
void Register(Flag *flag)
FlagManager * flag_manager_
std::multimap< std::string, Flag * >::const_iterator int_map_const_itr
const bool enabled() const
ContextVec context_infos_
void set_description(const std::string &val)
size_t GetFlagMapCount() const
DISALLOW_COPY_AND_ASSIGN(FlagUveManager)
void set_version(const std::string &val)
bool operator==(const FlagContext &rhs) const
bool operator!=(const FlagContext &rhs) const
std::map< std::string, FlagConfig >::iterator flag_map_itr
uint8_t type
Definition: load_balance.h:109
std::vector< Flag > FlagVec
void Set(const std::string &name, const std::string &version_info, bool enabled, FlagState::Type state, ContextVec &context_infos)
DISALLOW_COPY_AND_ASSIGN(FlagConfigManager)
static FlagManager * GetInstance()
void set_context_infos(const ContextVec &val)
FlagConfigVec GetFlagInfosUnlocked() const
std::string version_
std::vector< FlagConfig > FlagConfigVec
void set_enabled(const bool val)
static void CreateInstance(FlagManager *mgr, FlagUveCb send_uve_cb)
FlagConfigVec GetFlagInfos(bool lock) const
const ContextVec & context_infos() const
void set_context_infos(const ContextVec &val)
std::multimap< std::string, Flag * > InterestMap
FlagStateCb flag_state_cb_
std::multimap< std::string, Flag * >::iterator int_map_itr
bool operator==(const Flag &rhs) const
static std::string version_
DISALLOW_COPY_AND_ASSIGN(Flag)
FlagContext(const std::string &description, const std::string &val)
bool IsRegistered(const Flag *flag) const
bool operator!=(const Flag &rhs) const
const std::string & name() const
FlagUveManager(FlagManager *manager, FlagUveCb send_uve_cb)
boost::function< void()> FlagStateCb
std::vector< FlagContext > ContextVec
std::vector< FlagContext >::const_iterator context_iterator
std::vector< FlagContext >::size_type context_size
const std::string & description() const
std::vector< FlagConfig >::const_iterator flag_cfg_itr
static boost::scoped_ptr< FlagManager > instance_
bool operator==(const FlagConfig &rhs) const
bool IsFlagEnabled(const std::string &name, bool default_state, const ContextVec &c_vec) const
FlagConfig(const std::string &name, const std::string &version, bool enabled, FlagState::Type state, ContextVec &context_infos)
void set_state(const FlagState::Type &val)
FlagConfigManager(FlagManager *manager)
FlagManager * manager_
static boost::scoped_ptr< FlagConfigManager > instance_
void set_name(const std::string &val)
const std::string & name() const
static Type FromString(const std::string &type)