ConnectionManager.cpp
Go to the documentation of this file.
1 #include "ConnectionManager.h"
2 
3 #include <iostream>
4 #include <fstream>
5 #include <algorithm>
6 
8 {
9  std::mutex ConnectionManager::initializationMutex;
10  bool ConnectionManager::initialized = false;
11  std::map<std::string, std::unique_ptr<mongocxx::pool>> ConnectionManager::Connections = {};
12 
14  {
15  std::string armarx_home = std::string(getenv("HOME")) + "/.armarx";
16  if (getenv("ARMARX_DEFAULTS_DIR"))
17  {
18  armarx_home = getenv("ARMARX_DEFAULTS_DIR");
19  }
20  std::ifstream cFile (armarx_home + "/default.cfg");
21  if (cFile.is_open())
22  {
23  std::string line;
24  while(getline(cFile, line))
25  {
26  line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
27  if(line[0] == '#' || line.empty())
28  {
29  continue;
30  }
31  auto delimiterPos = line.find("=");
32  const auto name = line.substr(0, delimiterPos);
33  const auto value = line.substr(delimiterPos + 1);
34  if (name == "ArmarX.MongoHost")
35  {
36  host = value;
37  }
38  if (name == "ArmarX.MongoPort")
39  {
40  port = (unsigned int) std::stoi(value);
41  }
42  if (name == "ArmarX.MongoUser")
43  {
44  user = value;
45  }
46  if (name == "ArmarX.MongoPassword")
47  {
48  password = value;
49  }
50  }
51  }
52  }
53 
55  {
56  // we always need a host and a port
57  return !host.empty() and port != 0;
58  }
59 
61  {
62  std::stringstream ss;
63  ss << "mongodb://";
64 
65  if (!user.empty())
66  {
67  ss << user;
68  if (!password.empty())
69  {
70  ss << ":" << password;
71  }
72  ss << "@";
73  }
74  ss << host;
75  return ss.str();
76  }
77 
79  {
80  // TODO: What happens if a connection exists and you would like to open another one with a different user (e.g. that sees different things)?
81  return "mongodb://" + host + ":" + std::to_string(port);
82  }
83 
85  {
86  return baseUri() + ":" + std::to_string(port) + "/?minPoolSize=" + std::to_string(minPoolSize) + "&maxPoolSize=" + std::to_string(maxPoolSize);
87  }
88 
90  {
91  return uri() + "&database=" + database;
92  }
93 
94  void ConnectionManager::initialize_if()
95  {
96  std::lock_guard l(initializationMutex); // all others have to wait until the initialization is complete
97  if (!initialized)
98  {
99  initialized = true;
100  mongocxx::instance instance{}; // This should be done only once.
101  }
102  }
103 
104  mongocxx::pool& ConnectionManager::Connect(const MongoDBSettings& settings)
105  {
106  initialize_if();
107 
108  const auto uri_str = settings.uri();
109  auto it = Connections.find(uri_str);
110  if (it == Connections.end())
111  {
112  mongocxx::uri uri(uri_str);
113  auto pool = std::make_unique<mongocxx::pool>(uri);
114  auto con = Connections.emplace(settings.key(), std::move(pool));
115  return *con.first->second;
116  }
117  else
118  {
119  // A connection already exists. We do not need to open another one.
120  return *it->second;
121  }
122  }
123 
124  bool ConnectionManager::ConnectionIsValid(const MongoDBSettings& settings, bool forceNewConnection)
125  {
126  initialize_if();
127 
128  try
129  {
130  if (!forceNewConnection)
131  {
132  auto it = Connections.find(settings.key());
133  if (it != Connections.end())
134  {
135  auto client = it->second->acquire();
136  auto admin = client->database("admin");
137  auto result = admin.run_command(bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("isMaster", 1)));
138  return true;
139  }
140  }
141 
142  mongocxx::uri uri(settings.uri());
143  auto client = mongocxx::client(uri);
144  auto admin = client["admin"];
145  auto result = admin.run_command(bsoncxx::builder::basic::make_document(bsoncxx::builder::basic::kvp("isMaster", 1)));
146  return true;
147  }
148  catch (const std::exception& xcp)
149  {
150  return false;
151  }
152  }
153 
155  {
156  initialize_if();
157 
158  auto it = Connections.find(settings.key());
159  return it != Connections.end();
160  }
161 }
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::key
std::string key() const
Definition: ConnectionManager.cpp:78
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::isSet
bool isSet() const
Definition: ConnectionManager.cpp:54
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings
Definition: ConnectionManager.h:33
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::port
unsigned int port
Definition: ConnectionManager.h:36
armarx::armem::server::ltm::mongodb::ConnectionManager::ConnectionExists
static bool ConnectionExists(const MongoDBSettings &settings)
Definition: ConnectionManager.cpp:154
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::uri
std::string uri() const
Definition: ConnectionManager.cpp:84
armarx::armem::server::ltm::mongodb::ConnectionManager::Connect
static mongocxx::pool & Connect(const MongoDBSettings &settings)
Definition: ConnectionManager.cpp:104
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::user
std::string user
Definition: ConnectionManager.h:37
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::toString
std::string toString() const
Definition: ConnectionManager.cpp:89
armarx::armem::server::ltm::mongodb
Definition: ConnectionManager.cpp:7
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::baseUri
std::string baseUri() const
Definition: ConnectionManager.cpp:60
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::MongoDBSettings
MongoDBSettings()
Definition: ConnectionManager.cpp:13
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::host
std::string host
Definition: ConnectionManager.h:35
armarx::armem::server::ltm::mongodb::ConnectionManager::ConnectionIsValid
static bool ConnectionIsValid(const MongoDBSettings &settings, bool forceNewConnection=false)
Definition: ConnectionManager.cpp:124
ConnectionManager.h
armarx::armem::server::ltm::mongodb::ConnectionManager::MongoDBSettings::password
std::string password
Definition: ConnectionManager.h:38