From 147d495b670a60553441b92d0361d06223f5145d Mon Sep 17 00:00:00 2001
From: "fabian.peller-konrad@kit.edu" <fabian.peller-konrad@kit.edu>
Date: Tue, 29 Jun 2021 14:49:59 +0200
Subject: [PATCH] check if mongodb is running. If not return empty results

---
 .../armem/core/longtermmemory/Memory.cpp      | 32 +++++++++++++
 .../armem/core/longtermmemory/Memory.h        |  2 +
 .../mongodb/MongoDBConnectionManager.cpp      | 48 ++++++++++++++++++-
 .../mongodb/MongoDBConnectionManager.h        |  8 +++-
 4 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
index 4a96e410d..248594801 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.cpp
@@ -10,20 +10,47 @@
 namespace armarx::armem::ltm
 {
 
+    bool Memory::checkConnection() const
+    {
+        // Check connection:
+        if (!MongoDBConnectionManager::ConnectionIsValid(dbsettings))
+        {
+            ARMARX_WARNING << deactivateSpam("ConnectionIsNotValid") << "The connection to mongocxx for memory '" << name() << "' is not valid. Settings are: " << dbsettings.toString();
+            return false;
+        }
+        ARMARX_INFO << "Checking connection";
+        return true;
+    }
+
     wm::Memory Memory::convert() const
     {
+        if (!checkConnection())
+        {
+            wm::Memory m(id());
+            return m;
+        }
+
         ARMARX_INFO << "Converting with connection to: " << dbsettings.toString();
 
+        TIMING_START(LTM_Convert);
+
         wm::Memory m(id());
         for (const auto& [_, s] : _container)
         {
             m.addCoreSegment(s.convert());
         }
+
+        TIMING_END(LTM_Convert);
         return m;
     }
 
     void Memory::reload()
     {
+        if (!checkConnection())
+        {
+            return;
+        }
+
         ARMARX_INFO << "(Re)Establishing connection to: " << dbsettings.toString();
         _container.clear();
 
@@ -60,6 +87,11 @@ namespace armarx::armem::ltm
 
     void Memory::append(const wm::Memory& m)
     {
+        if (!checkConnection())
+        {
+            return;
+        }
+
         ARMARX_INFO << "Merge memory with name '" << m.name() << "' into the LTM with name '" << name() << "'";
 
         TIMING_START(LTM_Append);
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
index 0c14d4810..86c00cc61 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/Memory.h
@@ -65,6 +65,8 @@ namespace armarx::armem::ltm
             other.dbsettings = dbsettings;
         }
 
+    private:
+        bool checkConnection() const;
 
     public:
         MongoDBConnectionManager::MongoDBSettings dbsettings;
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.cpp b/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.cpp
index d35c7640c..6ad448369 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.cpp
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.cpp
@@ -5,13 +5,19 @@ namespace armarx::armem::ltm
     bool MongoDBConnectionManager::initialized = false;
     std::map<std::string, mongocxx::client> MongoDBConnectionManager::Connections = {};
 
-    mongocxx::client& MongoDBConnectionManager::EstablishConnection(const MongoDBSettings& settings)
+
+    void MongoDBConnectionManager::initialize_if()
     {
         if (!initialized)
         {
             initialized = true;
             mongocxx::instance instance{}; // This should be done only once.
         }
+    }
+
+    mongocxx::client& MongoDBConnectionManager::EstablishConnection(const MongoDBSettings& settings)
+    {
+        initialize_if();
 
         const auto uri_str = settings.uri();
         const auto& it = Connections.find(uri_str);
@@ -27,4 +33,44 @@ namespace armarx::armem::ltm
             return it->second;
         }
     }
+
+    bool MongoDBConnectionManager::ConnectionIsValid(const MongoDBSettings& settings, bool force)
+    {
+        initialize_if();
+
+        try
+        {
+            if (!force)
+            {
+                const auto uri_str = settings.uri();
+                const auto& it = Connections.find(uri_str);
+                if (it != Connections.end())
+                {
+                    auto admin = it->second["admin"];
+                    auto result = admin.run_command(bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("isMaster", 1)));
+                    return true;
+                }
+            }
+
+            const auto uri_str = settings.uri();
+            mongocxx::uri uri(uri_str);
+            auto client = mongocxx::client(uri);
+            auto admin = client["admin"];
+            auto result = admin.run_command(bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("isMaster", 1)));
+            return true;
+        }
+        catch (const std::exception& xcp)
+        {
+            return false;
+        }
+    }
+
+    bool MongoDBConnectionManager::ConnectionExists(const MongoDBSettings& settings)
+    {
+        initialize_if();
+
+        const auto uri_str = settings.uri();
+        const auto& it = Connections.find(uri_str);
+        return it != Connections.end();
+    }
 }
diff --git a/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h b/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h
index 0c04151cc..0cd3cb5ba 100644
--- a/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h
+++ b/source/RobotAPI/libraries/armem/core/longtermmemory/mongodb/MongoDBConnectionManager.h
@@ -4,6 +4,7 @@
 #include <vector>
 #include <map>
 #include <memory>
+#include <iostream>
 
 #include <bsoncxx/json.hpp>
 #include <mongocxx/client.hpp>
@@ -35,7 +36,7 @@ namespace armarx::armem::ltm
         struct MongoDBSettings
         {
             std::string host = "localhost";
-            unsigned int port = 27017;
+            unsigned int port = 25270;
             std::string user = "";
             std::string password = "";
             std::string database = "Test";
@@ -59,6 +60,11 @@ namespace armarx::armem::ltm
         };
 
         static mongocxx::client& EstablishConnection(const MongoDBSettings& settings);
+        static bool ConnectionIsValid(const MongoDBSettings& settings, bool force = false);
+        static bool ConnectionExists(const MongoDBSettings& settings);
+
+    private:
+        static void initialize_if();
 
 
     private:
-- 
GitLab