fake_session.cc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id: session.cc 1250 2010-03-09 22:52:15Z jinmei $
  15. #include "config.h"
  16. #include <stdint.h>
  17. #include <cstdio>
  18. #include <vector>
  19. #include <iostream>
  20. #include <sstream>
  21. #ifdef HAVE_BOOST_SYSTEM
  22. #include <boost/bind.hpp>
  23. #include <boost/function.hpp>
  24. #include <boost/asio.hpp>
  25. #endif
  26. #include <boost/foreach.hpp>
  27. #include <exceptions/exceptions.h>
  28. #include <cc/data.h>
  29. #include "fake_session.h"
  30. using namespace std;
  31. using namespace isc::cc;
  32. using namespace isc::data;
  33. #ifdef HAVE_BOOST_SYSTEM
  34. // some of the boost::asio names conflict with socket API system calls
  35. // (e.g. write(2)) so we don't import the entire boost::asio namespace.
  36. using boost::asio::io_service;
  37. using boost::asio::ip::tcp;
  38. #endif
  39. #include <sys/types.h>
  40. #include <sys/socket.h>
  41. #include <netinet/in.h>
  42. isc::data::ElementPtr initial_messages;
  43. isc::data::ElementPtr subscriptions;
  44. isc::data::ElementPtr msg_queue;
  45. // ok i want these in cc/data
  46. static bool
  47. listContains(ElementPtr list, ElementPtr el)
  48. {
  49. if (!list) {
  50. return false;
  51. }
  52. BOOST_FOREACH(ElementPtr l_el, list->listValue()) {
  53. if (l_el == el) {
  54. return true;
  55. }
  56. }
  57. return false;
  58. }
  59. static void
  60. listRemove(ElementPtr list, ElementPtr el) {
  61. int i = -1;
  62. BOOST_FOREACH(ElementPtr s_el, list->listValue()) {
  63. if (el == s_el) {
  64. i = 0;
  65. }
  66. i++;
  67. }
  68. if (i >= 0) {
  69. list->remove(i);
  70. }
  71. }
  72. // endwant
  73. ElementPtr
  74. getFirstMessage(std::string& group, std::string& to)
  75. {
  76. ElementPtr el;
  77. if (msg_queue && msg_queue->size() > 0) {
  78. el = msg_queue->get(0);
  79. msg_queue->remove(0);
  80. group = el->get(0)->stringValue();
  81. to = el->get(1)->stringValue();
  82. return el->get(2);
  83. } else {
  84. group = "";
  85. to = "";
  86. return ElementPtr();
  87. }
  88. }
  89. void
  90. addMessage(ElementPtr msg, const std::string& group, const std::string& to)
  91. {
  92. ElementPtr m_el = Element::createFromString("[]");
  93. m_el->add(Element::create(group));
  94. m_el->add(Element::create(to));
  95. m_el->add(msg);
  96. if (!msg_queue) {
  97. msg_queue = Element::createFromString("[]");
  98. }
  99. msg_queue->add(m_el);
  100. }
  101. bool
  102. haveSubscription(const std::string& group, const std::string& instance)
  103. {
  104. if (!subscriptions) {
  105. return false;
  106. }
  107. ElementPtr s1 = Element::createFromString("[]");
  108. ElementPtr s2 = Element::createFromString("[]");
  109. s1->add(Element::create(group));
  110. s1->add(Element::create(instance));
  111. s2->add(Element::create(group));
  112. s2->add(Element::create("*"));
  113. bool result = (listContains(subscriptions, s1) || listContains(subscriptions, s2));
  114. return result;
  115. }
  116. bool
  117. haveSubscription(const ElementPtr group, const ElementPtr instance)
  118. {
  119. return haveSubscription(group->stringValue(), instance->stringValue());
  120. }
  121. namespace isc {
  122. namespace cc {
  123. Session::Session()
  124. {
  125. }
  126. #ifdef HAVE_BOOST_SYSTEM
  127. Session::Session(io_service& io_service UNUSED_PARAM)
  128. {
  129. }
  130. #endif
  131. Session::~Session() {
  132. }
  133. bool
  134. Session::connect() {
  135. return true;
  136. }
  137. void
  138. Session::disconnect() {
  139. }
  140. int
  141. Session::getSocket() const {
  142. return 1;
  143. }
  144. void
  145. Session::startRead(boost::function<void()> read_callback UNUSED_PARAM) {
  146. }
  147. void
  148. Session::establish() {
  149. }
  150. //
  151. // Convert to wire format and send this on the TCP stream with its length prefix
  152. //
  153. void
  154. Session::sendmsg(ElementPtr& msg) {
  155. //cout << "[XX] client sends message: " << msg << endl;
  156. // err, to where?
  157. addMessage(msg, "*", "*");
  158. }
  159. void
  160. Session::sendmsg(ElementPtr& env, ElementPtr& msg) {
  161. //cout << "[XX] client sends message: " << msg << endl;
  162. //cout << "[XX] env: " << env << endl;
  163. addMessage(msg, env->get("group")->stringValue(), env->get("to")->stringValue());
  164. }
  165. bool
  166. Session::recvmsg(ElementPtr& msg, bool nonblock UNUSED_PARAM, int seq UNUSED_PARAM) {
  167. //cout << "[XX] client asks for message " << endl;
  168. if (initial_messages &&
  169. initial_messages->getType() == Element::list &&
  170. initial_messages->size() > 0) {
  171. msg = initial_messages->get(0);
  172. initial_messages->remove(0);
  173. } else {
  174. msg = ElementPtr();
  175. }
  176. return (true);
  177. }
  178. bool
  179. Session::recvmsg(ElementPtr& env, ElementPtr& msg, bool nonblock UNUSED_PARAM, int seq UNUSED_PARAM) {
  180. //cout << "[XX] client asks for message and env" << endl;
  181. env = ElementPtr();
  182. if (initial_messages &&
  183. initial_messages->getType() == Element::list &&
  184. initial_messages->size() > 0) {
  185. // do we need initial message to have env[group] and [to] too?
  186. msg = initial_messages->get(0);
  187. initial_messages->remove(0);
  188. return true;
  189. } else if (msg_queue) {
  190. BOOST_FOREACH(ElementPtr c_m, msg_queue->listValue()) {
  191. ElementPtr to_remove = ElementPtr();
  192. if (haveSubscription(c_m->get(0), c_m->get(1))) {
  193. env = Element::createFromString("{}");
  194. env->set("group", c_m->get(0));
  195. env->set("to", c_m->get(1));
  196. msg = c_m->get(2);
  197. to_remove = c_m;
  198. }
  199. if (to_remove) {
  200. listRemove(msg_queue, to_remove);
  201. return true;
  202. }
  203. }
  204. }
  205. msg = ElementPtr();
  206. env = ElementPtr();
  207. return false;
  208. }
  209. void
  210. Session::subscribe(std::string group, std::string instance) {
  211. //cout << "[XX] client subscribes to " << group << " . " << instance << endl;
  212. ElementPtr s_el = Element::createFromString("[]");
  213. s_el->add(Element::create(group));
  214. s_el->add(Element::create(instance));
  215. if (!subscriptions) {
  216. subscriptions = Element::createFromString("[]");
  217. }
  218. subscriptions->add(s_el);
  219. }
  220. void
  221. Session::unsubscribe(std::string group, std::string instance) {
  222. //cout << "[XX] client unsubscribes from " << group << " . " << instance << endl;
  223. ElementPtr s_el = Element::createFromString("[]");
  224. s_el->add(Element::create(group));
  225. s_el->add(Element::create(instance));
  226. if (!subscriptions) {
  227. return;
  228. }
  229. listRemove(subscriptions, s_el);
  230. }
  231. unsigned int
  232. Session::group_sendmsg(ElementPtr msg, std::string group,
  233. std::string to, std::string instance UNUSED_PARAM)
  234. {
  235. //cout << "[XX] client sends message: " << msg << endl;
  236. //cout << "[XX] to: " << group << " . " << instance << "." << to << endl;
  237. addMessage(msg, group, to);
  238. return 1;
  239. }
  240. bool
  241. Session::group_recvmsg(ElementPtr& envelope, ElementPtr& msg,
  242. bool nonblock, int seq)
  243. {
  244. return (recvmsg(envelope, msg, nonblock, seq));
  245. }
  246. unsigned int
  247. Session::reply(ElementPtr& envelope, ElementPtr& newmsg) {
  248. //cout << "[XX] client sends reply: " << newmsg << endl;
  249. //cout << "[XX] env: " << envelope << endl;
  250. addMessage(newmsg, envelope->get("group")->stringValue(), envelope->get("to")->stringValue());
  251. return 1;
  252. }
  253. bool
  254. Session::hasQueuedMsgs() {
  255. return false;
  256. }
  257. }
  258. }