Please note that active projects have migrated to https://github.com/fawkesrobotics.

robot-memory: fix include circular dependency
[fawkes.git] / src / plugins / robot-memory / robot_memory.h
1 /***************************************************************************
2  *  robot_memory.h - Class for storing and querying information in the RobotMemory
3  *    
4  *  Created: Aug 23, 2016 1:34:32 PM 2016
5  *  Copyright  2016  Frederik Zwilling
6  *             2017 Tim Niemueller [www.niemueller.de]
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 #ifndef __PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_
22 #define __PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_
23
24 #include <aspect/clock.h>
25 #include <aspect/configurable.h>
26 #include <aspect/logging.h>
27 #include <aspect/blackboard.h>
28 #include <plugins/mongodb/aspect/mongodb_conncreator.h>
29 #include <memory>
30 #include <vector>
31
32 #include <mongo/client/dbclient.h>
33 #include "event_trigger_manager.h"
34 #include "computables/computables_manager.h"
35
36 namespace fawkes {
37   class Mutex;
38   class RobotMemoryInterface;
39 }
40
41 ///typedef for shorter type description
42 typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
43
44 class RobotMemory
45 {
46   /// Friend the RobotMemoryThread so that only it can access the loop and init functions
47   friend class RobotMemoryThread;
48
49   public:
50     RobotMemory(fawkes::Configuration* config, fawkes::Logger* logger,
51                 fawkes::Clock* clock, fawkes::MongoDBConnCreator* mongo_connection_manager,
52                 fawkes::BlackBoard* blackboard);
53     virtual ~RobotMemory();
54
55     //robot memory functions
56     QResCursor query(mongo::Query query, std::string collection = "");
57     mongo::BSONObj aggregate(std::vector<mongo::BSONObj> pipeline, std::string collection = "");
58     int insert(mongo::BSONObj obj, std::string collection = "");
59     int insert(std::vector<mongo::BSONObj> v_obj, std::string collection = "");
60     int insert(std::string obj_str, std::string collection = "");
61     int update(mongo::Query query, mongo::BSONObj update, std::string collection = "", bool upsert = false);
62     int update(mongo::Query query, std::string update_str, std::string collection = "", bool upsert = false);
63     mongo::BSONObj find_one_and_update(const mongo::BSONObj& filter, const mongo::BSONObj& update,
64                                        std::string collection, bool upsert = false, bool return_new = true);
65     int remove(mongo::Query query, std::string collection = "");
66     mongo::BSONObj mapreduce(mongo::Query query, std::string collection,
67                              std::string js_map_fun, std::string js_reduce_fun);
68     QResCursor aggregate(mongo::BSONObj pipeline, std::string collection = "");
69     int drop_collection(std::string collection);
70     int clear_memory();
71     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
72     int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
73     int create_index(mongo::BSONObj keys, std::string collection = "", bool unique = false);
74
75     //bool semaphore_create(const std::string& name, unsigned int value);
76     //bool semaphore_acquire(const std::string& name, unsigned int v = 1);
77     //bool semaphore_release(const std::string& name, unsigned int v = 1);
78     bool mutex_setup_ttl(float max_age_sec);
79     bool mutex_create(const std::string& name);
80     bool mutex_destroy(const std::string& name);
81     bool mutex_try_lock(const std::string& name, bool force = false);
82     bool mutex_try_lock(const std::string& name, std::string identity, bool force = false);
83     bool mutex_unlock(const std::string& name, std::string identity);
84     bool mutex_renew_lock(const std::string& name, std::string identity);
85     bool mutex_expire_locks(float max_age_sec);
86
87     /**
88      * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
89      * @param query Query the updated document has to match
90      * @param collection db.collection to use
91      * @param callback Callback function (e.g. &Class::callback)
92      * @param _obj Pointer to class the callback is a function of (usaually this)
93      * @return Trigger object pointer, save it to remove the trigger later
94      */
95     template<typename T>
96     EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
97     {
98       check_collection_name(collection);
99       return trigger_manager_->register_trigger(query, collection, callback, _obj);
100     }
101     /**
102      * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
103      * @param query_str Query as JSON string
104      * @param collection db.collection to use
105      * @param callback Callback function (e.g. &Class::callback)
106      * @param _obj Pointer to class the callback is a function of (usaually this)
107      * @return Trigger object pointer, save it to remove the trigger later
108      */
109     template<typename T>
110     EventTrigger* register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
111     {
112       check_collection_name(collection);
113       return register_trigger(mongo::fromjson(query_str), collection, callback, _obj);
114     }
115     void remove_trigger(EventTrigger* trigger);
116
117     /**
118      * Registers a Computable which provides information in the robot memory that is computed on demand.
119      *
120      * @param query_to_compute Query describing what the function computes. Yor computable is called when an new query matches the key value fields in the identifiyer.
121      * @param collection db.collection to fill with computed information
122      * @param compute_func Callback function that computes the information and retruns a list of computed documents
123      * @param obj Pointer to class the callback is a function of (usaually this)
124      * @param caching_time How long should computed results for a query be cached and be used for identical queries in that time?
125      * @param priority Computable priority ordering the evaluation
126      * @return Computable Object pointer used for removing it
127      */
128     template<typename T>
129     Computable* register_computable(mongo::Query query_to_compute, std::string collection, std::list<mongo::BSONObj>(T::*compute_func)(mongo::BSONObj, std::string), T *obj, double caching_time = 0.0, int priority = 0)
130     {
131       check_collection_name(collection);
132       return computables_manager_->register_computable(query_to_compute, collection, compute_func, obj, caching_time, priority);
133     }
134     void remove_computable(Computable* computable);
135
136   private:
137     fawkes::MongoDBConnCreator* mongo_connection_manager_;
138     mongo::DBClientBase* mongodb_client_local_;
139     mongo::DBClientBase* mongodb_client_distributed_;
140     bool distributed_;
141     fawkes::Configuration* config_;
142     fawkes::Logger* logger_;
143     fawkes::Clock* clock_;
144     fawkes::BlackBoard* blackboard_;
145
146     const char* name_ = "RobotMemory";
147     std::string database_name_;
148     std::string default_collection_;
149     bool debug_;
150     fawkes::Mutex *mutex_;
151     fawkes::RobotMemoryInterface* rm_if_;
152     EventTriggerManager* trigger_manager_;
153     ComputablesManager* computables_manager_;
154     std::vector<std::string> distributed_dbs_;
155
156     unsigned int cfg_startup_grace_period_;
157     std::string  cfg_coord_database_;
158     std::string  cfg_coord_mutex_collection_;
159
160     void init();
161     void loop();
162
163     void log(std::string what, std::string level = "info");
164     void log_deb(std::string what, std::string level = "info");
165     void log(mongo::Query query, std::string what, std::string level = "info");
166     void log(mongo::BSONObj obj, std::string what, std::string level = "info");
167     void log_deb(mongo::Query query, std::string what, std::string level = "info");
168     void log_deb(mongo::BSONObj obj, std::string what, std::string level = "info");
169
170     void set_fields(mongo::BSONObj &obj, std::string what);
171     void set_fields(mongo::Query &q, std::string what);
172     void remove_field(mongo::Query &q, std::string what);
173
174     void check_collection_name(std::string &collection);
175     mongo::DBClientBase* get_mongodb_client(std::string &collection);
176 };
177
178 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_ROBOT_MEMORY_H_ */