[Fawkes Git] branch/fzwilling/robot-memory: 5 revs updated. (0.5.0-3411-g53d178b)

Frederik Zwilling zwilling at kbsg.rwth-aachen.de
Thu Oct 6 19:03:54 CEST 2016


Changes have been pushed for the project "Fawkes Robotics Software Framework".

Gitweb: http://git.fawkesrobotics.org/fawkes.git
Trac:   http://trac.fawkesrobotics.org

The branch, fzwilling/robot-memory has been updated
        to  53d178b07bfcf2d3ebbfe7032c12cddb92c05439 (commit)
       via  325821df6a31cb7702cf5a330e4910b1748921e0 (commit)
       via  ef3d9a20b40ecd024a8143b6f603ac620ec70e43 (commit)
       via  4270c488e8edeb250df1258dfd6a915e836174b3 (commit)
       via  386a339d826b1bf9d0947d5f0879f8e53438c95c (commit)
      from  5729d6f402028c886397bce50000dd9d44fd9d18 (commit)

http://git.fawkesrobotics.org/fawkes.git/fzwilling/robot-memory

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- *Log* ---------------------------------------------------------------
commit 386a339d826b1bf9d0947d5f0879f8e53438c95c
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Mon Oct 3 17:20:38 2016 +0200
Commit:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
CommitDate: Thu Oct 6 19:03:33 2016 +0200

    robot-memory: first prototype for event triggers using the oplog

http://git.fawkesrobotics.org/fawkes.git/commit/386a339
http://trac.fawkesrobotics.org/changeset/386a339

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 4270c488e8edeb250df1258dfd6a915e836174b3
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 11:44:14 2016 +0200
Commit:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
CommitDate: Thu Oct 6 19:03:37 2016 +0200

    robot-memory: handling trigger callback functions

http://git.fawkesrobotics.org/fawkes.git/commit/4270c48
http://trac.fawkesrobotics.org/changeset/4270c48

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit ef3d9a20b40ecd024a8143b6f603ac620ec70e43
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 18:36:45 2016 +0200
Commit:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
CommitDate: Thu Oct 6 19:03:42 2016 +0200

    robot-memory: enable oplog on local mongodb with single replSet
    
    To enable the oplog we have to make the database to a replica set with a
    single member. This is necessary for triggers.

http://git.fawkesrobotics.org/fawkes.git/commit/ef3d9a2
http://trac.fawkesrobotics.org/changeset/ef3d9a2

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 325821df6a31cb7702cf5a330e4910b1748921e0
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 18:46:06 2016 +0200
Commit:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
CommitDate: Thu Oct 6 19:03:46 2016 +0200

    robot-memory: tests and fixes for event triggers

http://git.fawkesrobotics.org/fawkes.git/commit/325821d
http://trac.fawkesrobotics.org/changeset/325821d

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit 53d178b07bfcf2d3ebbfe7032c12cddb92c05439
Author:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
AuthorDate: Thu Oct 6 19:01:30 2016 +0200
Commit:     Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
CommitDate: Thu Oct 6 19:03:51 2016 +0200

    robot-memory: fixed DumpRestore test

http://git.fawkesrobotics.org/fawkes.git/commit/53d178b
http://trac.fawkesrobotics.org/changeset/53d178b

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


- *Summary* -----------------------------------------------------------
 src/plugins/robot-memory/Makefile                  |   17 +++-
 .../robot-memory/event_trigger.cpp}                |   32 +++----
 src/plugins/robot-memory/event_trigger.h           |   51 ++++++++++
 src/plugins/robot-memory/event_trigger_manager.cpp |  102 +++++++++++++++++++
 src/plugins/robot-memory/event_trigger_manager.h   |  103 ++++++++++++++++++++
 src/plugins/robot-memory/robot_memory.cpp          |   18 ++++
 src/plugins/robot-memory/robot_memory.h            |   34 ++++++-
 src/plugins/robot-memory/robot_memory_setup.cpp    |   21 +++--
 src/plugins/robot-memory/robot_memory_thread.cpp   |    2 +
 .../robot-memory/test-plugin/robot_memory_test.cpp |   59 +++++++++++-
 .../robot-memory/test-plugin/robot_memory_test.h   |   18 ++++
 .../test-plugin/robot_memory_test_thread.cpp       |    5 +-
 12 files changed, 426 insertions(+), 36 deletions(-)
 copy src/{tools/ffinfo/ffinfo.cpp => plugins/robot-memory/event_trigger.cpp} (62%)
 create mode 100644 src/plugins/robot-memory/event_trigger.h
 create mode 100644 src/plugins/robot-memory/event_trigger_manager.cpp
 create mode 100644 src/plugins/robot-memory/event_trigger_manager.h


