command_interpreter.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <exceptions/exceptions.h>
  8. #include <cc/command_interpreter.h>
  9. #include <string>
  10. #include <cc/data.h>
  11. using namespace std;
  12. using isc::data::Element;
  13. using isc::data::ConstElementPtr;
  14. using isc::data::ElementPtr;
  15. using isc::data::JSONError;
  16. namespace isc {
  17. namespace config {
  18. const char *CONTROL_COMMAND = "command";
  19. const char *CONTROL_RESULT = "result";
  20. const char *CONTROL_TEXT = "text";
  21. const char *CONTROL_ARGUMENTS = "arguments";
  22. // Full version, with status, text and arguments
  23. ConstElementPtr
  24. createAnswer(const int status_code, const std::string& text,
  25. const ConstElementPtr& arg) {
  26. if (status_code != 0 && text.empty()) {
  27. isc_throw(CtrlChannelError, "Text has to be provided for status_code != 0");
  28. }
  29. ElementPtr answer = Element::createMap();
  30. ElementPtr result = Element::create(status_code);
  31. answer->set(CONTROL_RESULT, result);
  32. if (!text.empty()) {
  33. answer->set(CONTROL_TEXT, Element::create(text));
  34. }
  35. if (arg) {
  36. answer->set(CONTROL_ARGUMENTS, arg);
  37. }
  38. return (answer);
  39. }
  40. ConstElementPtr
  41. createAnswer() {
  42. return (createAnswer(0, string(""), ConstElementPtr()));
  43. }
  44. ConstElementPtr
  45. createAnswer(const int status_code, const std::string& text) {
  46. return (createAnswer(status_code, text, ElementPtr()));
  47. }
  48. ConstElementPtr
  49. createAnswer(const int status_code, const ConstElementPtr& arg) {
  50. return (createAnswer(status_code, "", arg));
  51. }
  52. ConstElementPtr
  53. parseAnswer(int &rcode, const ConstElementPtr& msg) {
  54. if (!msg) {
  55. isc_throw(CtrlChannelError, "No answer specified");
  56. }
  57. if (msg->getType() != Element::map) {
  58. isc_throw(CtrlChannelError,
  59. "Invalid answer Element specified, expected map");
  60. }
  61. if (!msg->contains(CONTROL_RESULT)) {
  62. isc_throw(CtrlChannelError,
  63. "Invalid answer specified, does not contain mandatory 'result'");
  64. }
  65. ConstElementPtr result = msg->get(CONTROL_RESULT);
  66. if (result->getType() != Element::integer) {
  67. isc_throw(CtrlChannelError,
  68. "Result element in answer message is not a string");
  69. }
  70. rcode = result->intValue();
  71. // If there are arguments, return them.
  72. ConstElementPtr args = msg->get(CONTROL_ARGUMENTS);
  73. if (args) {
  74. return (args);
  75. }
  76. // There are no arguments, let's try to return just the text status
  77. return (msg->get(CONTROL_TEXT));
  78. }
  79. std::string
  80. answerToText(const ConstElementPtr& msg) {
  81. if (!msg) {
  82. isc_throw(CtrlChannelError, "No answer specified");
  83. }
  84. if (msg->getType() != Element::map) {
  85. isc_throw(CtrlChannelError,
  86. "Invalid answer Element specified, expected map");
  87. }
  88. if (!msg->contains(CONTROL_RESULT)) {
  89. isc_throw(CtrlChannelError,
  90. "Invalid answer specified, does not contain mandatory 'result'");
  91. }
  92. ConstElementPtr result = msg->get(CONTROL_RESULT);
  93. if (result->getType() != Element::integer) {
  94. isc_throw(CtrlChannelError,
  95. "Result element in answer message is not a string");
  96. }
  97. stringstream txt;
  98. int rcode = result->intValue();
  99. if (rcode == 0) {
  100. txt << "success(0)";
  101. } else {
  102. txt << "failure(" << rcode << ")";
  103. }
  104. // Was any text provided? If yes, include it.
  105. ConstElementPtr txt_elem = msg->get(CONTROL_TEXT);
  106. if (txt_elem) {
  107. txt << ", text=" << txt_elem->stringValue();
  108. }
  109. return (txt.str());
  110. }
  111. ConstElementPtr
  112. createCommand(const std::string& command) {
  113. return (createCommand(command, ElementPtr()));
  114. }
  115. ConstElementPtr
  116. createCommand(const std::string& command, ConstElementPtr arg) {
  117. ElementPtr query = Element::createMap();
  118. ElementPtr cmd = Element::create(command);
  119. query->set(CONTROL_COMMAND, cmd);
  120. if (arg) {
  121. query->set(CONTROL_ARGUMENTS, arg);
  122. }
  123. return (query);
  124. }
  125. std::string
  126. parseCommand(ConstElementPtr& arg, ConstElementPtr command) {
  127. if (!command) {
  128. isc_throw(CtrlChannelError, "No command specified");
  129. }
  130. if (command->getType() != Element::map) {
  131. isc_throw(CtrlChannelError, "Invalid command Element specified, expected map");
  132. }
  133. if (!command->contains(CONTROL_COMMAND)) {
  134. isc_throw(CtrlChannelError,
  135. "Invalid answer specified, does not contain mandatory 'command'");
  136. }
  137. ConstElementPtr cmd = command->get(CONTROL_COMMAND);
  138. if (cmd->getType() != Element::string) {
  139. isc_throw(CtrlChannelError,
  140. "'command' element in command message is not a string");
  141. }
  142. arg = command->get(CONTROL_ARGUMENTS);
  143. return (cmd->stringValue());
  144. }
  145. }
  146. }