OpenSDN source code
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 #include <mutex>
10 
11 #include <boost/function.hpp>
12 #include <boost/scoped_ptr.hpp>
13 
14 #include <base/logging.h>
15 #include <base/sandesh/process_info_constants.h>
16 #include <base/sandesh/process_info_types.h>
17 
18 #include "rapidjson/document.h"
19 #include "rapidjson/stringbuffer.h"
20 #include "rapidjson/writer.h"
21 
92 namespace process {
93 
94 class FlagManager;
95 
96 
103 struct FlagState {
104  enum Type {
106  ALPHA = 1,
107  BETA = 2,
110  UNKNOWN = 5
111  };
112 
113  static std::string ToString(Type state) {
114  switch (state) {
115  case EXPERIMENTAL:
116  return "Experimental";
117  break;
118  case ALPHA:
119  return "Alpha";
120  break;
121  case BETA:
122  return "Beta";
123  break;
124  case IN_PROGRESS:
125  return "In Progress";
126  break;
127  case PRE_RETIRED:
128  return "Pre Retired";
129  break;
130  case UNKNOWN:
131  return "Unknown";
132  break;
133  }
134  return "Unknown";
135  }
136 
137  static Type FromString(const std::string& type) {
138  if (type == "Experimental") {
139  return EXPERIMENTAL;
140  }
141  if (type == "Alpha") {
142  return ALPHA;
143  }
144  if (type == "Beta") {
145  return BETA;
146  }
147  if (type == "In-Progress") {
148  return IN_PROGRESS;
149  }
150  if (type == "Pre-Retired") {
151  return PRE_RETIRED;
152  }
153  if (type == "Unknown") {
154  return UNKNOWN;
155  }
156  return UNKNOWN;
157  }
158 };
159 
160 struct FlagContext {
161  FlagContext(const std::string& description, const std::string &val)
162  : desc(description),
163  value(val) {}
164 
165  bool operator == (const FlagContext & rhs) const {
166  if (!(desc == rhs.desc))
167  return false;
168  if (!(value == rhs.value))
169  return false;
170  return true;
171  }
172  bool operator != (const FlagContext &rhs) const {
173  return !(*this == rhs);
174  }
175 
176  std::string desc;
177  std::string value;
178 };
179 
180 typedef std::vector<FlagContext> ContextVec;
181 typedef std::vector<FlagContext>::const_iterator context_iterator;
182 typedef std::vector<FlagContext>::size_type context_size;
183 
184 class FlagConfig {
185 public:
186  FlagConfig(const std::string &name,const std::string &version,
188  : name_(name),
189  version_(version),
190  enabled_(enabled),
191  state_(state),
194 
198  void set_name(const std::string &val) { name_ = val; }
199  const std::string& name() const { return name_; }
200 
201  void set_version(const std::string &val) { version_ = val; }
202  const std::string& version() const { return version_; }
203 
204  void set_enabled(bool val) { enabled_ = val; }
205  bool enabled() const { return enabled_; }
206 
207  void set_state(const FlagState::Type &val) { state_ = val; }
208  const FlagState::Type& state() const { return state_; }
209 
210  void set_context_infos(const ContextVec &val) { context_infos_ = val; }
211  const ContextVec &context_infos() const { return context_infos_; }
212 
213  bool operator == (const FlagConfig &rhs) const {
214  if (!(name_ == rhs.name_))
215  return false;
216  if (!(version_ == rhs.version_))
217  return false;
218  if (!(enabled_ == rhs.enabled_))
219  return false;
220  if (!(state_ == rhs.state_))
221  return false;
222  if (!(context_infos_ == rhs.context_infos_))
223  return false;
224  return true;
225  }
226 
227  bool operator != (const FlagConfig &rhs) const {
228  return !(*this == rhs);
229  }
230 private:
231  std::string name_;
232  std::string version_;
233  bool enabled_;
236 };
237 
238 typedef std::vector<FlagConfig> FlagConfigVec;
239 typedef std::vector<FlagConfig>::const_iterator flag_cfg_itr;
240 
241 
257 class Flag
258 {
259 public:
266  typedef boost::function<void ()> FlagStateCb;
267 
273  Flag(FlagManager *manager, const std::string &name,
274  const std::string &description, bool enabled,
276 
281  Flag(const Flag& flag, FlagStateCb callback);
282 
286  Flag() {};
287  ~Flag();
288 
292  void InvokeCb();
293 
297  void set_name(const std::string &val) { name_ = val; }
298  const std::string& name() const { return name_; }
299 
300  void set_description(const std::string &val) { description_ = val; }
301  const std::string& description() const { return description_; }
302 
303  void set_enabled(const bool val) { enabled_ = val; }
304  const bool enabled() const { return enabled_; }
305 
306  void set_context_infos(const ContextVec &val) { context_infos_ = val; }
307  const ContextVec &context_infos() const { return context_infos_; }
308 
309  bool operator == (const Flag &rhs) const;
310  bool operator != (const Flag &rhs) const;
311 private:
312  std::string name_;
313  std::string description_;
314  bool enabled_;
316 
319 
321 };
322 
323 typedef std::vector<Flag> FlagVec;
324 
338 public:
339  static FlagConfigManager* GetInstance();
340  static void Initialize(const string &build_info);
341 
346  void Set(const std::string &name,const std::string &version_info,
347  bool enabled, FlagState::Type state, ContextVec &context_infos);
348 
352  void Unset(const std::string &name);
353 
354 private:
355  // Singleton
356  FlagConfigManager(FlagManager *manager);
357 
358  static boost::scoped_ptr<FlagConfigManager> instance_;
360 
361  static std::string version_;
362 
364 };
365 
366 // ----------------------------------------------------------------------------
367 
379 public:
380  static FlagUveManager* GetInstance();
381 
393  void SendUVE();
394 
398  FlagConfigVec GetFlagInfos(bool lock) const;
399 private:
401 
407  typedef boost::function<void (void)> FlagUveCb;
408 
409  // Singleton
410  FlagUveManager(FlagManager *manager, FlagUveCb send_uve_cb);
411  static void CreateInstance(FlagManager *mgr, FlagUveCb send_uve_cb);
412 
413  static boost::scoped_ptr<FlagUveManager> instance_;
416 
418 };
419 
420 // ----------------------------------------------------------------------------
421 
445 {
446 public:
447  static FlagManager* GetInstance();
448 
458  void Set(const std::string &name, const std::string &version, bool enabled,
459  FlagState::Type state, ContextVec &context_infos);
460 
464  void Unset(const std::string &name);
465 
471  bool IsFlagEnabled(const std::string &name, bool default_state,
472  const ContextVec &c_vec) const;
473 
477  void ClearFlags();
478 
482  size_t GetFlagMapCount() const;
483 
495  void Register(Flag *flag);
496 
500  void Unregister(const Flag *flag);
501 
505  bool IsRegistered(const Flag *flag) const;
506 
510  size_t GetIntMapCount() const;
511 
522  FlagConfigVec GetFlagInfos() const;
523 
524 private:
525  friend class Flag;
526  friend class FlagConfigManager;
527  friend class FlagUveManager;
528 
530  }
531 
543  typedef std::map<std::string, FlagConfig> FlagMap;
544  typedef std::map<std::string, FlagConfig>::iterator flag_map_itr;
545  typedef std::map<std::string, FlagConfig>::const_iterator flag_map_citr;
546 
561  typedef std::multimap<std::string, Flag *> InterestMap;
562  typedef std::multimap<std::string, Flag *>::const_iterator int_map_const_itr;
563  typedef std::multimap<std::string, Flag *>::iterator int_map_itr;
564 
565  // ==============================================================
566 
568 
569  static boost::scoped_ptr<FlagManager> instance_;
570  mutable std::mutex mutex_;
571 
572  FlagMap flag_map_; // map for capability-list/user-config
573  InterestMap int_map_; // map for storing module interest
574 
576 };
577 
578 
579 } // namespace process
580 #endif // BASE_FEATURE_FLAGS_H_
DISALLOW_COPY_AND_ASSIGN(FlagConfigManager)
FlagConfigManager(FlagManager *manager)
void Unset(const std::string &name)
static FlagConfigManager * GetInstance()
static std::string version_
static boost::scoped_ptr< FlagConfigManager > instance_
static void Initialize(const string &build_info)
void Set(const std::string &name, const std::string &version_info, bool enabled, FlagState::Type state, ContextVec &context_infos)
void set_version(const std::string &val)
std::string version_
ContextVec context_infos_
void set_name(const std::string &val)
FlagState::Type state_
void set_enabled(bool val)
const FlagState::Type & state() const
void set_state(const FlagState::Type &val)
const std::string & name() const
bool operator==(const FlagConfig &rhs) const
bool enabled() const
const std::string & version() const
const ContextVec & context_infos() const
void set_context_infos(const ContextVec &val)
FlagConfig(const std::string &name, const std::string &version, bool enabled, FlagState::Type state, ContextVec &context_infos)
bool operator!=(const FlagConfig &rhs) const
bool IsRegistered(const Flag *flag) const
size_t GetIntMapCount() const
std::map< std::string, FlagConfig >::iterator flag_map_itr
std::multimap< std::string, Flag * >::iterator int_map_itr
size_t GetFlagMapCount() const
void Register(Flag *flag)
void Set(const std::string &name, const std::string &version, bool enabled, FlagState::Type state, ContextVec &context_infos)
static FlagManager * GetInstance()
FlagConfigVec GetFlagInfosUnlocked() const
std::multimap< std::string, Flag * >::const_iterator int_map_const_itr
void Unregister(const Flag *flag)
bool IsFlagEnabled(const std::string &name, bool default_state, const ContextVec &c_vec) const
void Unset(const std::string &name)
static boost::scoped_ptr< FlagManager > instance_
DISALLOW_COPY_AND_ASSIGN(FlagManager)
FlagConfigVec GetFlagInfos() const
std::map< std::string, FlagConfig >::const_iterator flag_map_citr
std::multimap< std::string, Flag * > InterestMap
std::map< std::string, FlagConfig > FlagMap
FlagConfigVec GetFlagInfos(bool lock) const
boost::function< void(void)> FlagUveCb
static void CreateInstance(FlagManager *mgr, FlagUveCb send_uve_cb)
static boost::scoped_ptr< FlagUveManager > instance_
DISALLOW_COPY_AND_ASSIGN(FlagUveManager)
FlagManager * flag_manager_
FlagUveManager(FlagManager *manager, FlagUveCb send_uve_cb)
static FlagUveManager * GetInstance()
const ContextVec & context_infos() const
bool operator!=(const Flag &rhs) const
void set_context_infos(const ContextVec &val)
std::string name_
bool operator==(const Flag &rhs) const
void set_name(const std::string &val)
DISALLOW_COPY_AND_ASSIGN(Flag)
FlagManager * manager_
const std::string & name() const
boost::function< void()> FlagStateCb
void set_description(const std::string &val)
ContextVec context_infos_
void set_enabled(const bool val)
std::string description_
const bool enabled() const
const std::string & description() const
FlagStateCb flag_state_cb_
Flag(FlagManager *manager, const std::string &name, const std::string &description, bool enabled, ContextVec &context_infos)
uint8_t type
Definition: load_balance.h:2
std::vector< FlagContext >::size_type context_size
std::vector< Flag > FlagVec
std::vector< FlagConfig > FlagConfigVec
std::vector< FlagContext >::const_iterator context_iterator
std::vector< FlagContext > ContextVec
std::vector< FlagConfig >::const_iterator flag_cfg_itr
bool operator!=(const FlagContext &rhs) const
bool operator==(const FlagContext &rhs) const
FlagContext(const std::string &description, const std::string &val)
static Type FromString(const std::string &type)
static std::string ToString(Type state)