- *Diffs* -------------------------------------------------------------

- *commit* 386a339d826b1bf9d0947d5f0879f8e53438c95c - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Mon Oct 3 17:20:38 2016 +0200
Subject: robot-memory: first prototype for event triggers using the oplog

 src/plugins/robot-memory/event_trigger_manager.cpp |   96 ++++++++++++++++++++
 src/plugins/robot-memory/event_trigger_manager.h   |   66 ++++++++++++++
 src/plugins/robot-memory/robot_memory.cpp          |    9 ++
 src/plugins/robot-memory/robot_memory.h            |    3 +
 src/plugins/robot-memory/robot_memory_thread.cpp   |    2 +
 5 files changed, 176 insertions(+), 0 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 5fba663..cd14986 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -51,6 +51,7 @@ RobotMemory::RobotMemory(fawkes::Configuration* config, fawkes::Logger* logger,
 RobotMemory::~RobotMemory()
 {
   delete mutex_;
+  delete trigger_manager_;
   blackboard_->close(rm_if_);
 }
 
@@ -76,9 +77,17 @@ void RobotMemory::init()
   rm_if_->set_result("");
   rm_if_->write();
 
+  //Setup event trigger manager
+  trigger_manager_ = new EventTriggerManager(logger_, config_);
+
   log_deb("Initialized RobotMemory");
 }
 
+void RobotMemory::loop()
+{
+  trigger_manager_->check_events();
+}
+
 QResCursor RobotMemory::query(Query query, std::string collection)
 {
   check_collection_name(collection);
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 4de84fd..3417f74 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -29,6 +29,7 @@
 
 #include <mongo/client/dbclient.h>
 #include "interfaces/RobotMemoryInterface.h"
+#include "event_trigger_manager.h"
 
 namespace fawkes {
   class Mutex;
@@ -76,8 +77,10 @@ class RobotMemory
     bool debug_;
     fawkes::Mutex *mutex_;
     fawkes::RobotMemoryInterface* rm_if_;
+    EventTriggerManager* trigger_manager_;
 
     void init();
+    void loop();
 
     void log(std::string what, std::string level = "info");
     void log_deb(std::string what, std::string level = "info");
diff --git a/src/plugins/robot-memory/robot_memory_thread.cpp b/src/plugins/robot-memory/robot_memory_thread.cpp
index 807c55d..5509a14 100644
--- a/src/plugins/robot-memory/robot_memory_thread.cpp
+++ b/src/plugins/robot-memory/robot_memory_thread.cpp
@@ -92,5 +92,7 @@ RobotMemoryThread::loop()
 
     robot_memory->rm_if_->msgq_pop();
   }
+
+  robot_memory->loop();
 }
 

- *commit* 4270c488e8edeb250df1258dfd6a915e836174b3 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 11:44:14 2016 +0200
Subject: robot-memory: handling trigger callback functions

 .../robot-memory/event_trigger.cpp}                |   32 ++++------
 src/plugins/robot-memory/event_trigger.h           |   51 +++++++++++++++
 src/plugins/robot-memory/event_trigger_manager.cpp |   66 +++++++++++++++----
 src/plugins/robot-memory/event_trigger_manager.h   |   10 ++-
 src/plugins/robot-memory/robot_memory.cpp          |   18 +++++
 src/plugins/robot-memory/robot_memory.h            |    7 ++-
 6 files changed, 146 insertions(+), 38 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index 46991b8..21d99f9 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -21,10 +21,16 @@
 
 #include "event_trigger_manager.h"
 #include <plugin/loader.h>
+#include <boost/bind.hpp>
 
 using namespace fawkes;
 using namespace mongo;
 
+void EventTriggerManager::callback_test(mongo::BSONObj update)
+{
+  logger_->log_info(name.c_str(), "callback: %s", update.toString().c_str());
+}
+
 EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
 {
   logger_ = logger;
@@ -49,39 +55,71 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
   }
 
   //test setup
