ConnectionManager.cpp
Go to the documentation of this file.
1#include "ConnectionManager.h"
2
3#include <algorithm>
4#include <fstream>
5#include <iostream>
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
54 bool
56 {
57 // we always need a host and a port
58 return !host.empty() and port != 0;
59 }
60
61 std::string
63 {
64 std::stringstream ss;
65 ss << "mongodb://";
66
67 if (!user.empty())
68 {
69 ss << user;
70 if (!password.empty())
71 {
72 ss << ":" << password;
73 }
74 ss << "@";
75 }
76 ss << host;
77 return ss.str();
78 }
79
80 std::string
82 {
83 // 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)?
84 return "mongodb://" + host + ":" + std::to_string(port);
85 }
86
87 std::string
89 {
90 return baseUri() + ":" + std::to_string(port) +
91 "/?minPoolSize=" + std::to_string(minPoolSize) +
92 "&maxPoolSize=" + std::to_string(maxPoolSize);
93 }
94
95 std::string
97 {
98 return uri() + "&database=" + database;
99 }
100
101 void
102 ConnectionManager::initialize_if()
103 {
104 std::lock_guard l(
105 initializationMutex); // all others have to wait until the initialization is complete
106 if (!initialized)
107 {
108 initialized = true;
109 mongocxx::instance instance{}; // This should be done only once.
110 }
111 }
112
113 mongocxx::pool&
115 {
116 initialize_if();
117
118 const auto uri_str = settings.uri();
119 auto it = Connections.find(uri_str);
120 if (it == Connections.end())
121 {
122 mongocxx::uri uri(uri_str);
123 auto pool = std::make_unique<mongocxx::pool>(uri);
124 auto con = Connections.emplace(settings.key(), std::move(pool));
125 return *con.first->second;
126 }
127 else
128 {
129 // A connection already exists. We do not need to open another one.
130 return *it->second;
131 }
132 }
133
134 bool
135 ConnectionManager::ConnectionIsValid(const MongoDBSettings& settings, bool forceNewConnection)
136 {
137 initialize_if();
138
139 try
140 {
141 if (!forceNewConnection)
142 {
143 auto it = Connections.find(settings.key());
144 if (it != Connections.end())
145 {
146 auto client = it->second->acquire();
147 auto admin = client->database("admin");
148 auto result = admin.run_command(bsoncxx::builder::basic::make_document(
149 bsoncxx::builder::basic::kvp("isMaster", 1)));
150 return true;
151 }
152 }
153
154 mongocxx::uri uri(settings.uri());
155 auto client = mongocxx::client(uri);
156 auto admin = client["admin"];
157 auto result = admin.run_command(bsoncxx::builder::basic::make_document(
158 bsoncxx::builder::basic::kvp("isMaster", 1)));
159 return true;
160 }
161 catch (const std::exception& xcp)
162 {
163 return false;
164 }
165 }
166
167 bool
169 {
170 initialize_if();
171
172 auto it = Connections.find(settings.key());
173 return it != Connections.end();
174 }
175} // namespace armarx::armem::server::ltm::mongodb
static mongocxx::pool & Connect(const MongoDBSettings &settings)
static bool ConnectionIsValid(const MongoDBSettings &settings, bool forceNewConnection=false)
static bool ConnectionExists(const MongoDBSettings &settings)
This file is part of ArmarX.