Fawkes API  Fawkes Development Version
event_trigger_manager.h
1 /***************************************************************************
2  * event_trigger_manager.h - Manager to realize triggers on events in the robot memory
3  *
4  *
5  * Created: 3:53:45 PM 2016
6  * Copyright 2016 Frederik Zwilling
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #ifndef FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
23 #define FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
24 
25 #include "event_trigger.h"
26 
27 #include <aspect/configurable.h>
28 #include <aspect/logging.h>
29 #include <core/threading/mutex_locker.h>
30 #include <plugin/loader.h>
31 #include <plugins/mongodb/aspect/mongodb_conncreator.h>
32 
33 #include <boost/bind.hpp>
34 #include <list>
35 
36 namespace mongo {
37 class DBClientBase;
38 class DBClientCursor;
39 } // namespace mongo
40 
41 ///typedef for shorter type description
42 typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
43 
45 {
46  /// Access for robot memory to use the check_events function in the loop
47  friend class RobotMemory;
48 
49 public:
51  fawkes::Configuration * config,
52  fawkes::MongoDBConnCreator *mongo_connection_manager);
53  virtual ~EventTriggerManager();
54 
55  /**
56  * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
57  * @param query Query the updated document has to match
58  * @param collection db.collection to use
59  * @param callback Callback function (e.g. &Class::callback)
60  * @param obj Pointer to class the callback is a function of (usaually this)
61  * @return Trigger object pointer, save it to remove the trigger later
62  */
63  template <typename T>
64  EventTrigger *
65  register_trigger(mongo::Query query,
66  std::string collection,
67  void (T::*callback)(mongo::BSONObj),
68  T *obj)
69  {
70  //lock to be thread safe (e.g. registration during checking)
71  fawkes::MutexLocker lock(mutex_);
72 
73  //construct query for oplog
74  mongo::BSONObjBuilder query_builder;
75  query_builder.append("ns", collection);
76  // added/updated object is a subdocument in the oplog document
77  for (mongo::BSONObjIterator it = query.getFilter().begin(); it.more();) {
78  mongo::BSONElement elem = it.next();
79  query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
80  }
81  mongo::Query oplog_query = query_builder.obj();
82  oplog_query.readPref(mongo::ReadPreference_Nearest, mongo::BSONArray());
83 
84  //check if collection is local or replicated
85  mongo::DBClientBase *con;
86  std::string oplog;
87  oplog = "local.oplog.rs";
88  if (std::find(dbnames_distributed_.begin(), dbnames_distributed_.end(), get_db_name(collection))
89  != dbnames_distributed_.end()) {
90  con = con_replica_;
91  } else {
92  con = con_local_;
93  }
94 
95  EventTrigger *trigger =
96  new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
97  trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
98  triggers.push_back(trigger);
99  return trigger;
100  }
101 
102  void remove_trigger(EventTrigger *trigger);
103 
104  static std::string get_db_name(const std::string &ns);
105 
106 private:
107  void check_events();
108  QResCursor create_oplog_cursor(mongo::DBClientBase *con, std::string oplog, mongo::Query query);
109 
110  std::string name = "RobotMemory EventTriggerManager";
111  fawkes::Logger * logger_;
112  fawkes::Configuration *config_;
113  fawkes::Mutex * mutex_;
114 
115  fawkes::MongoDBConnCreator *mongo_connection_manager_;
116  //MongoDB connections (necessary because the mongos instance used by the robot memory has no access to the oplog)
117  mongo::DBClientBase *con_local_;
118  mongo::DBClientBase *con_replica_;
119 
120  std::vector<std::string> dbnames_distributed_;
121  std::vector<std::string> dbnames_local_;
122  bool cfg_debug_;
123 
124  std::list<EventTrigger *> triggers;
125 };
126 
127 #endif //FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
QResCursor query(mongo::Query query, const std::string &collection="")
Query information from the robot memory.
Manager to realize triggers on events in the robot memory.
Mutex locking helper.
Definition: mutex_locker.h:33
Class holding all information about an EventTrigger.
Definition: event_trigger.h:32
static std::string get_db_name(const std::string &ns)
Split database name from namespace.
Interface for a MongoDB connection creator.
void remove_trigger(EventTrigger *trigger)
Remove a previously registered trigger.
EventTrigger * register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
Register a trigger to be notified when the robot memory is updated and the updated document matches t...
Access to the robot memory based on mongodb.
Definition: robot_memory.h:48
EventTriggerManager(fawkes::Logger *logger, fawkes::Configuration *config, fawkes::MongoDBConnCreator *mongo_connection_manager)
Constructor for class managing EventTriggers.
Mutex mutual exclusion lock.
Definition: mutex.h:32
Interface for configuration handling.
Definition: config.h:64
Interface for logging.
Definition: logger.h:41