-  register_trigger(mongo::fromjson("{}"), "syncedrobmem.test");
+  register_trigger(mongo::fromjson("{test: 0}"), "syncedrobmem.test", &EventTriggerManager::callback_test, this);
 
   logger_->log_info(name.c_str(), "Initialized");
 }
 
 EventTriggerManager::~EventTriggerManager()
 {
+  for(EventTrigger *trigger : triggers)
+    {
+      delete trigger;
+    }
 }
 
 void EventTriggerManager::check_events()
 {
-  while(oplog_cursor->more())
+  for(EventTrigger *trigger : triggers)
   {
-    BSONObj change = oplog_cursor->next();
-    logger_->log_info(name.c_str(), "Oplog has more: %s", change.toString().c_str());
-  }
-  if(oplog_cursor->isDead())
-  {
-    logger_->log_info(name.c_str(), "Tailable Cursor is dead, requerying");
-    oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", oplog_query);
+    while(trigger->oplog_cursor->more())
+    {
+      BSONObj change = trigger->oplog_cursor->next();
+      //actually call the callback function
+      trigger->callback(change);
+    }
+    if(trigger->oplog_cursor->isDead())
+    {
+      logger_->log_debug(name.c_str(), "Tailable Cursor is dead, requerying");
+      trigger->oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", trigger->oplog_query);
+    }
   }
 }
 
-void EventTriggerManager::register_trigger(mongo::Query query, std::string collection)
+template<typename T>
+void EventTriggerManager::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
 {
   logger_->log_info(name.c_str(), "Registering Trigger");
 
-  oplog_query = query;
+  //construct query for oplog
+  BSONObjBuilder query_builder;
+  query_builder.append("ns", collection);
+  // added/updated object is a subdocument in the oplog document
+  for(BSONObjIterator it = query.getFilter().begin(); it.more();)
+  {
+    BSONElement elem = it.next();
+    query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
+  }
+  mongo::Query oplog_query = query_builder.obj();
   oplog_query.readPref(ReadPreference_Nearest, BSONArray());
-  oplog_collection = collection;
 
-  //TODO: check if collection is local or replicated
-  oplog_cursor = create_oplog_cursor(con_replica_, "local.oplog.rs", oplog_query);
+  //check if collection is local or replicated
+  mongo::DBClientConnection* con;
+  std::string oplog;
+  if(collection.find(repl_set) == 0)
+  {
+    con = con_replica_;
+    oplog = "local.oplog.rs";
+  }
+  else
+  {
+    con = con_local_;
+    oplog = "local.oplog";
+  }
+
+  EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
+  trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
+  triggers.push_back(trigger);
 }
 
 QResCursor EventTriggerManager::create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query)
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index e1168d8..ab45725 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -25,6 +25,8 @@
 #include <mongo/client/dbclient.h>
 #include <aspect/logging.h>
 #include <aspect/configurable.h>
+#include <list>
+#include "event_trigger.h"
 
 
 ///typedef for shorter type description
@@ -42,11 +44,13 @@ class EventTriggerManager
     EventTriggerManager(fawkes::Logger* logger, fawkes::Configuration* config);
     virtual ~EventTriggerManager();
 
-    void register_trigger(mongo::Query query, std::string collection);
+    template<typename T>
+    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
 
   private:
     void check_events();
     QResCursor create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query);
+    void callback_test(mongo::BSONObj update);
 
     std::string name = "RobotMemory EventTriggerManager";
     fawkes::Logger* logger_;
@@ -58,9 +62,7 @@ class EventTriggerManager
 
     std::string repl_set, local_db;
 
-    mongo::Query oplog_query;
-    std::string oplog_collection;
-    QResCursor oplog_cursor;
+    std::list<EventTrigger*> triggers;
 };
 
 #endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_ */
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index cd14986..720bacc 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -417,3 +417,21 @@ RobotMemory::check_collection_name(std::string &collection)
     collection.replace(0, 6, default_collection_);
   }
 }
