CommonStorage.h
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package MemoryX::CommonStorage
17* @author Alexey Kozlov ( kozlov at kit dot edu)
18* @date 2012
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23#pragma once
24
25#include <memory>
26#include <mutex>
27
31
32#include "GridFileWrapper.h"
33#include <MemoryX/interface/components/CommonStorageInterface.h>
34
35namespace mongo
36{
37 class GridFS;
38 class GridFile;
39 class BSONObj;
40 class DBClientConnection;
41 class DBClientBase;
42 class Query;
43} // namespace mongo
44
45namespace memoryx
46{
47
48 class GridFileWrapper;
50 using GridFSPtr = std::shared_ptr<mongo::GridFS>;
51
53 {
54 public:
56 {
58 "MongoHost", "localhost", "MongoDB hostname and optionally port number")
59 .setCaseInsensitive(true);
60
62 "MongoAuth", false, "Whether authentication should be used for MongoDB");
63
64 defineRequiredProperty<std::string>("MongoUser", "MongoDB user name");
65
66 defineRequiredProperty<std::string>("MongoPassword", "MongoDB password");
67 }
68 };
69
70 /*!
71 * \brief The CommonStorage class provides an interface to MongoDB.
72 *
73 * See \ref commonstorage "memoryx::CommonStorage" - versatile storage backed up by MongoDB
74 */
76 virtual public CommonStorageInterface,
77 virtual public armarx::Component
78 {
79 public:
80 // inherited from Component
81 std::string getDefaultName() const override;
82 static std::string GetDefaultName();
83 void onInitComponent() override;
84 void onConnectComponent() override;
85 void onExitComponent() override;
86
87 /**
88 * @see PropertyUser::createPropertyDefinitions()
89 */
91
92 // inherited from CommonStorageInterface
93 std::string getMongoHostAndPort(const ::Ice::Current& c = Ice::emptyCurrent) override;
94 NameList getDBNames(const ::Ice::Current& = Ice::emptyCurrent) override;
95 NameList getCollectionNames(const ::std::string& dbName,
96 const ::Ice::Current& = Ice::emptyCurrent) override;
97 bool isConnected(const ::Ice::Current& c = Ice::emptyCurrent) override;
98
99 bool reconnect(const ::std::string& hostAndPort,
100 const ::std::string& userName,
101 const ::std::string& password,
102 const ::Ice::Current& = Ice::emptyCurrent) override;
103 bool authDB(const ::std::string& dbName,
104 const ::std::string& userName,
105 const ::std::string& password,
106 const ::Ice::Current& = Ice::emptyCurrent) override;
107
108 DatabaseInterfacePrx requestDatabase(const ::std::string& dbName,
109 const ::Ice::Current& = Ice::emptyCurrent) override;
110 void releaseDatabase(const DatabaseInterfacePrx& db,
111 const ::Ice::Current& = Ice::emptyCurrent) override;
112
113 CollectionInterfacePrx
114 requestCollection(const std::string& collectionNS,
115 const ::Ice::Current& c = Ice::emptyCurrent) override;
116 void releaseCollection(const CollectionInterfacePrx& coll,
117 const ::Ice::Current& c = Ice::emptyCurrent) override;
118 void dropCollection(const std::string& collectionNS,
119 const ::Ice::Current& c = Ice::emptyCurrent) override;
120
121 std::string storeFile(const ::std::string& dbName,
122 const ::std::string& fileName,
123 const ::std::string& gridFSName = "",
124 const ::Ice::Current& c = Ice::emptyCurrent) override;
125 std::string storeTextFile(const ::std::string& dbName,
126 const ::std::string& bufferToStore,
127 const ::std::string& gridFSName = "",
128 const ::Ice::Current& c = Ice::emptyCurrent) override;
129 std::string storeBinaryFile(const ::std::string& dbName,
130 const memoryx::Blob& bufferToStore,
131 const ::std::string& gridFSName = "",
132 const ::Ice::Current& c = Ice::emptyCurrent) override;
133
134 bool getTextFileById(const ::std::string& dbName,
135 const ::std::string& fileId,
136 ::std::string& buffer,
137 const ::Ice::Current& c = Ice::emptyCurrent) override;
138 bool getBinaryFileById(const ::std::string& dbName,
139 const ::std::string& fileId,
140 memoryx::Blob& buffer,
141 const ::Ice::Current& c = Ice::emptyCurrent) override;
142 bool getTextFileByName(const ::std::string& dbName,
143 const ::std::string& gridFSName,
144 ::std::string& buffer,
145 const ::Ice::Current& c = Ice::emptyCurrent) override;
146 bool getBinaryFileByName(const ::std::string& dbName,
147 const ::std::string& gridFSName,
148 memoryx::Blob& buffer,
149 const ::Ice::Current& c = Ice::emptyCurrent) override;
150
151 GridFileInterfacePrx getFileProxyById(const ::std::string& dbName,
152 const ::std::string& fileId,
153 const ::Ice::Current& c = Ice::emptyCurrent) override;
154 GridFileInterfacePrx
155 getFileProxyByName(const ::std::string& dbName,
156 const ::std::string& gridFSName,
157 const ::Ice::Current& c = Ice::emptyCurrent) override;
158 void releaseFileProxy(const GridFileInterfacePrx& fileProxy,
159 const ::Ice::Current& c = Ice::emptyCurrent) override;
160
161 bool removeFileById(const ::std::string& dbName,
162 const ::std::string& fileId,
163 const ::Ice::Current& c = Ice::emptyCurrent) override;
164 bool removeFileByName(const ::std::string& dbName,
165 const ::std::string& gridFSName,
166 const ::Ice::Current& c = Ice::emptyCurrent) override;
167
168 // methods called by Collection
169 Ice::Int count(const std::string& ns);
170
171 DBStorableData findByMongoId(const std::string& ns, const std::string& id);
172 DBStorableDataList findByFieldValue(const std::string& ns,
173 const std::string& fieldName,
174 const ::std::string& fieldValue);
175 DBStorableDataList findByFieldValueList(const std::string& ns,
176 const std::string& fieldName,
177 const NameList& fieldValueList);
178 DBStorableData findOneByFieldValue(const std::string& ns,
179 const std::string& fieldName,
180 const ::std::string& fieldValue);
181 DBStorableDataList
182 findByQuery(const std::string& ns, const std::string& query, const std::string& where = "");
183 DBStorableData findOneByQuery(const std::string& ns, const std::string& query);
184 DBStorableDataList findAll(const std::string& ns);
185 DBStorableData findAllUniqueByFieldName(const std::string& ns,
186 const ::std::string& fieldName);
187 EntityIdList findAllIds(const std::string& ns);
188 NameList findAllFieldValues(const std::string& ns, const std::string& fieldName);
189
190 std::string insert(const std::string& ns, const DBStorableData& obj, bool upsert = false);
191 std::vector<std::string> insertList(const std::string& ns,
192 const DBStorableDataList& objectList);
193 bool update(const std::string& ns,
194 const DBStorableData& obj,
195 const std::string& keyField,
196 bool upsert = false);
197 bool
198 updateByQuery(const std::string& ns, const std::string& query, const mongo::BSONObj& obj);
199
200 bool removeByMongoId(const std::string& ns, const std::string& id);
201 bool removeByFieldValue(const std::string& ns,
202 const std::string& fieldName,
203 const std::string& fieldValue);
204 bool removeByQuery(const std::string& ns, const std::string& query);
205 bool clearCollection(const std::string& ns);
206
207 bool ensureIndex(const std::string& ns, const std::string& fieldName, bool unique);
208
209 void removeFileByQuery(const std::string& dbName, const mongo::BSONObj& fileQuery);
210
211 NameList getFileNameList(const std::string& dbName,
212 const Ice::Current& c = Ice::emptyCurrent) override;
213 NameList getFileIdList(const std::string& dbName,
214 const Ice::Current& c = Ice::emptyCurrent) override;
215
216 private:
217 bool removeByMongoQuery(const std::string& ns, const mongo::Query& query);
218 DBStorableDataList
219 findByMongoQuery(const std::string& ns, const mongo::Query& query, bool justOne = false);
220 NameList findFieldByMongoQuery(const std::string& ns,
221 const mongo::Query& query,
222 const std::string& fieldName);
223 mongo::GridFile getFileByQuery(const std::string& dbName, const mongo::BSONObj& query);
224 GridFileInterfacePrx createFileProxy(mongo::GridFile gridFile, const Ice::Current& c);
225 std::string getDocumentId(const mongo::BSONObj& doc);
226 std::string getDocumentField(const mongo::BSONObj& doc, const std::string& fieldName);
227 GridFSPtr getGridFS(const std::string& dbName);
228 bool readTextFile(mongo::GridFile& gridFile, std::string& buffer);
229 bool readBinaryFile(mongo::GridFile& gridFile, memoryx::Blob& buffer);
230
231 std::string createPasswordDigest(const std::string& username, const std::string& password);
232 std::string extractDBNameFromNS(const std::string& ns);
233 bool authenticateNS(const std::string& ns);
234 bool authenticateDB(const std::string& dbName);
235 bool forceAuthenticate(const std::string& dbName,
236 const std::string& userName,
237 const std::string& password);
238
239 /**
240 * @brief checkConnection is periodically called by memoryx::CommonStorage::connectionCheckerTask
241 *
242 * This method runs a query on the database and sets CommonStorage to state disconnected
243 * if the query fails (usually because the database connection has been lost.
244 */
245 void checkConnection();
246
247 private:
248 mutable std::mutex serverSettingsMutex;
249 std::string hostAndPort;
250 bool useAuth;
251 std::string userName;
252 std::string pwdDigest;
253 std::deque<std::shared_ptr<mongo::DBClientConnection>> pool;
254
255 struct ConnectionWrapper
256 {
257 ConnectionWrapper(CommonStorage& storage,
258 std::shared_ptr<mongo::DBClientConnection> connPtr);
259 ConnectionWrapper(ConnectionWrapper&&) = default;
260 ~ConnectionWrapper();
261
262 mongo::DBClientConnection& conn();
263
264 private:
265 std::shared_ptr<mongo::DBClientConnection> connPtr;
266 const std::string hostAndPort;
267 CommonStorage* const storage;
268 };
269
270 ConnectionWrapper getConnection();
271
272 std::shared_ptr<mongo::DBClientConnection> conn;
273 std::set<std::string> authDBs;
274
275 std::map<Ice::Identity, DatabaseInterfacePtr> openedDatabases;
276 mutable std::mutex openedDatabasesMutex;
277 std::map<Ice::Identity, CollectionInterfacePtr> openedCollections;
278 mutable std::mutex openedCollectionsMutex;
279 std::map<Ice::Identity, GridFileWrapperPtr> openedFiles;
280 mutable std::mutex openedFilesMutex;
281 std::map<std::string, GridFSPtr> openedGridFS;
282 mutable std::mutex openedGridFSMutex;
283
284 mutable std::shared_ptr<std::mutex> accessGridFSFilesMutex;
285
286 /**
287 * @brief connectionCheckerTask periodically runs memoryx::CommonStorage::checkConnection()
288 */
290
291 bool connect();
292 bool keepOldFileIfEqual(const mongo::GridFile& oldFile,
293 const mongo::GridFile newFile,
294 const mongo::BSONObj& newFileDoc,
295 const std::string dbName,
296 std::string& oldId);
297 };
298
300} // namespace memoryx
#define ARMARXCOMPONENT_IMPORT_EXPORT
constexpr T c
Default component property definition container.
Definition Component.h:70
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition Component.h:94
IceUtil::Handle< PeriodicTask< T > > pointer_type
Shared pointer type for convenience.
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
PropertyDefinition< PropertyType > & defineRequiredProperty(const std::string &name, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
CommonStoragePropertyDefinitions(std::string prefix)
The CommonStorage class provides an interface to MongoDB.
void onInitComponent() override
Pure virtual hook for the subclass.
bool isConnected(const ::Ice::Current &c=Ice::emptyCurrent) override
bool removeByMongoId(const std::string &ns, const std::string &id)
bool getBinaryFileById(const ::std::string &dbName, const ::std::string &fileId, memoryx::Blob &buffer, const ::Ice::Current &c=Ice::emptyCurrent) override
bool removeFileById(const ::std::string &dbName, const ::std::string &fileId, const ::Ice::Current &c=Ice::emptyCurrent) override
bool removeByQuery(const std::string &ns, const std::string &query)
void releaseCollection(const CollectionInterfacePrx &coll, const ::Ice::Current &c=Ice::emptyCurrent) override
GridFileInterfacePrx getFileProxyById(const ::std::string &dbName, const ::std::string &fileId, const ::Ice::Current &c=Ice::emptyCurrent) override
Ice::Int count(const std::string &ns)
bool clearCollection(const std::string &ns)
NameList getDBNames(const ::Ice::Current &=Ice::emptyCurrent) override
std::string storeBinaryFile(const ::std::string &dbName, const memoryx::Blob &bufferToStore, const ::std::string &gridFSName="", const ::Ice::Current &c=Ice::emptyCurrent) override
bool getTextFileById(const ::std::string &dbName, const ::std::string &fileId, ::std::string &buffer, const ::Ice::Current &c=Ice::emptyCurrent) override
DBStorableData findByMongoId(const std::string &ns, const std::string &id)
GridFileInterfacePrx getFileProxyByName(const ::std::string &dbName, const ::std::string &gridFSName, const ::Ice::Current &c=Ice::emptyCurrent) override
NameList getFileIdList(const std::string &dbName, const Ice::Current &c=Ice::emptyCurrent) override
bool removeFileByName(const ::std::string &dbName, const ::std::string &gridFSName, const ::Ice::Current &c=Ice::emptyCurrent) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
std::string insert(const std::string &ns, const DBStorableData &obj, bool upsert=false)
DBStorableDataList findByQuery(const std::string &ns, const std::string &query, const std::string &where="")
void releaseFileProxy(const GridFileInterfacePrx &fileProxy, const ::Ice::Current &c=Ice::emptyCurrent) override
bool removeByFieldValue(const std::string &ns, const std::string &fieldName, const std::string &fieldValue)
DBStorableDataList findAll(const std::string &ns)
NameList findAllFieldValues(const std::string &ns, const std::string &fieldName)
bool update(const std::string &ns, const DBStorableData &obj, const std::string &keyField, bool upsert=false)
std::string storeTextFile(const ::std::string &dbName, const ::std::string &bufferToStore, const ::std::string &gridFSName="", const ::Ice::Current &c=Ice::emptyCurrent) override
std::vector< std::string > insertList(const std::string &ns, const DBStorableDataList &objectList)
DBStorableData findOneByQuery(const std::string &ns, const std::string &query)
DBStorableData findOneByFieldValue(const std::string &ns, const std::string &fieldName, const ::std::string &fieldValue)
DBStorableDataList findByFieldValue(const std::string &ns, const std::string &fieldName, const ::std::string &fieldValue)
void onConnectComponent() override
Pure virtual hook for the subclass.
CollectionInterfacePrx requestCollection(const std::string &collectionNS, const ::Ice::Current &c=Ice::emptyCurrent) override
DBStorableData findAllUniqueByFieldName(const std::string &ns, const ::std::string &fieldName)
bool ensureIndex(const std::string &ns, const std::string &fieldName, bool unique)
DatabaseInterfacePrx requestDatabase(const ::std::string &dbName, const ::Ice::Current &=Ice::emptyCurrent) override
static std::string GetDefaultName()
NameList getCollectionNames(const ::std::string &dbName, const ::Ice::Current &=Ice::emptyCurrent) override
bool updateByQuery(const std::string &ns, const std::string &query, const mongo::BSONObj &obj)
EntityIdList findAllIds(const std::string &ns)
bool reconnect(const ::std::string &hostAndPort, const ::std::string &userName, const ::std::string &password, const ::Ice::Current &=Ice::emptyCurrent) override
void releaseDatabase(const DatabaseInterfacePrx &db, const ::Ice::Current &=Ice::emptyCurrent) override
bool authDB(const ::std::string &dbName, const ::std::string &userName, const ::std::string &password, const ::Ice::Current &=Ice::emptyCurrent) override
std::string storeFile(const ::std::string &dbName, const ::std::string &fileName, const ::std::string &gridFSName="", const ::Ice::Current &c=Ice::emptyCurrent) override
void onExitComponent() override
Hook for subclass.
void dropCollection(const std::string &collectionNS, const ::Ice::Current &c=Ice::emptyCurrent) override
NameList getFileNameList(const std::string &dbName, const Ice::Current &c=Ice::emptyCurrent) override
DBStorableDataList findByFieldValueList(const std::string &ns, const std::string &fieldName, const NameList &fieldValueList)
std::string getMongoHostAndPort(const ::Ice::Current &c=Ice::emptyCurrent) override
std::string getDefaultName() const override
Retrieve default name of component.
bool getBinaryFileByName(const ::std::string &dbName, const ::std::string &gridFSName, memoryx::Blob &buffer, const ::Ice::Current &c=Ice::emptyCurrent) override
void removeFileByQuery(const std::string &dbName, const mongo::BSONObj &fileQuery)
bool getTextFileByName(const ::std::string &dbName, const ::std::string &gridFSName, ::std::string &buffer, const ::Ice::Current &c=Ice::emptyCurrent) override
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
VirtualRobot headers.
IceInternal::Handle< GridFileWrapper > GridFileWrapperPtr
std::shared_ptr< mongo::GridFS > GridFSPtr
IceUtil::Handle< CommonStorage > CommonStoragePtr