hce-node application  1.4.3
HCE Hierarchical Cluster Engine node application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ServiceMessages.cpp
Go to the documentation of this file.
1 #include <Poco/JSON/JSON.h>
2 #include <Poco/JSON/Stringifier.h>
3 #include <Poco/JSON/Parser.h>
4 #include <Poco/JSON/JSONException.h>
5 #include <Poco/Dynamic/Var.h>
6 #include <sstream>
7 #include <algorithm>
8 #include <iterator>
9 
10 #include "ServiceMessages.hpp"
11 
12 namespace HCE
13 {
14 namespace handlers
15 {
16 //-----------------------------------------------------------------------------
17 RouteMessage::RouteMessage(std::vector<ClientWorkerItem>& queue_)
18 : inherited(), queue(queue_)
19 {
20 }
21 //-----------------------------------------------------------------------------
22 void RouteMessage::packToObject(Poco::JSON::Object& obj, const std::vector<ClientWorkerItem>& workerItem)
23 {
24  for (size_t i=0;i<workerItem.size();++i)
25  {
26  Poco::JSON::Object::Ptr pItemElem = new Poco::JSON::Object();
27  if (!pItemElem.isNull())
28  {
29  packToObject(*pItemElem, workerItem[i].route);
30  obj.set(workerItem[i].identity, pItemElem);
31  }
32  }
33 }
34 //-----------------------------------------------------------------------------
35 bool RouteMessage::serialize(std::string& json)
36 {
37  resetError();
38  try
39  {
40  Poco::JSON::Object::Ptr pObj = new Poco::JSON::Object();
41  if (pObj.isNull())
42  throw Poco::Exception("Object instance was not created");
43 
44  packToObject(*pObj, queue);
45 
46  std::stringstream ostr;
47  Poco::JSON::Stringifier::stringify(pObj, ostr);
48  json = ostr.str();
49 
50  _isError = false;
51  }
52  catch(Poco::Exception& e)
53  {
54  _isError = true;
55  errorMsg = e.displayText();
57  }
58  catch(std::exception& e)
59  {
60  _isError = true;
61  errorMsg = e.what();
63  }
64  return !_isError;
65 }
66 //-----------------------------------------------------------------------------
67 void RouteMessage::unpackFromObject(Poco::JSON::Object& obj, std::vector<ClientWorkerItem>& workerItem)
68 {
69  std::vector<std::string> names;
70  obj.getNames(names);
71 
72  for (size_t i=0;i<names.size();++i)
73  {
74  Poco::JSON::Object::Ptr pObj = obj.getObject(names[i]);
75  if (!pObj.isNull())
76  {
77  ClientWorkerItem clientWorker(names[i]);
78  unpackFromObject(*pObj, clientWorker.route);
79  workerItem.push_back(std::forward<ClientWorkerItem>(clientWorker));
80  }
81  }
82 }
83 //-----------------------------------------------------------------------------
84 bool RouteMessage::unserialize(const std::string& json)
85 {
86  resetError();
87  queue.clear();
88 
89  try
90  {
91  Poco::JSON::Parser parser;
92  Poco::Dynamic::Var res = parser.parse(json);
93 
94  Poco::JSON::Object::Ptr pObj = res.extract<Poco::JSON::Object::Ptr>();
95 
96  unpackFromObject(*pObj, queue);
97 
98  _isError = false;
99  }
100  catch(Poco::JSON::JSONException& e)
101  {
102  _isError = true;
103  errorMsg = e.displayText();
105  }
106  catch(Poco::Exception& e)
107  {
108  _isError = true;
109  errorMsg = e.displayText();
111  }
112  catch(std::exception& e)
113  {
114  _isError = true;
115  errorMsg = e.what();
117  }
118  return !_isError;
119 }
120 //-----------------------------------------------------------------------------
121 std::string RouteMessage::build(const std::string& title)
122 {
123  std::string result = "";
124  std::string json;
125  serialize(json);
126 
127  if (title.empty())
128  result = json;
129  else
130  result = (title+ROUTE_TABLE_MSG_TITLE_DELIMITER+json);
131  return result;
132 }
133 //-----------------------------------------------------------------------------
134 void RouteMessage::extract(const std::string& title, const std::string& msgBody)
135 {
136  try
137  {
138  if (msgBody.compare(0, title.length(), title)!=0)
139  Poco::Exception("Title of message not found", ERROR_TITLE);
140 
141  size_t pos = msgBody.find_first_of(ROUTE_TABLE_MSG_TITLE_DELIMITER);
142  if (pos==std::string::npos)
143  Poco::Exception("Delimiter of title message not found", ERROR_TITLE);
144 
145  std::string json = msgBody.substr(pos+1);
146  unserialize(json);
147  }
148  catch(Poco::Exception& e)
149  {
150  _isError = true;
151  errorMsg = e.displayText();
152  errorCode = e.code();
153  }
154 }
155 //-----------------------------------------------------------------------------
157 {
158  queue.clear();
159 }
160 //-----------------------------------------------------------------------------
161 std::vector<std::string> RouteMessage::extractIdentityNames(const std::string& routeMsg)
162 {
163  std::vector<std::string> clients;
164  std::string routes(routeMsg);
165 
166  size_t pos = routes.find_first_of(ROUTE_LIST_COUNT_DELIMITER);
167  if (pos!=std::string::npos)
168  routes = routes.substr(0, pos);
169 
170  std::replace(routes.begin(), routes.end(), ROUTE_LIST_NAMES_DELIMITER, ' ');
171 
172  std::stringstream routesStream(routes);
173  std::istream_iterator <std::string> iit(routesStream);
174  std::istream_iterator <std::string> eos;
175 
176  while (iit != eos)
177  {
178  clients.push_back((*iit));
179  ++iit;
180  }
181  return clients;
182 }
183 //-----------------------------------------------------------------------------
184 std::string RouteMessage::buildIdentityNames(const std::vector<ClientWorkerItem>& clientQueue)
185 {
186  std::vector<std::string> names;
187  for (size_t i=0;i<clientQueue.size();++i)
188  {
189  names.push_back(clientQueue[i].identity);
190  }
191  return buildIdentityNames(names);
192 }
193 //-----------------------------------------------------------------------------
194 std::string RouteMessage::buildIdentityNames(const std::vector<std::string>& names)
195 {
196  std::stringstream outMsg;
197  for (size_t i=0;i<names.size();++i)
198  {
199  outMsg << names[i];
200  if ((i+1) < names.size())
201  outMsg << ROUTE_LIST_NAMES_DELIMITER;
202  }
203  return outMsg.str();
204 }
205 //-----------------------------------------------------------------------------
206 void RouteMessage::extractRouteNames(std::vector<std::string>& routeNames, const std::vector<ClientWorkerItem>& clientQueue)
207 {
208  for (size_t i=0;i<clientQueue.size();++i)
209  {
210  routeNames.push_back(clientQueue[i].identity);
211  extractRouteNames(routeNames, clientQueue[i].route);
212  }
213 }
214 //-----------------------------------------------------------------------------
215 std::vector<std::string> RouteMessage::extractRouteNames(const std::vector<ClientWorkerItem>& clientQueue)
216 {
217  std::vector<std::string> routeNames;
218  extractRouteNames(routeNames, clientQueue);
219  return routeNames;
220 }
221 //-----------------------------------------------------------------------------
222 std::vector<std::string> RouteMessage::extractRouteNames(void)
223 {
224  return extractRouteNames(queue);
225 }
226 //-----------------------------------------------------------------------------
227 //-----------------------------------------------------------------------------
229 : inherited(), managerRole(0), nodesNames(), resourcesUsageAlgorithm(0), resourcesUsageAlgorithmWeights(""), resourcesUsageLimits("")
230 {
231  if (!json.empty())
232  unserialize(json);
233 }
234 //-----------------------------------------------------------------------------
235 bool RequestRouteMessage::serialize(std::string& json)
236 {
237  resetError();
238  try
239  {
240  Poco::JSON::Object::Ptr pObj = new Poco::JSON::Object();
241  if (pObj.isNull())
242  throw Poco::Exception("Object instance was not created");
243 
244  pObj->set(MANAGER_ROLE, managerRole);
245 
246  Poco::JSON::Array::Ptr pNodesNames = new Poco::JSON::Array();
247  if (pNodesNames.isNull())
248  throw Poco::Exception("Object instance was not created");
249 
250  for (size_t i=0;i<nodesNames.size();++i)
251  {
252  pNodesNames->add(nodesNames[i]);
253  }
254  pObj->set(NODES_NAMES, pNodesNames);
255 
256  pObj->set(RESOURCES_USAGE_ALGORITHM, resourcesUsageAlgorithm);
257  pObj->set(RESOURCES_USAGE_ALGORITHM_WEIGHTS, resourcesUsageAlgorithmWeights);
258  pObj->set(RESOURCES_USAGE_LIMITS, resourcesUsageLimits);
259 
260  std::stringstream ostr;
261  Poco::JSON::Stringifier::stringify(pObj, ostr);
262  json = ostr.str();
263 
264  _isError = false;
265  }
266  catch(Poco::Exception& e)
267  {
268  _isError = true;
269  errorMsg = e.displayText();
271  }
272  catch(std::exception& e)
273  {
274  _isError = true;
275  errorMsg = e.what();
277  }
278  return !_isError;
279 }
280 //-----------------------------------------------------------------------------
281 bool RequestRouteMessage::unserialize(const std::string& json)
282 {
283  resetError();
284  clear();
285 
286  try
287  {
288  Poco::JSON::Parser parser;
289  Poco::Dynamic::Var res = parser.parse(json);
290 
291  Poco::JSON::Object::Ptr pObj = res.extract<Poco::JSON::Object::Ptr>();
292 
293  Poco::Dynamic::Var tmp = pObj->get(MANAGER_ROLE);
294  managerRole = convertVarToNumeric<unsigned int>(tmp, 0);
295 
296  Poco::JSON::Array::Ptr pNodesNames = pObj->getArray(NODES_NAMES);
297  for (size_t i=0;i<pNodesNames->size();++i)
298  {
299  tmp = pNodesNames->get(i);
300  if (tmp.isString())
301  nodesNames.push_back(tmp.convert<std::string>());
302  }
303 
304  tmp = pObj->get(RESOURCES_USAGE_ALGORITHM);
305  resourcesUsageAlgorithm = convertVarToNumeric<unsigned int>(tmp, 0);
306 
307  tmp = pObj->get(RESOURCES_USAGE_ALGORITHM_WEIGHTS);
308  if (tmp.isString())
309  resourcesUsageAlgorithmWeights = tmp.convert<std::string>();
310 
311  tmp = pObj->get(RESOURCES_USAGE_LIMITS);
312  if (tmp.isString())
313  resourcesUsageLimits = tmp.convert<std::string>();
314 
315  _isError = false;
316  }
317  catch(Poco::JSON::JSONException& e)
318  {
319  _isError = true;
320  errorMsg = e.displayText();
322  }
323  catch(Poco::Exception& e)
324  {
325  _isError = true;
326  errorMsg = e.displayText();
328  }
329  return !_isError;
330 }
331 //-----------------------------------------------------------------------------
333 {
334  managerRole = 0;
335  nodesNames.clear();
336  resourcesUsageAlgorithm = 0;
337  resourcesUsageAlgorithmWeights.clear();
338  resourcesUsageLimits.clear();
339 }
340 //-----------------------------------------------------------------------------
341 //-----------------------------------------------------------------------------
342 HeartbeatMessage::HeartbeatMessage(std::vector<ClientWorkerItem>& queue_, const std::string& resources_)
343 : inherited(), queue(queue_), resources(resources_)
344 {
345 }
346 //-----------------------------------------------------------------------------
347 void HeartbeatMessage::packToObject(Poco::JSON::Object& obj, const std::vector<ClientWorkerItem>& workerItem)
348 {
349  for (size_t i=0;i<workerItem.size();++i)
350  {
351  Poco::JSON::Object::Ptr pItemElem = new Poco::JSON::Object();
352  if (!pItemElem.isNull())
353  {
354  packToObject(*pItemElem, workerItem[i].route);
355  obj.set(workerItem[i].identity, pItemElem);
356  }
357  }
358 }
359 //-----------------------------------------------------------------------------
360 bool HeartbeatMessage::serialize(std::string& json)
361 {
362  resetError();
363  try
364  {
365  Poco::JSON::Object::Ptr pObj = new Poco::JSON::Object();
366  if (pObj.isNull())
367  throw Poco::Exception("Object instance was not created");
368 
369  Poco::JSON::Object::Ptr pRoutesElem = new Poco::JSON::Object();
370  if (pRoutesElem.isNull())
371  throw Poco::Exception("Object instance was not created");
372 
373  packToObject(*pRoutesElem, queue);
375  pObj->set(HCE::handlers::HEARTBEAT_JSON_ROUTES, pRoutesElem);
377  pObj->set(HCE::handlers::HEARTBEAT_JSON_RESOURCES, resources);
378 
379  std::stringstream ostr;
380  Poco::JSON::Stringifier::stringify(pObj, ostr);
381  json = ostr.str();
382 
383  _isError = false;
384  }
385  catch(Poco::Exception& e)
386  {
387  _isError = true;
388  errorMsg = e.displayText();
390  }
391  catch(std::exception& e)
392  {
393  _isError = true;
394  errorMsg = e.what();
396  }
397  return !_isError;
398 }
399 //-----------------------------------------------------------------------------
400 void HeartbeatMessage::unpackFromObject(Poco::JSON::Object& obj, std::vector<ClientWorkerItem>& workerItem)
401 {
402  std::vector<std::string> names;
403  obj.getNames(names);
404 
405  for (size_t i=0;i<names.size();++i)
406  {
407  Poco::JSON::Object::Ptr pObj = obj.getObject(names[i]);
408  if (!pObj.isNull())
409  {
410  ClientWorkerItem clientWorker(names[i]);
411  unpackFromObject(*pObj, clientWorker.route);
412  workerItem.push_back(std::forward<ClientWorkerItem>(clientWorker));
413  }
414  }
415 }
416 //-----------------------------------------------------------------------------
417 bool HeartbeatMessage::unserialize(const std::string& json)
418 {
419  clear();
420  try
421  {
422  Poco::JSON::Parser parser;
423  Poco::Dynamic::Var res = parser.parse(json);
424 
425  Poco::JSON::Object::Ptr pObj = res.extract<Poco::JSON::Object::Ptr>();
426 
427  Poco::JSON::Object::Ptr pRoutesElem = pObj->getObject(HCE::handlers::HEARTBEAT_JSON_ROUTES);
428  if (!pRoutesElem.isNull())
429  {
430  unpackFromObject(*pRoutesElem, queue);
431  }
432 
433  Poco::Dynamic::Var tmp = pObj->get(HCE::handlers::HEARTBEAT_JSON_RESOURCES);
434  if (tmp.isString())
435  resources = tmp.convert<std::string>();
436 
437  _isError = false;
438  }
439  catch(Poco::JSON::JSONException& e)
440  {
441  _isError = true;
442  errorMsg = e.displayText();
444  }
445  catch(Poco::Exception& e)
446  {
447  _isError = true;
448  errorMsg = e.displayText();
450  }
451  catch(std::exception& e)
452  {
453  _isError = true;
454  errorMsg = e.what();
456  }
457  return !_isError;
458 }
459 //-----------------------------------------------------------------------------
460 std::string HeartbeatMessage::build(const std::string& title)
461 {
462  std::string result = "";
463  std::string json;
464  serialize(json);
465 
466  if (title.empty())
467  result = json;
468  else
469  result = (title+HEARTBEAT_MSG_DELIMITER+json);
470  return result;
471 }
472 //-----------------------------------------------------------------------------
473 void HeartbeatMessage::extract(const std::string& message, const std::string& title)
474 {
475  try
476  {
477  if (message.compare(0, title.length(), title)!=0)
478  Poco::Exception("Title of message not found", ERROR_TITLE);
479 
480  size_t pos = message.find_first_of(HEARTBEAT_MSG_DELIMITER);
481  if (pos==std::string::npos)
482  Poco::Exception("Delimiter of title message not found", ERROR_TITLE);
483 
484  std::string json = message.substr(pos+1);
485  unserialize(json);
486  }
487  catch(Poco::Exception& e)
488  {
489  _isError = true;
490  errorMsg = e.displayText();
491  errorCode = e.code();
492  }
493 }
494 //-----------------------------------------------------------------------------
496 {
497  resetError();
498  queue.clear();
499  resources.clear();
500 }
501 //-----------------------------------------------------------------------------
502 //-----------------------------------------------------------------------------
503 PropertyMessage::PropertyMessage(const std::string& identity_, const std::string& property_)
504 : inherited(), identity(identity_), property(property_)
505 {
506 }
507 //-----------------------------------------------------------------------------
508 bool PropertyMessage::serialize(std::string& json)
509 {
510  resetError();
511  try
512  {
513  Poco::JSON::Object::Ptr pObj = new Poco::JSON::Object();
514  if (pObj.isNull())
515  throw Poco::Exception("Object instance was not created");
516 
517  pObj->set(identity, property);
518 
519  std::stringstream ostr;
520  Poco::JSON::Stringifier::stringify(pObj, ostr);
521  json = ostr.str();
522 
523  _isError = false;
524  }
525  catch(Poco::Exception& e)
526  {
527  _isError = true;
528  errorMsg = e.displayText();
530  }
531  catch(std::exception& e)
532  {
533  _isError = true;
534  errorMsg = e.what();
536  }
537  return !_isError;
538 }
539 //-----------------------------------------------------------------------------
540 bool PropertyMessage::unserialize(const std::string& json)
541 {
542  clear();
543  try
544  {
545  Poco::JSON::Parser parser;
546  Poco::Dynamic::Var res = parser.parse(json);
547 
548  Poco::JSON::Object::Ptr pObj = res.extract<Poco::JSON::Object::Ptr>();
549 
550  if (!pObj.isNull())
551  {
552  std::vector<std::string> names;
553  pObj->getNames(names);
554 
555  for (size_t i=0;i<names.size();++i)
556  {
557  identity = names[i];
558  Poco::Dynamic::Var tmp = pObj->get(identity);
559  if (tmp.isString())
560  property = tmp.convert<std::string>();
561  break;
562  }
563  }
564  _isError = false;
565  }
566  catch(Poco::JSON::JSONException& e)
567  {
568  _isError = true;
569  errorMsg = e.displayText();
571  }
572  catch(Poco::Exception& e)
573  {
574  _isError = true;
575  errorMsg = e.displayText();
577  }
578  catch(std::exception& e)
579  {
580  _isError = true;
581  errorMsg = e.what();
583  }
584  return !_isError;
585 }
586 //-----------------------------------------------------------------------------
587 std::string PropertyMessage::build(const std::string& title)
588 {
589  std::string result = "";
590  std::string json;
591  serialize(json);
592 
593  if (title.empty())
594  result = json;
595  else
596  result = (title+PROPERTY_MSG_DELIMITER+json);
597  return result;
598 }
599 //-----------------------------------------------------------------------------
600 void PropertyMessage::extract(const std::string& message, const std::string& title)
601 {
602  try
603  {
604  if (message.compare(0, title.length(), title)!=0)
605  Poco::Exception("Title of message not found", ERROR_TITLE);
606 
607  size_t pos = message.find_first_of(PROPERTY_MSG_DELIMITER);
608  if (pos==std::string::npos)
609  Poco::Exception("Delimiter of title message not found", ERROR_TITLE);
610 
611  std::string json = message.substr(pos+1);
612  unserialize(json);
613  }
614  catch(Poco::Exception& e)
615  {
616  _isError = true;
617  errorMsg = e.displayText();
618  errorCode = e.code();
619  }
620 }
621 //-----------------------------------------------------------------------------
623 {
624  resetError();
625  property.clear();
626 }
627 //-----------------------------------------------------------------------------
628 //-----------------------------------------------------------------------------
629 } // end namespace handlers
630 } // end namespace HCE