+
+/**
+ * Register a trigger that notifies you when the event specified in the query happens
+ */
+template<typename T>
+void RobotMemory::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+{
+  trigger_manager_->register_trigger(query, collection, callback, _obj);
+}
+
+/**
+ * Register a trigger that notifies you when the event specified in the query happens
+ */
+template<typename T>
+void RobotMemory::register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+{
+  register_trigger(fromjson(query_str), collection, callback);
+}
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 3417f74..4eabaec 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -39,7 +39,7 @@ namespace fawkes {
 ///typedef for shorter type description
 typedef std::unique_ptr<mongo::DBClientCursor> QResCursor;
 
-/*
+/**
  *
  */
 class RobotMemory
@@ -64,6 +64,11 @@ class RobotMemory
     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
     int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
 
+    template<typename T>
+    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    template<typename T>
+    void register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+
   private:
     mongo::DBClientBase* mongodb_client_;
     fawkes::Configuration* config_;

- *commit* ef3d9a20b40ecd024a8143b6f603ac620ec70e43 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 18:36:45 2016 +0200
Subject: robot-memory: enable oplog on local mongodb with single replSet

 src/plugins/robot-memory/robot_memory_setup.cpp |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/robot_memory_setup.cpp b/src/plugins/robot-memory/robot_memory_setup.cpp
index e983d5f..fc4bc29 100644
--- a/src/plugins/robot-memory/robot_memory_setup.cpp
+++ b/src/plugins/robot-memory/robot_memory_setup.cpp
@@ -24,6 +24,7 @@
 #include <mongo/client/dbclient.h>
 #include <mongo/client/init.h>
 #include <utils/misc/string_conversions.h>
+#include <stdio.h>
 
 using namespace fawkes;
 
@@ -48,8 +49,14 @@ void RobotMemorySetup::setup_mongods()
   unsigned int local_port = config->get_uint("plugins/robot-memory/setup/local/port");
   std::string local_db_name = config->get_string("plugins/robot-memory/database");
   std::string local_port_str = std::to_string(local_port);
-  const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(), NULL};
+  const char *local_argv[] = {"mongod", "--port", local_port_str.c_str(),
+      "--replSet", "local", NULL}; //'local' replica set to enable the oplog
   start_mongo_process("mongod-local", local_port, local_argv);
+  std::string local_config = "{_id: 'local', members:[{_id:1,host:'localhost:" + local_port_str + "'}]}";
+  run_mongo_command(local_port, std::string("{replSetInitiate:" + local_config + "}"), "already initialized");
+  //wait for initialization
+  usleep(1000000);
+  create_database(local_port, local_db_name);
 
   //only start other processes when we want to run the robot memory distributed
   if(!config->get_bool("plugins/robot-memory/setup/distributed"))
