RESTStorageMixin.h
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <vector>
5
6#include <SimoxUtility/json.h>
8
11
12
16
18{
19 enum DataType {
21 };
22
24 std::string host;
25 std::string ltm_path;
26 };
27
29 {
30 public:
31 RESTStorageMixin() : RESTStorageMixin("DefaultExport", armem::MemoryID()) {}
32 RESTStorageMixin(const std::string& exportName, const armem::MemoryID& id, std::string host = "localhost", int port = 8080) : exportName_(exportName), id_(id), host_(host), port_(port) {
33 client_ = std::make_shared<httplib::Client>(host, port);
34
36 }
37
38
39
41 {
42 std::string path = "/ltm";
43
44 auto res = client_->Get(path);
45
46 if (res)
47 {
48 ARMARX_INFO << "MemoryX-REST server is running at host=" << host_ << ", port=" << port_;
49
50
51 return true;
52 }
53
54 ARMARX_INFO << "MemoryX-REST server is not running at host=" << host_ << ", port=" << port_;
55
56 return false;
57 }
58
60 {
61 if (client_)
62 {
63 client_->stop();
64 }
65
66 client_ = std::make_shared<httplib::Client>(host_, port_);
67 }
68
69 bool containsItem(std::string& key)
70 {
71 std::string path = buildPath();
72 std::string query = "key=" + key;
73 std::string url = path + "?" + query;
74
75 ARMARX_DEBUG << "GET request: Read data from MemoryX-REST server: key=" << key << ", url=" << url;
76
77 auto res = client_->Get(url);
78
79 bool containsItem = false;
80
81 if (res && res->status == 200)
82 {
83 ARMARX_DEBUG << "GET request successful: REST-LTM contain item with key=" << key;
84 ARMARX_DEBUG << "Response: " << res->body;
85
86 containsItem = true;
87 }
88 else if (res && res->status == 404)
89 {
90 ARMARX_DEBUG << "GET request successful: REST-LTM does not contain item with key=" << key;
91 ARMARX_DEBUG << "Response: " << res->body;
92
93 containsItem = false;
94 }
95 else if (res)
96 {
97 ARMARX_ERROR << "GET request failed. Status: " << res->status;
98 ARMARX_DEBUG << "Response: " << res->body;
99 }
100 else
101 {
102 ARMARX_DEBUG << "GET request failed. No connection could be established to the MemoryX-REST server at host=" << host_ << ", port=" << port_;
103 }
104
105 return containsItem;
106 }
107
108
109 void writeDataToRest(std::string& key, const std::vector<unsigned char>& data)
110 {
111 std::string path = buildPath();
112 std::string query = "key=" + key;
113 std::string url = path + "?" + query;
114
115 ARMARX_DEBUG << "PUT request: Write data to MemoryX-REST server: key=" << key << ", url=" << url;
116
117 std::string body(data.begin(), data.end());
118
119 auto res = client_->Put(url, body, "application/json");
120
121 if (res && res->status == 200)
122 {
123 ARMARX_DEBUG << "PUT request response: " << res->body;
124 }
125 else if (res)
126 {
127 ARMARX_ERROR << "PUT request failed. Status: " << res->status;
128 }
129 else
130 {
131 ARMARX_DEBUG << "PUT request failed. No connection could be established to the MemoryX-REST server at host=" << host_ << ", port=" << port_;
132 }
133 }
134
135 std::vector<unsigned char> readDataFromRest(std::string& key)
136 {
137 std::string path = buildPath();
138 std::string query = "key=" + key;
139 std::string url = path + "?" + query;
140
141 ARMARX_DEBUG << "GET request: Read data from MemoryX-REST server: key=" << key << ", url=" << url;
142
143 auto res = client_->Get(url);
144
145 std::vector<unsigned char> data;
146
147 if (res && res->status == 200)
148 {
149 ARMARX_DEBUG << "GET request response: " << res->body;
150
151 data = std::vector<unsigned char>(res->body.begin(), res->body.end());
152 }
153 else if (res && res->status == 404)
154 {
155 ARMARX_ERROR << "GET request failed: REST-LTM does not contain any item with key=" << key;
156 }
157 else if (res)
158 {
159 ARMARX_ERROR << "GET request failed. Status: " << res->status;
160 }
161 else
162 {
163 ARMARX_DEBUG << "GET request failed. No connection could be established to the MemoryX-REST server at host=" << host_ << ", port=" << port_;
164 }
165
166 return data;
167 }
168
169 std::vector<std::string> getItems()
170 {
171 std::string path = buildPath();
172 std::string url = path;
173
174 ARMARX_DEBUG << "GET request: Get items from MemoryX-REST server: url=" << url;
175
176 auto res = client_->Get(url);
177
178 std::vector<std::string> item_keys;
179
180 if (res && res->status == 200)
181 {
182 ARMARX_DEBUG << "GET request response: " << res->body;
183
184 try
185 {
186 nlohmann::json json_response = nlohmann::json::parse(res->body);
187
188 if (json_response.contains("keys") && json_response["keys"].is_array())
189 {
190 item_keys = json_response["keys"].get<std::vector<std::string>>();
191 }
192 }
193 catch (const std::exception& e)
194 {
195 ARMARX_ERROR << "GET request: Error parsing JSON: " << e.what();
196 }
197 }
198 else if (res)
199 {
200 ARMARX_ERROR << "GET request failed. Status: " << res->status;
201 }
202 else
203 {
204 ARMARX_DEBUG << "GET request failed. No connection could be established to the MemoryX-REST server at host=" << host_ << ", port=" << port_;
205 }
206
207 return item_keys;
208 }
209
210
211 void writeDataToRest(std::string& key, nlohmann::json& jsonData)
212 {
213 std::string str_data = jsonData.dump();
214 std::vector<unsigned char> data(str_data.begin(), str_data.end());
215
217 }
218
219 void writeDataToRest(std::string& key, DataType type, const std::vector<unsigned char>& data)
220 {
221 std::string path = buildPath();
222 std::string mime_type = getMimeType(type);
223 std::string query = "?item=" + key;
224
225 std::string body(data.begin(), data.end());
226
227 auto res = client_->Put(path + query, body, mime_type);
228
229 if (res)
230 {
231 ARMARX_DEBUG << "Status: " << res->status;
232 ARMARX_DEBUG << "Response: " << res->body;
233 }
234 else
235 {
236 ARMARX_ERROR << "Request failed. Error: " << res.error();
237 }
238 }
239
240
241
242 void removeData(std::string& key)
243 {
244 std::string path = buildPath();
245 std::string query = "key=" + key;
246 std::string url = path + "?" + query;
247
248 ARMARX_DEBUG << "DELETE request: Remove item from MemoryX-REST server: key=" << key << ", url=" << url;
249
250
251 auto res = client_->Delete(url);
252
253 if (res && res->status == 200)
254 {
255 ARMARX_DEBUG << "DELETE request successlful: " << res->body;
256 }
257 else if (res && res->status == 404)
258 {
259 ARMARX_ERROR << "DELETE request failed. REST-LTM does not contain any item with key=" << key;
260 }
261 else if (res)
262 {
263 ARMARX_ERROR << "DELETE request failed. Status: " << res->status;
264 }
265 else
266 {
267 ARMARX_DEBUG << "DELETE request failed. No connection could be established to the MemoryX-REST server at host=" << host_ << ", port=" << port_;
268 }
269 }
270
272 {
273 id_ = id;
274 }
275
276 void setMixinExportName(const std::string& exportName)
277 {
278 exportName_ = exportName;
279 }
280
281 void createPropertyDefinitions(PropertyDefinitionsPtr& defs, const std::string& prefix)
282 {
283 defs->optional(host_, prefix + "host");
284 defs->optional(port_, prefix + "port");
285 defs->optional(exportName_, prefix + "exportName");
286 }
287
288 void setPort(int port)
289 {
290 port_ = port;
291 resetClient();
292 }
293
294 int getPort() const
295 {
296 return port_;
297 }
298
299 void setHost(std::string& host)
300 {
301 host_ = host;
302 resetClient();
303 }
304
305 std::string getHost()
306 {
307 return host_;
308 }
309
310 private:
311 // RESTServerConfig m_config;
312 std::string exportName_;
313 std::shared_ptr<httplib::Client> client_;
314 armem::MemoryID id_;
315
316 std::string host_ = "localhost";
317 int port_ = 8080;
318
319 std::string buildPath() {
320 std::string url = "/ltm/" + exportName_;
321
322 if (id_.hasMemoryName())
323 {
325 }
326 if (id_.hasCoreSegmentName())
327 {
329 }
330 if (id_.hasProviderSegmentName())
331 {
333 }
334 if (id_.hasEntityName())
335 {
337 }
338 if (id_.hasTimestamp())
339 {
340 url += "/" + id_.timestampStr();
341 }
342 if (id_.hasInstanceIndex())
343 {
344 url += "/" + id_.instanceIndexStr();
345 }
346
347 return url;
348 }
349
350 std::string getMimeType(DataType type) {
351
352 if (type == DataType::JSON)
353 {
354 return "application/json";
355 }
356 else if (type == DataType::PNG)
357 {
358 return "image/png";
359 }
360 else
361 {
362 return "";
363 }
364 }
365 };
366
367} // namespace armarx::armem::server::ltm::detail::mixin
std::string coreSegmentName
Definition MemoryID.h:51
bool hasProviderSegmentName() const
Definition MemoryID.h:115
bool hasEntityName() const
Definition MemoryID.h:121
bool hasInstanceIndex() const
Definition MemoryID.h:139
bool hasMemoryName() const
Definition MemoryID.h:103
bool hasCoreSegmentName() const
Definition MemoryID.h:109
std::string entityName
Definition MemoryID.h:53
bool hasTimestamp() const
Definition MemoryID.h:127
std::string memoryName
Definition MemoryID.h:50
std::string instanceIndexStr() const
Get the instance index as string.
Definition MemoryID.cpp:455
std::string timestampStr() const
Get the timestamp as string.
Definition MemoryID.cpp:449
std::string providerSegmentName
Definition MemoryID.h:52
RESTStorageMixin(const std::string &exportName, const armem::MemoryID &id, std::string host="localhost", int port=8080)
void createPropertyDefinitions(PropertyDefinitionsPtr &defs, const std::string &prefix)
std::vector< unsigned char > readDataFromRest(std::string &key)
void writeDataToRest(std::string &key, nlohmann::json &jsonData)
void writeDataToRest(std::string &key, const std::vector< unsigned char > &data)
void writeDataToRest(std::string &key, DataType type, const std::vector< unsigned char > &data)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
std::string escapeName(const std::string &segmentName)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.