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 
59  void resetClient()
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
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::removeData
void removeData(std::string &key)
Definition: RESTStorageMixin.h:242
armarx::armem::server::ltm::detail::mixin::RESTServerConfig
Definition: RESTStorageMixin.h:23
armarx::armem::MemoryID::providerSegmentName
std::string providerSegmentName
Definition: MemoryID.h:52
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::writeDataToRest
void writeDataToRest(std::string &key, DataType type, const std::vector< unsigned char > &data)
Definition: RESTStorageMixin.h:219
MemoryID.h
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::readDataFromRest
std::vector< unsigned char > readDataFromRest(std::string &key)
Definition: RESTStorageMixin.h:135
armarx::armem::server::ltm::detail::mixin::RESTServerConfig::host
std::string host
Definition: RESTStorageMixin.h:24
armarx::armem
Definition: LegacyRobotStateMemoryAdapter.cpp:32
armarx::armem::server::ltm ::util::fs::detail::escapeName
std::string escapeName(const std::string &segmentName)
Definition: filesystem.cpp:19
PeriodicTask.h
armarx::armem::MemoryID::coreSegmentName
std::string coreSegmentName
Definition: MemoryID.h:51
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::getItems
std::vector< std::string > getItems()
Definition: RESTStorageMixin.h:169
armarx::armem::server::ltm::detail::mixin::JSON
@ JSON
Definition: RESTStorageMixin.h:20
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::createPropertyDefinitions
void createPropertyDefinitions(PropertyDefinitionsPtr &defs, const std::string &prefix)
Definition: RESTStorageMixin.h:281
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::setPort
void setPort(int port)
Definition: RESTStorageMixin.h:288
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::resetClient
void resetClient()
Definition: RESTStorageMixin.h:59
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::RESTStorageMixin
RESTStorageMixin()
Definition: RESTStorageMixin.h:31
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
armarx::armem::MemoryID::hasTimestamp
bool hasTimestamp() const
Definition: MemoryID.h:127
armarx::armem::server::ltm::detail::mixin::DataType
DataType
Definition: RESTStorageMixin.h:19
armarx::armem::MemoryID::hasInstanceIndex
bool hasInstanceIndex() const
Definition: MemoryID.h:139
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin
Definition: RESTStorageMixin.h:28
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::RESTStorageMixin
RESTStorageMixin(const std::string &exportName, const armem::MemoryID &id, std::string host="localhost", int port=8080)
Definition: RESTStorageMixin.h:32
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::armem::MemoryID::entityName
std::string entityName
Definition: MemoryID.h:53
memory_definitions.h
armarx::armem::MemoryID::hasEntityName
bool hasEntityName() const
Definition: MemoryID.h:121
armarx::armem::MemoryID::memoryName
std::string memoryName
Definition: MemoryID.h:50
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::setMixinExportName
void setMixinExportName(const std::string &exportName)
Definition: RESTStorageMixin.h:276
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::writeDataToRest
void writeDataToRest(std::string &key, nlohmann::json &jsonData)
Definition: RESTStorageMixin.h:211
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::armem::server::ltm::detail::mixin
Definition: BufferedMemoryMixin.cpp:3
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::writeDataToRest
void writeDataToRest(std::string &key, const std::vector< unsigned char > &data)
Definition: RESTStorageMixin.h:109
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::armem::MemoryID::hasProviderSegmentName
bool hasProviderSegmentName() const
Definition: MemoryID.h:115
armarx::armem::MemoryID::hasCoreSegmentName
bool hasCoreSegmentName() const
Definition: MemoryID.h:109
armarx::armem::MemoryID::hasMemoryName
bool hasMemoryName() const
Definition: MemoryID.h:103
armarx::armem::server::ltm::detail::mixin::PNG
@ PNG
Definition: RESTStorageMixin.h:20
filesystem.h
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::checkConnection
bool checkConnection()
Definition: RESTStorageMixin.h:40
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::setHost
void setHost(std::string &host)
Definition: RESTStorageMixin.h:299
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::containsItem
bool containsItem(std::string &key)
Definition: RESTStorageMixin.h:69
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::getPort
int getPort() const
Definition: RESTStorageMixin.h:294
Logging.h
httplib.h
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::setMixinMemoryID
void setMixinMemoryID(armem::MemoryID &id)
Definition: RESTStorageMixin.h:271
armarx::armem::server::ltm::detail::mixin::RESTStorageMixin::getHost
std::string getHost()
Definition: RESTStorageMixin.h:305
armarx::armem::MemoryID::instanceIndexStr
std::string instanceIndexStr() const
Get the instance index as string.
Definition: MemoryID.cpp:455
armarx::armem::server::ltm::detail::mixin::RESTServerConfig::ltm_path
std::string ltm_path
Definition: RESTStorageMixin.h:25
armarx::armem::MemoryID::timestampStr
std::string timestampStr() const
Get the timestamp as string.
Definition: MemoryID.cpp:449