@@ -113,10 +120,10 @@ void RobotMemorySetup::start_mongo_process(std::string proc_name, unsigned int p
   if (!is_mongo_running(port))
     {
       std::string cmd = command_args_tostring(argv);
-      logger->log_info("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
+      logger->log_error("RobotMemorySetup", "Starting %s process: '%s'", proc_name.c_str(), cmd.c_str());
       config_mongod = new SubProcess(proc_name.c_str(), argv[0], argv, NULL, logger);
       logger->log_info("RobotMemorySetup", "Started %s", proc_name.c_str());
-      wait_until_started(port, cmd);
+      wait_until_started(port, cmd, config->get_int("plugins/robot-memory/setup/max_setup_time"));
     }
 }
 
@@ -126,13 +133,13 @@ void RobotMemorySetup::start_mongo_process(std::string proc_name, unsigned int p
  */
 void RobotMemorySetup::shutdown_mongods()
 {
-  if (local_mongod)
+  if(local_mongod)
     delete local_mongod;
-  if (config_mongod)
+  if(config_mongod)
     delete config_mongod;
-  if (distribuded_mongod)
+  if(distribuded_mongod)
     delete distribuded_mongod;
-  if (mongos)
+  if(mongos)
     delete mongos;
 }
 

- *commit* 325821df6a31cb7702cf5a330e4910b1748921e0 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 18:46:06 2016 +0200
Subject: robot-memory: tests and fixes for event triggers

 src/plugins/robot-memory/Makefile                  |   17 +++++--
 src/plugins/robot-memory/event_trigger_manager.cpp |   52 ++++----------------
 src/plugins/robot-memory/event_trigger_manager.h   |   41 ++++++++++++++-
 src/plugins/robot-memory/robot_memory.cpp          |   17 ++-----
 src/plugins/robot-memory/robot_memory.h            |   28 ++++++++++-
 .../robot-memory/test-plugin/robot_memory_test.cpp |   44 +++++++++++++++++
 .../robot-memory/test-plugin/robot_memory_test.h   |   18 +++++++
 .../test-plugin/robot_memory_test_thread.cpp       |    5 +-
 8 files changed, 156 insertions(+), 66 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/Makefile b/src/plugins/robot-memory/Makefile
index 84453a7..d25debd 100644
--- a/src/plugins/robot-memory/Makefile
+++ b/src/plugins/robot-memory/Makefile
@@ -18,10 +18,14 @@ BASEDIR = ../../..
 include $(BASEDIR)/etc/buildsys/config.mk
 include $(BUILDCONFDIR)/tf/tf.mk
 include $(BASEDIR)/src/plugins/mongodb/mongodb.mk
+include $(BASEDIR)/etc/buildsys/boost.mk
 
 PRESUBDIRS = interfaces aspect
 SUBDIRS = test-plugin
 
+REQ_BOOST_LIBS = bind function
+HAVE_BOOST_LIBS = $(call boost-have-libs,$(REQ_BOOST_LIBS))
+
 LIBS_robot_memory = fawkescore fawkesaspects fawkesblackboard fawkesinterface \
 		fawkesutils fawkeslogging fawkesmongodbaspect fvutils \
 		fawkestf RobotMemoryInterface fawkesrobotmemory
@@ -29,9 +33,9 @@ OBJS_robot_memory = $(patsubst %.cpp,%.o,$(patsubst qa/%,,$(subst $(SRCDIR)/,,$(
 
 OBJS_all    = $(OBJS_robot_memory)
 
-ifeq ($(HAVE_MONGODB)$(HAVE_TF),11)
-  CFLAGS += $(CFLAGS_TF) $(CFLAGS_MONGODB)
-  LDFLAGS += $(LDFLAGS_TF) $(LDFLAGS_MONGODB)
+ifeq ($(HAVE_MONGODB)$(HAVE_TF)$(HAVE_BOOST_LIBS),111)
+  CFLAGS += $(CFLAGS_TF) $(CFLAGS_MONGODB) $(call boost-libs-cflags,$(REQ_BOOST_LIBS))
+  LDFLAGS += $(LDFLAGS_TF) $(LDFLAGS_MONGODB) $(call boost-libs-ldflags,$(REQ_BOOST_LIBS))
   PLUGINS_all = $(PLUGINDIR)/robot-memory.so
 else
   ifneq ($(HAVE_MONGODB),1)
@@ -40,6 +44,9 @@ else
   ifneq ($(HAVE_TF),1)
     WARN_TARGETS += warning_tf
   endif
+  ifneq ($(HAVE_BOOST_LIBS),1)
+    WARN_TARGETS_BOOST = $(foreach l,$(REQ_BOOST_LIBS),$(if $(call boost-have-lib,$l),, warning_boost_$l))
+  endif
 endif
 
 ifeq ($(OBJSSUBMAKE),1)
@@ -49,7 +56,9 @@ all: $(WARN_TARGETS)
 warning_mongodb:
 	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting RobotMemory Plugin$(TNORMAL) (mongodb[-devel] not installed)"
 warning_tf:
-	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting PCL utility library$(TNORMAL) (tf framework not available)"
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Omitting RobotMemory Plugin$(TNORMAL) (tf framework not available)"
+$(WARN_TARGETS_BOOST): warning_boost_%:
+	$(SILENT)echo -e "$(INDENT_PRINT)--> $(TRED)Cannot build RobotMemory Plugin$(TNORMAL) (Boost library $* not found)"endif
 endif
 
 include $(BUILDSYSDIR)/base.mk
diff --git a/src/plugins/robot-memory/event_trigger_manager.cpp b/src/plugins/robot-memory/event_trigger_manager.cpp
index 21d99f9..b2af921 100644
--- a/src/plugins/robot-memory/event_trigger_manager.cpp
+++ b/src/plugins/robot-memory/event_trigger_manager.cpp
@@ -19,6 +19,7 @@
  *  Read the full text in the LICENSE.GPL file in the doc directory.
  */
 
+
 #include "event_trigger_manager.h"
 #include <plugin/loader.h>
 #include <boost/bind.hpp>
@@ -26,11 +27,6 @@
 using namespace fawkes;
 using namespace mongo;
 
-void EventTriggerManager::callback_test(mongo::BSONObj update)
-{
-  logger_->log_info(name.c_str(), "callback: %s", update.toString().c_str());
-}
-
 EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
 {
   logger_ = logger;
@@ -47,16 +43,12 @@ EventTriggerManager::EventTriggerManager(Logger* logger, Configuration* config)
   }
   repl_set = config_->get_string("plugins/robot-memory/setup/replicated/replica-set-name");
   con_replica_ = new mongo::DBClientConnection();
-  //TODO: connect to repl set instead of instance
   if(!con_replica_->connect("localhost:" + std::to_string(config_->get_uint("plugins/robot-memory/setup/replicated/port")), errmsg))
   {
     std::string err_msg = "Could not connect to replica set: "+ errmsg;
     throw PluginLoadException("robot-memory", err_msg.c_str());
   }
 
-  //test setup
-  register_trigger(mongo::fromjson("{test: 0}"), "syncedrobmem.test", &EventTriggerManager::callback_test, this);
-
   logger_->log_info(name.c_str(), "Initialized");
 }
 
@@ -75,6 +67,7 @@ void EventTriggerManager::check_events()
     while(trigger->oplog_cursor->more())
     {
       BSONObj change = trigger->oplog_cursor->next();
+      //logger_->log_info(name.c_str(), "Triggering: %s", change.toString().c_str());
       //actually call the callback function
       trigger->callback(change);
     }
@@ -86,40 +79,14 @@ void EventTriggerManager::check_events()
   }
 }
 
-template<typename T>
-void EventTriggerManager::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
+/**
+ * Remove a previously registered trigger
+ * @param trigger Pointer to the trigger to remove
+ */
+void EventTriggerManager::remove_trigger(EventTrigger* trigger)
 {
-  logger_->log_info(name.c_str(), "Registering Trigger");
-
-  //construct query for oplog
-  BSONObjBuilder query_builder;
-  query_builder.append("ns", collection);
-  // added/updated object is a subdocument in the oplog document
-  for(BSONObjIterator it = query.getFilter().begin(); it.more();)
-  {
-    BSONElement elem = it.next();
-    query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
-  }
-  mongo::Query oplog_query = query_builder.obj();
-  oplog_query.readPref(ReadPreference_Nearest, BSONArray());
-
-  //check if collection is local or replicated
-  mongo::DBClientConnection* con;
-  std::string oplog;
-  if(collection.find(repl_set) == 0)
-  {
-    con = con_replica_;
-    oplog = "local.oplog.rs";
-  }
-  else
-  {
-    con = con_local_;
-    oplog = "local.oplog";
-  }
-
-  EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
-  trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
-  triggers.push_back(trigger);
+  triggers.remove(trigger);
+  delete trigger;
 }
 
 QResCursor EventTriggerManager::create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query)
@@ -132,3 +99,4 @@ QResCursor EventTriggerManager::create_oplog_cursor(mongo::DBClientConnection* c
   }
   return res;
 }
+
diff --git a/src/plugins/robot-memory/event_trigger_manager.h b/src/plugins/robot-memory/event_trigger_manager.h
index ab45725..f25253d 100644
--- a/src/plugins/robot-memory/event_trigger_manager.h
+++ b/src/plugins/robot-memory/event_trigger_manager.h
@@ -27,6 +27,7 @@
 #include <aspect/configurable.h>
 #include <list>
 #include "event_trigger.h"
+#include <boost/bind.hpp>
 
 
 ///typedef for shorter type description
@@ -45,12 +46,46 @@ class EventTriggerManager
     virtual ~EventTriggerManager();
 
     template<typename T>
-    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *obj)
+    {
+      //construct query for oplog
+      mongo::BSONObjBuilder query_builder;
+      query_builder.append("ns", collection);
+      // added/updated object is a subdocument in the oplog document
+      for(mongo::BSONObjIterator it = query.getFilter().begin(); it.more();)
+      {
+        mongo::BSONElement elem = it.next();
+        query_builder.appendAs(elem, std::string("o.") + elem.fieldName());
+      }
+      mongo::Query oplog_query = query_builder.obj();
+      oplog_query.readPref(mongo::ReadPreference_Nearest, mongo::BSONArray());
+
+      //check if collection is local or replicated
+      mongo::DBClientConnection* con;
+      std::string oplog;
+      if(collection.find(repl_set) == 0)
+      {
+        con = con_replica_;
+        oplog = "local.oplog.rs";
+      }
+      else
+      {
+        con = con_local_;
+        oplog = "local.oplog.rs";
+      }
+
+      EventTrigger *trigger = new EventTrigger(oplog_query, collection, boost::bind(callback, obj, _1));
+      trigger->oplog_cursor = create_oplog_cursor(con, oplog, oplog_query);
+      triggers.push_back(trigger);
+      return trigger;
+    }
+
+
+    void remove_trigger(EventTrigger* trigger);
 
   private:
     void check_events();
     QResCursor create_oplog_cursor(mongo::DBClientConnection* con, std::string oplog, mongo::Query query);
