modelverse.xml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <class name="Modelverse">
  2. <relationships>
  3. <association name="http_client" class="HTTPClient" min="2" max="2"/>
  4. </relationships>
  5. <method name="load_action">
  6. <parameter name="context"/>
  7. <body>
  8. action = self.actions[None].pop(0)
  9. self.parameters = action["parameters"]
  10. self.current_ID = action["ID"]
  11. </body>
  12. </method>
  13. <method name="expect_response">
  14. <parameter name="expected"/>
  15. <parameter name="pop" default="False"/>
  16. <body>
  17. if self.responses and self.responses[0] == expected:
  18. if pop:
  19. del self.responses[0]
  20. return True
  21. else:
  22. return False
  23. </body>
  24. </method>
  25. <method name="expect_response_partial">
  26. <parameter name="expected"/>
  27. <parameter name="pop" default="False"/>
  28. <body>
  29. print("Checking for partial resonse, got: " + str(self.responses))
  30. if self.responses and self.responses.startswith(expected):
  31. if pop:
  32. del self.responses[0]
  33. return True
  34. else:
  35. return False
  36. </body>
  37. </method>
  38. <method name="expect_action">
  39. <parameter name="context"/>
  40. <parameter name="expected"/>
  41. <body>
  42. return self.actions[context] and self.actions[context][0]["name"] == expected
  43. </body>
  44. </method>
  45. <constructor>
  46. <body>
  47. self.actions = {None: []}
  48. self.responses = []
  49. self.http_clients = []
  50. </body>
  51. </constructor>
  52. <scxml initial="init">
  53. <state id="init">
  54. <onentry>
  55. <raise scope="cd" event="create_instance">
  56. <parameter expr="'http_client'"/>
  57. <parameter expr="'HTTPClient'"/>
  58. </raise>
  59. <raise scope="cd" event="create_instance">
  60. <parameter expr="'http_client'"/>
  61. <parameter expr="'HTTPClient'"/>
  62. </raise>
  63. </onentry>
  64. <transition event="instance_created" target=".">
  65. <parameter name="instance"/>
  66. <script>
  67. self.http_clients.append(instance)
  68. </script>
  69. <raise scope="cd" event="start_instance">
  70. <parameter expr="instance"/>
  71. </raise>
  72. </transition>
  73. <transition cond="len(self.http_clients) == 2" target="../waiting"/>
  74. </state>
  75. <state id="waiting">
  76. <transition event="http_client_initialized" target="../initialized"/>
  77. </state>
  78. <parallel id="initialized">
  79. <onentry>
  80. <raise scope="output" port="ready" event="ready"/>
  81. </onentry>
  82. <state id="http_mapper" initial="init">
  83. <state id="init">
  84. <transition event="request" cond="isinstance(value, type([]))" target=".">
  85. <parameter name="value"/>
  86. <raise event="HTTP_input" target="self.http_clients[0]">
  87. <parameter expr='urllib.urlencode({"op": "set_input", "data": json.dumps(value), "taskname": self.taskname})'/>
  88. <parameter expr='None'/>
  89. </raise>
  90. <script>
  91. print("Sent out value: " + str(urllib.urlencode({"op": "set_input", "data": json.dumps(value), "taskname": self.taskname})))
  92. </script>
  93. </transition>
  94. <transition event="request" cond="not isinstance(value, type([]))" target=".">
  95. <parameter name="value"/>
  96. <raise event="HTTP_input" target="self.http_clients[0]">
  97. <parameter expr='urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": self.taskname})'/>
  98. <parameter expr='None'/>
  99. </raise>
  100. <script>
  101. print("Sent out value: " + str(urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": self.taskname})))
  102. </script>
  103. </transition>
  104. <transition event="request_raw" target=".">
  105. <parameter name="value"/>
  106. <parameter name="taskname"/>
  107. <parameter name="http_client"/>
  108. <raise event="HTTP_input" target="self.http_clients[http_client]">
  109. <parameter expr='urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": taskname})'/>
  110. <parameter expr='"parent"'/>
  111. </raise>
  112. </transition>
  113. <transition event="HTTP_output" target=".">
  114. <parameter name="data"/>
  115. <raise event="HTTP_input" target="self.http_clients[1]">
  116. <parameter expr='urllib.urlencode({"op": "get_output", "taskname": self.taskname})'/>
  117. <parameter expr='"parent"'/>
  118. </raise>
  119. <script>
  120. print("Got output " + str(data))
  121. self.responses.append(json.loads(data))
  122. </script>
  123. </transition>
  124. </state>
  125. </state>
  126. <state id="behaviour" initial="wait_for_action">
  127. <state id="connecting" initial="connect_http_client">
  128. <onentry>
  129. <script>
  130. self.address, self.timeout = self.parameters
  131. self.address = self.address.rsplit(":", 1)
  132. self.address = (self.address[0], int(self.address[1]))
  133. self.i = 0
  134. self.taskname = str(uuid.uuid4())
  135. </script>
  136. </onentry>
  137. <state id="connect_http_client">
  138. <transition cond="self.i &lt; 2" target="../waiting_http_client">
  139. <raise scope="narrow" target="self.http_clients[self.i]" event="connect">
  140. <parameter expr="self.address"/>
  141. <parameter expr="self.timeout"/>
  142. </raise>
  143. </transition>
  144. <transition cond="self.i == 2" target="../../wait_for_action/connected">
  145. <!-- Start polling for output -->
  146. <raise event="HTTP_input" target="self.http_clients[1]">
  147. <parameter expr='urllib.urlencode({"op": "get_output", "taskname": self.taskname})'/>
  148. <parameter expr='"parent"'/>
  149. </raise>
  150. <!-- Sent out completion -->
  151. <raise event="result">
  152. <parameter expr="[]"/>
  153. </raise>
  154. </transition>
  155. </state>
  156. <state id="waiting_http_client">
  157. <transition event="http_client_ready" target="../wait_for_taskname_ack">
  158. <!-- Request the task to be created -->
  159. <raise event="request_raw">
  160. <parameter expr="self.taskname"/>
  161. <parameter expr="'task_manager'"/>
  162. <parameter expr="self.i"/>
  163. </raise>
  164. <script>
  165. self.i += 1
  166. </script>
  167. </transition>
  168. <transition event="http_client_timeout" target="../../wait_for_action/disconnected">
  169. <raise scope="broad" event="exception">
  170. <parameter expr="self.current_ID"/>
  171. <parameter expr="'Connection timeout'"/>
  172. </raise>
  173. </transition>
  174. </state>
  175. <state id="wait_for_taskname_ack">
  176. <transition cond="self.expect_response('OK', pop=True)" target="../connect_http_client"/>
  177. </state>
  178. </state>
  179. <state id="logging_in" initial="wait_prompt_1">
  180. <state id="wait_prompt_1">
  181. <transition cond="self.expect_response('Log on as which user?', pop=True)" target="../wait_prompt_2">
  182. <raise event="request">
  183. <parameter expr="self.parameters[0]"/>
  184. </raise>
  185. </transition>
  186. </state>
  187. <state id="wait_prompt_2">
  188. <transition cond="self.expect_response('Password for existing user?', pop=True)" target="../wait_prompt_existing">
  189. <raise event="request">
  190. <parameter expr="self.parameters[1]"/>
  191. </raise>
  192. </transition>
  193. <transition cond="self.expect_response('This is a new user: please give password!', pop=True)" target="../wait_prompt_existing">
  194. <raise event="request">
  195. <parameter expr="self.parameters[1]"/>
  196. </raise>
  197. </transition>
  198. </state>
  199. <state id="wait_prompt_existing">
  200. <transition cond="self.expect_response('Welcome to the Model Management Interface v2.0!', pop=True)" target="../login_ok"/>
  201. <transition cond="self.expect_response('Wrong password!', pop=True)" target="../../wait_for_action/connected">
  202. <raise event="exception">
  203. <parameter expr="{'name': 'PermissionDenied'}"/>
  204. </raise>
  205. </transition>
  206. </state>
  207. <state id="login_ok">
  208. <transition cond="self.expect_response('Use the \'help\' command for a list of possible commands', pop=True)" target="../../wait_for_action/megamodelling">
  209. <raise event="request">
  210. <parameter expr="'quiet'"/>
  211. </raise>
  212. <raise event="result">
  213. <parameter expr="[]"/>
  214. </raise>
  215. </transition>
  216. </state>
  217. </state>
  218. <state id="model_list">
  219. <onentry>
  220. <raise event="request">
  221. <parameter expr="'model_list'"/>
  222. </raise>
  223. <script>
  224. print("Raised model_list!")
  225. </script>
  226. </onentry>
  227. <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../wait_for_action/history">
  228. <raise event="result">
  229. <parameter expr="self.split_response('Success: ')"/>
  230. </raise>
  231. </transition>
  232. </state>
  233. <state id="wait_for_action" initial="disconnected">
  234. <state id="disconnected">
  235. <transition cond="self.expect_action(None, 'init')" target="../../connecting">
  236. <script>
  237. self.load_action(None)
  238. </script>
  239. </transition>
  240. </state>
  241. <state id="connected">
  242. <transition cond="self.expect_action(None, 'login')" target="../../logging_in">
  243. <script>
  244. self.load_action(None)
  245. </script>
  246. </transition>
  247. </state>
  248. <state id="megamodelling">
  249. <transition cond="self.expect_action(None, 'model_list')" target="../../model_list">
  250. <script>
  251. self.load_action(None)
  252. </script>
  253. </transition>
  254. </state>
  255. <state id="modelling" initial="manual">
  256. <state id="manual">
  257. </state>
  258. <state id="scripted">
  259. </state>
  260. </state>
  261. <history id="history" type="deep"/>
  262. </state>
  263. </state>
  264. <state id="queue">
  265. <state id="queue">
  266. <transition port="action_in" event="action" target=".">
  267. <parameter name="action_name"/>
  268. <parameter name="ID"/>
  269. <parameter name="context_ID"/>
  270. <parameter name="parameters"/>
  271. <script>
  272. self.actions[context_ID].append({"name": action_name, "ID": ID, "parameters": parameters})
  273. </script>
  274. </transition>
  275. <transition event="result" target=".">
  276. <parameter name="parameters"/>
  277. <raise scope="output" event="result" port="action_out">
  278. <parameter expr="self.current_ID"/>
  279. <parameter expr="parameters"/>
  280. </raise>
  281. </transition>
  282. <transition event="exception" target=".">
  283. <parameter name="parameters"/>
  284. <raise scope="output" event="exception" port="action_out">
  285. <parameter expr="self.current_ID"/>
  286. <parameter expr="parameters"/>
  287. </raise>
  288. </transition>
  289. <transition port="input_in" event="input" target=".">
  290. <parameter name="value"/>
  291. <parameter name="context_ID"/>
  292. <script>
  293. self.inputs[context_ID].append(value)
  294. </script>
  295. </transition>
  296. </state>
  297. </state>
  298. </parallel>
  299. </scxml>
  300. </class>