-    void callback_test(mongo::BSONObj update);
 
     std::string name = "RobotMemory EventTriggerManager";
     fawkes::Logger* logger_;
@@ -65,4 +100,4 @@ class EventTriggerManager
     std::list<EventTrigger*> triggers;
 };
 
-#endif /* FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_ */
+#endif //FAWKES_SRC_PLUGINS_ROBOT_MEMORY_EVENT_TRIGGER_MANAGER_H_
diff --git a/src/plugins/robot-memory/robot_memory.cpp b/src/plugins/robot-memory/robot_memory.cpp
index 720bacc..e48d09a 100644
--- a/src/plugins/robot-memory/robot_memory.cpp
+++ b/src/plugins/robot-memory/robot_memory.cpp
@@ -419,19 +419,10 @@ RobotMemory::check_collection_name(std::string &collection)
 }
 
 /**
- * Register a trigger that notifies you when the event specified in the query happens
+ * Remove a previously registered trigger
+ * @param trigger Pointer to the trigger to remove
  */
-template<typename T>
-void RobotMemory::register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+void RobotMemory::remove_trigger(EventTrigger* trigger)
 {
-  trigger_manager_->register_trigger(query, collection, callback, _obj);
-}
-
-/**
- * Register a trigger that notifies you when the event specified in the query happens
- */
-template<typename T>
-void RobotMemory::register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
-{
-  register_trigger(fromjson(query_str), collection, callback);
+  trigger_manager_->remove_trigger(trigger);
 }
diff --git a/src/plugins/robot-memory/robot_memory.h b/src/plugins/robot-memory/robot_memory.h
index 4eabaec..f3046b5 100644
--- a/src/plugins/robot-memory/robot_memory.h
+++ b/src/plugins/robot-memory/robot_memory.h
@@ -64,10 +64,34 @@ class RobotMemory
     int restore_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
     int dump_collection(std::string collection, std::string directory = "@CONFDIR@/robot-memory");
 
+    /**
+     * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
+     * @param query Query the updated document has to match
+     * @param collection db.collection to use
+     * @param callback Callback function (e.g. &Class::callback)
+     * @param _obj Pointer to class the callback is a function of (usaually this)
+     * @return Trigger object pointer, save it to remove the trigger later
+     */
     template<typename T>
-    void register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    EventTrigger* register_trigger(mongo::Query query, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+    {
+      return trigger_manager_->register_trigger(query, collection, callback, _obj);
+    }
+    /**
+     * Register a trigger to be notified when the robot memory is updated and the updated document matches the query
+     * @param query_str Query as JSON string
+     * @param collection db.collection to use
+     * @param callback Callback function (e.g. &Class::callback)
+     * @param _obj Pointer to class the callback is a function of (usaually this)
+     * @return Trigger object pointer, save it to remove the trigger later
+     */
     template<typename T>
-    void register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj);
+    EventTrigger* register_trigger(std::string query_str, std::string collection, void(T::*callback)(mongo::BSONObj), T *_obj)
+    {
+      return register_trigger(mongo::fromjson(query_str), collection, callback);
+    }
+
+    void remove_trigger(EventTrigger* trigger);
 
   private:
     mongo::DBClientBase* mongodb_client_;
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index a24e29e..2474a68 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -156,6 +156,50 @@ TEST_F(RobotMemoryTest, DumpAndResore)
 
 }
 
+TEST_F(RobotMemoryTest, EventTriggerLocal)
+{
+  RobotMemoryCallback* rmc = new RobotMemoryCallback();
+  rmc->callback_counter = 0;
+  EventTrigger* trigger1 = robot_memory->register_trigger(fromjson("{test:1}"),
+      "robmem.test", &RobotMemoryCallback::callback_test, rmc);
+  EventTrigger* trigger2 = robot_memory->register_trigger(fromjson("{test:2}"),
+      "robmem.test", &RobotMemoryCallback::callback_test, rmc);
+
+  robot_memory->insert(fromjson("{test:0, updateid:55}"), "robmem.test");
+  robot_memory->insert(fromjson("{test:1, updateid:42}"), "robmem.test");
+  robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "robmem.test");
+
+  //wait for robot memory to call triggers
+  usleep(500000);
+
+  ASSERT_EQ(2, rmc->callback_counter);
+
+  robot_memory->remove_trigger(trigger1);
+  robot_memory->remove_trigger(trigger2);
+}
+
+TEST_F(RobotMemoryTest, EventTriggerReplica)
+{
+  RobotMemoryCallback* rmc = new RobotMemoryCallback();
+  rmc->callback_counter = 0;
+  EventTrigger* trigger1 = robot_memory->register_trigger(fromjson("{test:1}"),
+      "syncedrobmem.test", &RobotMemoryCallback::callback_test, rmc);
+  EventTrigger* trigger2 = robot_memory->register_trigger(fromjson("{test:2}"),
+      "syncedrobmem.test", &RobotMemoryCallback::callback_test, rmc);
+
+  robot_memory->insert(fromjson("{test:0, updateid:55}"), "syncedrobmem.test");
+  robot_memory->insert(fromjson("{test:1, updateid:42}"), "syncedrobmem.test");
+  robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "syncedrobmem.test");
+
+  //wait for robot memory to call triggers
+  usleep(500000);
+
+  ASSERT_EQ(2, rmc->callback_counter);
+
+  robot_memory->remove_trigger(trigger1);
+  robot_memory->remove_trigger(trigger2);
+}
+
 ::testing::AssertionResult RobotMemoryTest::contains_pairs(BSONObj obj, BSONObj exp)
 {
   for(BSONObjIterator it = exp.begin(); it.more();)
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.h b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
index a9cdb07..665b1c1 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.h
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.h
@@ -55,5 +55,23 @@ class RobotMemoryTest : public ::testing::Test
   ::testing::AssertionResult contains_pairs(mongo::BSONObj obj, mongo::BSONObj exp);
 };
 
+/**
+ * Class to register callbacks independent of how many tests are using them at the moment
+ */
+class RobotMemoryCallback
+{
+  public:
+    RobotMemoryCallback()
+  {
+      callback_counter = 0;
+  };
+   ~RobotMemoryCallback(){};
+   int callback_counter;
+   void callback_test(mongo::BSONObj update)
+   {
+     callback_counter++;
+   }
+};
+
 
 #endif
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
index 5bedac1..640917b 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test_thread.cpp
@@ -47,13 +47,14 @@ RobotMemoryTestThread::init()
   test_env_ = new RobotMemoryTestEnvironment(robot_memory);
   ::testing::AddGlobalTestEnvironment((testing::Environment*) test_env_);
 
-  logger->log_warn(name(), "Starting tests");
-  test_result_ = RUN_ALL_TESTS();
 }
 
 void
 RobotMemoryTestThread::loop()
 {
+  logger->log_warn(name(), "Starting tests");
+  test_result_ = RUN_ALL_TESTS();
+  usleep(100000);
   logger->log_warn(name(), "Finished tests with, quitting as intended...");
   //stop fawkes to finish the testing run
   fawkes::runtime::quit();

- *commit* 53d178b07bfcf2d3ebbfe7032c12cddb92c05439 - - - - - - - - - -
Author:  Frederik Zwilling <zwilling at kbsg.rwth-aachen.de>
Date:    Thu Oct 6 19:01:30 2016 +0200
Subject: robot-memory: fixed DumpRestore test

 .../robot-memory/test-plugin/robot_memory_test.cpp |   21 ++++++++++++++-----
 1 files changed, 15 insertions(+), 6 deletions(-)

_Diff for modified files_:
diff --git a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
index 2474a68..9714625 100644
--- a/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
+++ b/src/plugins/robot-memory/test-plugin/robot_memory_test.cpp
@@ -20,6 +20,8 @@
  */
 
 #include "robot_memory_test.h"
+#include <list>
+#include <algorithm>
 
 //init static variable
 RobotMemory* RobotMemoryTestEnvironment::robot_memory = NULL;
@@ -146,14 +148,21 @@ TEST_F(RobotMemoryTest, DumpAndResore)
   ASSERT_TRUE(robot_memory->drop_collection("robmem.test"));
   ASSERT_TRUE(robot_memory->restore_collection("robmem.test"));
   QResCursor qres = robot_memory->query("{'testkey':'value'}");
+  std::list<int> values = {3, 2, 1};
   ASSERT_TRUE(qres->more());
-  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:1}")));
+  int got = qres->next().getField("v").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
   ASSERT_TRUE(qres->more());
-  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:2}")));
+  got = qres->next().getField("v").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
   ASSERT_TRUE(qres->more());
-  ASSERT_TRUE(contains_pairs(qres->next(), fromjson("{'testkey':'value',v:3}")));
+  got = qres->next().getField("v").Int();
+  ASSERT_TRUE(std::find(values.begin(), values.end(), got) != values.end());
+  values.remove(got);
+  ASSERT_EQ(0, values.size());
   ASSERT_FALSE(qres->more());
-
 }
 
 TEST_F(RobotMemoryTest, EventTriggerLocal)
@@ -170,7 +179,7 @@ TEST_F(RobotMemoryTest, EventTriggerLocal)
   robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "robmem.test");
 
   //wait for robot memory to call triggers
-  usleep(500000);
+  usleep(100000);
 
   ASSERT_EQ(2, rmc->callback_counter);
 
@@ -192,7 +201,7 @@ TEST_F(RobotMemoryTest, EventTriggerReplica)
   robot_memory->update(fromjson("{updateid:42}"), fromjson("{test:2, updateid:42}"), "syncedrobmem.test");
 
   //wait for robot memory to call triggers
-  usleep(500000);
+  usleep(100000);
 
   ASSERT_EQ(2, rmc->callback_counter);
 




-- 
Fawkes Robotics Framework                 http://www.fawkesrobotics.org


More information about the fawkes-commits mailing list