|
@@ -0,0 +1,600 @@
|
|
|
+"""
|
|
|
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
|
|
|
+
|
|
|
+Date: Wed Aug 10 09:45:50 2016
|
|
|
+
|
|
|
+Model author: Yentl Van Tendeloo
|
|
|
+Model name: HTTP Server
|
|
|
+Model description:
|
|
|
+Example HTTP echo server.
|
|
|
+"""
|
|
|
+
|
|
|
+from sccd.runtime.statecharts_core import *
|
|
|
+import time
|
|
|
+import os
|
|
|
+import urllib
|
|
|
+import sys
|
|
|
+import json
|
|
|
+
|
|
|
+import sys
|
|
|
+
|
|
|
+# package "HTTP Server"
|
|
|
+
|
|
|
+class Echo(RuntimeClassBase):
|
|
|
+ def __init__(self, controller, params):
|
|
|
+ RuntimeClassBase.__init__(self, controller)
|
|
|
+
|
|
|
+ self.semantics.big_step_maximality = StatechartSemantics.TakeMany
|
|
|
+ self.semantics.internal_event_lifeline = StatechartSemantics.Queue
|
|
|
+ self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
|
|
|
+ self.semantics.priority = StatechartSemantics.SourceParent
|
|
|
+ self.semantics.concurrency = StatechartSemantics.Single
|
|
|
+
|
|
|
+ # build Statechart structure
|
|
|
+ self.build_statechart_structure()
|
|
|
+
|
|
|
+ # call user defined constructor
|
|
|
+ Echo.user_defined_constructor(self, params)
|
|
|
+
|
|
|
+ def user_defined_constructor(self, params):
|
|
|
+ self.source = None
|
|
|
+
|
|
|
+ def user_defined_destructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ # builds Statechart structure
|
|
|
+ def build_statechart_structure(self):
|
|
|
+
|
|
|
+ # state <root>
|
|
|
+ self.states[""] = State(0, self)
|
|
|
+
|
|
|
+ # state /init_server
|
|
|
+ self.states["/init_server"] = State(1, self)
|
|
|
+ self.states["/init_server"].setEnter(self._init_server_enter)
|
|
|
+
|
|
|
+ # state /wait_for_requests
|
|
|
+ self.states["/wait_for_requests"] = State(2, self)
|
|
|
+
|
|
|
+ # state /wait_for_requests/wait
|
|
|
+ self.states["/wait_for_requests/wait"] = State(3, self)
|
|
|
+
|
|
|
+ # add children
|
|
|
+ self.states[""].addChild(self.states["/init_server"])
|
|
|
+ self.states[""].addChild(self.states["/wait_for_requests"])
|
|
|
+ self.states["/wait_for_requests"].addChild(self.states["/wait_for_requests/wait"])
|
|
|
+ self.states[""].fixTree()
|
|
|
+ self.states[""].default_state = self.states["/init_server"]
|
|
|
+ self.states["/wait_for_requests"].default_state = self.states["/wait_for_requests/wait"]
|
|
|
+
|
|
|
+ # transition /init_server
|
|
|
+ _init_server_0 = Transition(self, self.states["/init_server"], [self.states["/wait_for_requests"]])
|
|
|
+ _init_server_0.setAction(self._init_server_0_exec)
|
|
|
+ _init_server_0.setTrigger(Event("instance_created", None))
|
|
|
+ self.states["/init_server"].addTransition(_init_server_0)
|
|
|
+
|
|
|
+ # transition /wait_for_requests/wait
|
|
|
+ _wait_for_requests_wait_0 = Transition(self, self.states["/wait_for_requests/wait"], [self.states["/wait_for_requests/wait"]])
|
|
|
+ _wait_for_requests_wait_0.setAction(self._wait_for_requests_wait_0_exec)
|
|
|
+ _wait_for_requests_wait_0.setTrigger(Event("HTTP_output", None))
|
|
|
+ self.states["/wait_for_requests/wait"].addTransition(_wait_for_requests_wait_0)
|
|
|
+
|
|
|
+ def _init_server_enter(self):
|
|
|
+ self.big_step.outputEventOM(Event("create_instance", None, [self, 'to_server', 'Server', '', 8080]))
|
|
|
+
|
|
|
+ def _init_server_0_exec(self, parameters):
|
|
|
+ instancename = parameters[0]
|
|
|
+ self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
|
|
|
+
|
|
|
+ def _wait_for_requests_wait_0_exec(self, parameters):
|
|
|
+ source = parameters[0]
|
|
|
+ data = parameters[1]
|
|
|
+ print("Got input: " + str(data))
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'to_server/%s' % source, Event("HTTP_input", None, [data])]))
|
|
|
+
|
|
|
+ def initializeStatechart(self):
|
|
|
+ # enter default state
|
|
|
+ self.default_targets = self.states["/init_server"].getEffectiveTargetStates()
|
|
|
+ RuntimeClassBase.initializeStatechart(self)
|
|
|
+
|
|
|
+class Server(RuntimeClassBase):
|
|
|
+ def __init__(self, controller, address, port):
|
|
|
+ RuntimeClassBase.__init__(self, controller)
|
|
|
+
|
|
|
+ self.semantics.big_step_maximality = StatechartSemantics.TakeMany
|
|
|
+ self.semantics.internal_event_lifeline = StatechartSemantics.Queue
|
|
|
+ self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
|
|
|
+ self.semantics.priority = StatechartSemantics.SourceParent
|
|
|
+ self.semantics.concurrency = StatechartSemantics.Single
|
|
|
+
|
|
|
+ # build Statechart structure
|
|
|
+ self.build_statechart_structure()
|
|
|
+
|
|
|
+ # call user defined constructor
|
|
|
+ Server.user_defined_constructor(self, address, port)
|
|
|
+
|
|
|
+ def user_defined_constructor(self, address, port):
|
|
|
+ self.socket = None
|
|
|
+ self.address = address
|
|
|
+ self.port = port
|
|
|
+
|
|
|
+ def user_defined_destructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ # builds Statechart structure
|
|
|
+ def build_statechart_structure(self):
|
|
|
+
|
|
|
+ # state <root>
|
|
|
+ self.states[""] = State(0, self)
|
|
|
+
|
|
|
+ # state /main
|
|
|
+ self.states["/main"] = ParallelState(1, self)
|
|
|
+
|
|
|
+ # state /main/forward
|
|
|
+ self.states["/main/forward"] = State(2, self)
|
|
|
+
|
|
|
+ # state /main/forward/forward
|
|
|
+ self.states["/main/forward/forward"] = State(3, self)
|
|
|
+
|
|
|
+ # state /main/server
|
|
|
+ self.states["/main/server"] = State(4, self)
|
|
|
+
|
|
|
+ # state /main/server/init
|
|
|
+ self.states["/main/server/init"] = State(5, self)
|
|
|
+ self.states["/main/server/init"].setEnter(self._main_server_init_enter)
|
|
|
+
|
|
|
+ # state /main/server/binding
|
|
|
+ self.states["/main/server/binding"] = State(6, self)
|
|
|
+ self.states["/main/server/binding"].setEnter(self._main_server_binding_enter)
|
|
|
+
|
|
|
+ # state /main/server/listening
|
|
|
+ self.states["/main/server/listening"] = State(7, self)
|
|
|
+ self.states["/main/server/listening"].setEnter(self._main_server_listening_enter)
|
|
|
+
|
|
|
+ # state /main/server/accepting
|
|
|
+ self.states["/main/server/accepting"] = State(8, self)
|
|
|
+ self.states["/main/server/accepting"].setEnter(self._main_server_accepting_enter)
|
|
|
+ self.states["/main/server/accepting"].setExit(self._main_server_accepting_exit)
|
|
|
+
|
|
|
+ # state /main/close_socket
|
|
|
+ self.states["/main/close_socket"] = State(9, self)
|
|
|
+
|
|
|
+ # state /main/close_socket/close
|
|
|
+ self.states["/main/close_socket/close"] = State(10, self)
|
|
|
+
|
|
|
+ # add children
|
|
|
+ self.states[""].addChild(self.states["/main"])
|
|
|
+ self.states["/main"].addChild(self.states["/main/forward"])
|
|
|
+ self.states["/main"].addChild(self.states["/main/server"])
|
|
|
+ self.states["/main"].addChild(self.states["/main/close_socket"])
|
|
|
+ self.states["/main/forward"].addChild(self.states["/main/forward/forward"])
|
|
|
+ self.states["/main/server"].addChild(self.states["/main/server/init"])
|
|
|
+ self.states["/main/server"].addChild(self.states["/main/server/binding"])
|
|
|
+ self.states["/main/server"].addChild(self.states["/main/server/listening"])
|
|
|
+ self.states["/main/server"].addChild(self.states["/main/server/accepting"])
|
|
|
+ self.states["/main/close_socket"].addChild(self.states["/main/close_socket/close"])
|
|
|
+ self.states[""].fixTree()
|
|
|
+ self.states[""].default_state = self.states["/main"]
|
|
|
+ self.states["/main/forward"].default_state = self.states["/main/forward/forward"]
|
|
|
+ self.states["/main/server"].default_state = self.states["/main/server/init"]
|
|
|
+ self.states["/main/close_socket"].default_state = self.states["/main/close_socket/close"]
|
|
|
+
|
|
|
+ # transition /main/forward/forward
|
|
|
+ _main_forward_forward_0 = Transition(self, self.states["/main/forward/forward"], [self.states["/main/forward/forward"]])
|
|
|
+ _main_forward_forward_0.setAction(self._main_forward_forward_0_exec)
|
|
|
+ _main_forward_forward_0.setTrigger(Event("HTTP_output", None))
|
|
|
+ self.states["/main/forward/forward"].addTransition(_main_forward_forward_0)
|
|
|
+
|
|
|
+ # transition /main/server/init
|
|
|
+ _main_server_init_0 = Transition(self, self.states["/main/server/init"], [self.states["/main/server/binding"]])
|
|
|
+ _main_server_init_0.setAction(self._main_server_init_0_exec)
|
|
|
+ _main_server_init_0.setTrigger(Event("created_socket", "socket_in"))
|
|
|
+ self.states["/main/server/init"].addTransition(_main_server_init_0)
|
|
|
+
|
|
|
+ # transition /main/server/binding
|
|
|
+ _main_server_binding_0 = Transition(self, self.states["/main/server/binding"], [self.states["/main/server/listening"]])
|
|
|
+ _main_server_binding_0.setTrigger(Event("bound_socket", "socket_in"))
|
|
|
+ _main_server_binding_0.setGuard(self._main_server_binding_0_guard)
|
|
|
+ self.states["/main/server/binding"].addTransition(_main_server_binding_0)
|
|
|
+
|
|
|
+ # transition /main/server/listening
|
|
|
+ _main_server_listening_0 = Transition(self, self.states["/main/server/listening"], [self.states["/main/server/accepting"]])
|
|
|
+ _main_server_listening_0.setAction(self._main_server_listening_0_exec)
|
|
|
+ _main_server_listening_0.setTrigger(Event("listened_socket", "socket_in"))
|
|
|
+ _main_server_listening_0.setGuard(self._main_server_listening_0_guard)
|
|
|
+ self.states["/main/server/listening"].addTransition(_main_server_listening_0)
|
|
|
+
|
|
|
+ # transition /main/server/accepting
|
|
|
+ _main_server_accepting_0 = Transition(self, self.states["/main/server/accepting"], [self.states["/main/server/accepting"]])
|
|
|
+ _main_server_accepting_0.setAction(self._main_server_accepting_0_exec)
|
|
|
+ _main_server_accepting_0.setTrigger(Event("accepted_socket", "socket_in"))
|
|
|
+ self.states["/main/server/accepting"].addTransition(_main_server_accepting_0)
|
|
|
+ _main_server_accepting_1 = Transition(self, self.states["/main/server/accepting"], [self.states["/main/server/accepting"]])
|
|
|
+ _main_server_accepting_1.setAction(self._main_server_accepting_1_exec)
|
|
|
+ _main_server_accepting_1.setTrigger(Event("instance_created", None))
|
|
|
+ self.states["/main/server/accepting"].addTransition(_main_server_accepting_1)
|
|
|
+ _main_server_accepting_2 = Transition(self, self.states["/main/server/accepting"], [self.states["/main/server/accepting"]])
|
|
|
+ _main_server_accepting_2.setTrigger(Event("_0after"))
|
|
|
+ self.states["/main/server/accepting"].addTransition(_main_server_accepting_2)
|
|
|
+
|
|
|
+ # transition /main/close_socket/close
|
|
|
+ _main_close_socket_close_0 = Transition(self, self.states["/main/close_socket/close"], [self.states["/main/close_socket/close"]])
|
|
|
+ _main_close_socket_close_0.setAction(self._main_close_socket_close_0_exec)
|
|
|
+ _main_close_socket_close_0.setTrigger(Event("close_socket", None))
|
|
|
+ self.states["/main/close_socket/close"].addTransition(_main_close_socket_close_0)
|
|
|
+
|
|
|
+ def _main_server_init_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_socket", "socket_out", []))
|
|
|
+
|
|
|
+ def _main_server_binding_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("bind_socket", "socket_out", [self.socket, (self.address, self.port)]))
|
|
|
+
|
|
|
+ def _main_server_listening_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("listen_socket", "socket_out", [self.socket]))
|
|
|
+
|
|
|
+ def _main_server_accepting_enter(self):
|
|
|
+ self.addTimer(0, 1.0)
|
|
|
+
|
|
|
+ def _main_server_accepting_exit(self):
|
|
|
+ self.removeTimer(0)
|
|
|
+
|
|
|
+ def _main_forward_forward_0_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ data = parameters[1]
|
|
|
+ print("Forward")
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("HTTP_output", None, [association_name, data])]))
|
|
|
+
|
|
|
+ def _main_server_init_0_exec(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ self.socket = socket
|
|
|
+
|
|
|
+ def _main_server_binding_0_guard(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ return self.socket == socket
|
|
|
+
|
|
|
+ def _main_server_listening_0_exec(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ self.big_step.outputEvent(Event("accept_socket", "socket_out", [self.socket]))
|
|
|
+
|
|
|
+ def _main_server_listening_0_guard(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ return self.socket == socket
|
|
|
+
|
|
|
+ def _main_server_accepting_0_exec(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ connected_socket = parameters[1]
|
|
|
+ self.big_step.outputEventOM(Event("create_instance", None, [self, 'sockets', 'Socket', connected_socket]))
|
|
|
+ self.big_step.outputEvent(Event("accept_socket", "socket_out", [self.socket]))
|
|
|
+
|
|
|
+ def _main_server_accepting_1_exec(self, parameters):
|
|
|
+ instancename = parameters[0]
|
|
|
+ self.big_step.outputEventOM(Event("start_instance", None, [self, instancename]))
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, instancename, Event("set_association_name", None, [instancename])]))
|
|
|
+
|
|
|
+ def _main_close_socket_close_0_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
|
|
|
+
|
|
|
+ def initializeStatechart(self):
|
|
|
+ # enter default state
|
|
|
+ self.default_targets = self.states["/main"].getEffectiveTargetStates()
|
|
|
+ RuntimeClassBase.initializeStatechart(self)
|
|
|
+
|
|
|
+class Socket(RuntimeClassBase):
|
|
|
+ def __init__(self, controller, my_socket):
|
|
|
+ RuntimeClassBase.__init__(self, controller)
|
|
|
+
|
|
|
+ self.semantics.big_step_maximality = StatechartSemantics.TakeMany
|
|
|
+ self.semantics.internal_event_lifeline = StatechartSemantics.Queue
|
|
|
+ self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
|
|
|
+ self.semantics.priority = StatechartSemantics.SourceParent
|
|
|
+ self.semantics.concurrency = StatechartSemantics.Single
|
|
|
+
|
|
|
+ # build Statechart structure
|
|
|
+ self.build_statechart_structure()
|
|
|
+
|
|
|
+ # call user defined constructor
|
|
|
+ Socket.user_defined_constructor(self, my_socket)
|
|
|
+
|
|
|
+ def user_defined_constructor(self, my_socket):
|
|
|
+ self.socket = my_socket
|
|
|
+ self.received_data = ""
|
|
|
+ self.send_data = ""
|
|
|
+ self.closed = False
|
|
|
+ self.association_name = None
|
|
|
+
|
|
|
+ def user_defined_destructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ # builds Statechart structure
|
|
|
+ def build_statechart_structure(self):
|
|
|
+
|
|
|
+ # state <root>
|
|
|
+ self.states[""] = State(0, self)
|
|
|
+
|
|
|
+ # state /init
|
|
|
+ self.states["/init"] = State(1, self)
|
|
|
+
|
|
|
+ # state /connected
|
|
|
+ self.states["/connected"] = ParallelState(2, self)
|
|
|
+
|
|
|
+ # state /connected/listening
|
|
|
+ self.states["/connected/listening"] = State(3, self)
|
|
|
+
|
|
|
+ # state /connected/listening/listen
|
|
|
+ self.states["/connected/listening/listen"] = State(4, self)
|
|
|
+ self.states["/connected/listening/listen"].setEnter(self._connected_listening_listen_enter)
|
|
|
+
|
|
|
+ # state /connected/listening/closed
|
|
|
+ self.states["/connected/listening/closed"] = State(5, self)
|
|
|
+ self.states["/connected/listening/closed"].setEnter(self._connected_listening_closed_enter)
|
|
|
+
|
|
|
+ # state /connected/sending
|
|
|
+ self.states["/connected/sending"] = State(6, self)
|
|
|
+
|
|
|
+ # state /connected/sending/waiting_for_data
|
|
|
+ self.states["/connected/sending/waiting_for_data"] = State(7, self)
|
|
|
+
|
|
|
+ # state /connected/sending/transferring
|
|
|
+ self.states["/connected/sending/transferring"] = State(8, self)
|
|
|
+
|
|
|
+ # state /connected/queueing
|
|
|
+ self.states["/connected/queueing"] = State(9, self)
|
|
|
+
|
|
|
+ # state /connected/queueing/queueing
|
|
|
+ self.states["/connected/queueing/queueing"] = State(10, self)
|
|
|
+
|
|
|
+ # state /connected/parsing
|
|
|
+ self.states["/connected/parsing"] = State(11, self)
|
|
|
+
|
|
|
+ # state /connected/parsing/wait_for_header
|
|
|
+ self.states["/connected/parsing/wait_for_header"] = State(12, self)
|
|
|
+
|
|
|
+ # state /connected/parsing/closing
|
|
|
+ self.states["/connected/parsing/closing"] = State(13, self)
|
|
|
+ self.states["/connected/parsing/closing"].setEnter(self._connected_parsing_closing_enter)
|
|
|
+ self.states["/connected/parsing/closing"].setExit(self._connected_parsing_closing_exit)
|
|
|
+
|
|
|
+ # state /connected/parsing/wait_for_payload
|
|
|
+ self.states["/connected/parsing/wait_for_payload"] = State(14, self)
|
|
|
+
|
|
|
+ # state /close
|
|
|
+ self.states["/close"] = State(15, self)
|
|
|
+ self.states["/close"].setEnter(self._close_enter)
|
|
|
+
|
|
|
+ # add children
|
|
|
+ self.states[""].addChild(self.states["/init"])
|
|
|
+ self.states[""].addChild(self.states["/connected"])
|
|
|
+ self.states[""].addChild(self.states["/close"])
|
|
|
+ self.states["/connected"].addChild(self.states["/connected/listening"])
|
|
|
+ self.states["/connected"].addChild(self.states["/connected/sending"])
|
|
|
+ self.states["/connected"].addChild(self.states["/connected/queueing"])
|
|
|
+ self.states["/connected"].addChild(self.states["/connected/parsing"])
|
|
|
+ self.states["/connected/listening"].addChild(self.states["/connected/listening/listen"])
|
|
|
+ self.states["/connected/listening"].addChild(self.states["/connected/listening/closed"])
|
|
|
+ self.states["/connected/sending"].addChild(self.states["/connected/sending/waiting_for_data"])
|
|
|
+ self.states["/connected/sending"].addChild(self.states["/connected/sending/transferring"])
|
|
|
+ self.states["/connected/queueing"].addChild(self.states["/connected/queueing/queueing"])
|
|
|
+ self.states["/connected/parsing"].addChild(self.states["/connected/parsing/wait_for_header"])
|
|
|
+ self.states["/connected/parsing"].addChild(self.states["/connected/parsing/closing"])
|
|
|
+ self.states["/connected/parsing"].addChild(self.states["/connected/parsing/wait_for_payload"])
|
|
|
+ self.states[""].fixTree()
|
|
|
+ self.states[""].default_state = self.states["/init"]
|
|
|
+ self.states["/connected/listening"].default_state = self.states["/connected/listening/listen"]
|
|
|
+ self.states["/connected/sending"].default_state = self.states["/connected/sending/waiting_for_data"]
|
|
|
+ self.states["/connected/queueing"].default_state = self.states["/connected/queueing/queueing"]
|
|
|
+ self.states["/connected/parsing"].default_state = self.states["/connected/parsing/wait_for_header"]
|
|
|
+
|
|
|
+ # transition /init
|
|
|
+ _init_0 = Transition(self, self.states["/init"], [self.states["/connected"]])
|
|
|
+ _init_0.setAction(self._init_0_exec)
|
|
|
+ _init_0.setTrigger(Event("set_association_name", None))
|
|
|
+ self.states["/init"].addTransition(_init_0)
|
|
|
+
|
|
|
+ # transition /connected/listening/listen
|
|
|
+ _connected_listening_listen_0 = Transition(self, self.states["/connected/listening/listen"], [self.states["/connected/listening/listen"]])
|
|
|
+ _connected_listening_listen_0.setAction(self._connected_listening_listen_0_exec)
|
|
|
+ _connected_listening_listen_0.setTrigger(Event("received_socket", "socket_in"))
|
|
|
+ _connected_listening_listen_0.setGuard(self._connected_listening_listen_0_guard)
|
|
|
+ self.states["/connected/listening/listen"].addTransition(_connected_listening_listen_0)
|
|
|
+ _connected_listening_listen_1 = Transition(self, self.states["/connected/listening/listen"], [self.states["/connected/listening/closed"]])
|
|
|
+ _connected_listening_listen_1.setAction(self._connected_listening_listen_1_exec)
|
|
|
+ _connected_listening_listen_1.setTrigger(Event("received_socket", "socket_in"))
|
|
|
+ _connected_listening_listen_1.setGuard(self._connected_listening_listen_1_guard)
|
|
|
+ self.states["/connected/listening/listen"].addTransition(_connected_listening_listen_1)
|
|
|
+
|
|
|
+ # transition /connected/sending/waiting_for_data
|
|
|
+ _connected_sending_waiting_for_data_0 = Transition(self, self.states["/connected/sending/waiting_for_data"], [self.states["/connected/sending/transferring"]])
|
|
|
+ _connected_sending_waiting_for_data_0.setAction(self._connected_sending_waiting_for_data_0_exec)
|
|
|
+ _connected_sending_waiting_for_data_0.setTrigger(None)
|
|
|
+ _connected_sending_waiting_for_data_0.setGuard(self._connected_sending_waiting_for_data_0_guard)
|
|
|
+ self.states["/connected/sending/waiting_for_data"].addTransition(_connected_sending_waiting_for_data_0)
|
|
|
+
|
|
|
+ # transition /connected/sending/transferring
|
|
|
+ _connected_sending_transferring_0 = Transition(self, self.states["/connected/sending/transferring"], [self.states["/connected/sending/waiting_for_data"]])
|
|
|
+ _connected_sending_transferring_0.setAction(self._connected_sending_transferring_0_exec)
|
|
|
+ _connected_sending_transferring_0.setTrigger(Event("sent_socket", "socket_in"))
|
|
|
+ _connected_sending_transferring_0.setGuard(self._connected_sending_transferring_0_guard)
|
|
|
+ self.states["/connected/sending/transferring"].addTransition(_connected_sending_transferring_0)
|
|
|
+
|
|
|
+ # transition /connected/queueing/queueing
|
|
|
+ _connected_queueing_queueing_0 = Transition(self, self.states["/connected/queueing/queueing"], [self.states["/connected/queueing/queueing"]])
|
|
|
+ _connected_queueing_queueing_0.setAction(self._connected_queueing_queueing_0_exec)
|
|
|
+ _connected_queueing_queueing_0.setTrigger(Event("HTTP_input", None))
|
|
|
+ self.states["/connected/queueing/queueing"].addTransition(_connected_queueing_queueing_0)
|
|
|
+
|
|
|
+ # transition /connected/parsing/wait_for_header
|
|
|
+ _connected_parsing_wait_for_header_0 = Transition(self, self.states["/connected/parsing/wait_for_header"], [self.states["/connected/parsing/wait_for_payload"]])
|
|
|
+ _connected_parsing_wait_for_header_0.setAction(self._connected_parsing_wait_for_header_0_exec)
|
|
|
+ _connected_parsing_wait_for_header_0.setTrigger(None)
|
|
|
+ _connected_parsing_wait_for_header_0.setGuard(self._connected_parsing_wait_for_header_0_guard)
|
|
|
+ self.states["/connected/parsing/wait_for_header"].addTransition(_connected_parsing_wait_for_header_0)
|
|
|
+ _connected_parsing_wait_for_header_1 = Transition(self, self.states["/connected/parsing/wait_for_header"], [self.states["/connected/parsing/closing"]])
|
|
|
+ _connected_parsing_wait_for_header_1.setTrigger(None)
|
|
|
+ _connected_parsing_wait_for_header_1.setGuard(self._connected_parsing_wait_for_header_1_guard)
|
|
|
+ self.states["/connected/parsing/wait_for_header"].addTransition(_connected_parsing_wait_for_header_1)
|
|
|
+
|
|
|
+ # transition /connected/parsing/closing
|
|
|
+ _connected_parsing_closing_0 = Transition(self, self.states["/connected/parsing/closing"], [self.states["/connected/parsing/closing"]])
|
|
|
+ _connected_parsing_closing_0.setAction(self._connected_parsing_closing_0_exec)
|
|
|
+ _connected_parsing_closing_0.setTrigger(Event("_0after"))
|
|
|
+ self.states["/connected/parsing/closing"].addTransition(_connected_parsing_closing_0)
|
|
|
+
|
|
|
+ # transition /connected/parsing/wait_for_payload
|
|
|
+ _connected_parsing_wait_for_payload_0 = Transition(self, self.states["/connected/parsing/wait_for_payload"], [self.states["/connected/parsing/wait_for_header"]])
|
|
|
+ _connected_parsing_wait_for_payload_0.setAction(self._connected_parsing_wait_for_payload_0_exec)
|
|
|
+ _connected_parsing_wait_for_payload_0.setTrigger(None)
|
|
|
+ _connected_parsing_wait_for_payload_0.setGuard(self._connected_parsing_wait_for_payload_0_guard)
|
|
|
+ self.states["/connected/parsing/wait_for_payload"].addTransition(_connected_parsing_wait_for_payload_0)
|
|
|
+
|
|
|
+ # transition /connected
|
|
|
+ _connected_0 = Transition(self, self.states["/connected"], [self.states["/close"]])
|
|
|
+ _connected_0.setTrigger(Event("close", None))
|
|
|
+ self.states["/connected"].addTransition(_connected_0)
|
|
|
+
|
|
|
+ def _connected_listening_listen_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("recv_socket", "socket_out", [self.socket]))
|
|
|
+
|
|
|
+ def _connected_listening_closed_enter(self):
|
|
|
+ self.closed = True
|
|
|
+
|
|
|
+ def _connected_parsing_closing_enter(self):
|
|
|
+ self.addTimer(0, 0.0)
|
|
|
+
|
|
|
+ def _connected_parsing_closing_exit(self):
|
|
|
+ self.removeTimer(0)
|
|
|
+
|
|
|
+ def _close_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("close_socket", "socket_out", [self.socket]))
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("close_socket", None, [self.association_name])]))
|
|
|
+
|
|
|
+ def _init_0_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ self.association_name = association_name
|
|
|
+
|
|
|
+ def _connected_listening_listen_0_exec(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ data = parameters[1]
|
|
|
+ self.received_data += data
|
|
|
+ self.raiseInternalEvent(Event("received_data", None, []))
|
|
|
+
|
|
|
+ def _connected_listening_listen_0_guard(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ data = parameters[1]
|
|
|
+ return (self.socket == socket) and (len(data) > 0)
|
|
|
+
|
|
|
+ def _connected_listening_listen_1_exec(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ data = parameters[1]
|
|
|
+ self.raiseInternalEvent(Event("received_data", None, []))
|
|
|
+
|
|
|
+ def _connected_listening_listen_1_guard(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ data = parameters[1]
|
|
|
+ return (self.socket == socket) and (len(data) == 0)
|
|
|
+
|
|
|
+ def _connected_sending_waiting_for_data_0_exec(self, parameters):
|
|
|
+ self.big_step.outputEvent(Event("send_socket", "socket_out", [self.socket, self.send_data]))
|
|
|
+
|
|
|
+ def _connected_sending_waiting_for_data_0_guard(self, parameters):
|
|
|
+ return len(self.send_data) > 0
|
|
|
+
|
|
|
+ def _connected_sending_transferring_0_exec(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ sent_bytes = parameters[1]
|
|
|
+ self.send_data = self.send_data[sent_bytes:]
|
|
|
+
|
|
|
+ def _connected_sending_transferring_0_guard(self, parameters):
|
|
|
+ socket = parameters[0]
|
|
|
+ sent_bytes = parameters[1]
|
|
|
+ return self.socket == socket
|
|
|
+
|
|
|
+ def _connected_queueing_queueing_0_exec(self, parameters):
|
|
|
+ data = parameters[0]
|
|
|
+ #post_data = "&".join(["%s=%s" % (urllib.quote(k), urllib.quote(v)) for k, v in data.iteritems()])
|
|
|
+ #post_data = "&".join(["%s=%s" % (k, v) for k, v in data.iteritems()])
|
|
|
+ post_data = data
|
|
|
+ self.send_data += "HTTP/1.0 200 OK\r\n"
|
|
|
+ self.send_data += "Content-Length: %s\r\n" % len(post_data)
|
|
|
+ self.send_data += "Content-Type: %s; charset=UTF-8\r\n" % "text/plain"
|
|
|
+ self.send_data += "\r\n"
|
|
|
+ self.send_data += str(post_data)
|
|
|
+
|
|
|
+ def _connected_parsing_wait_for_header_0_exec(self, parameters):
|
|
|
+ header, self.received_data = self.received_data.split("\r\n\r\n", 1)
|
|
|
+ header = header.lower()
|
|
|
+ if "content-length" in header:
|
|
|
+ _, after = header.split("content-length:", 1)
|
|
|
+ after = after.split("\r\n", 1)[0]
|
|
|
+ after = after.strip()
|
|
|
+ self.length = int(after)
|
|
|
+ else:
|
|
|
+ self.length = float('inf')
|
|
|
+
|
|
|
+ def _connected_parsing_wait_for_header_0_guard(self, parameters):
|
|
|
+ return '\r\n\r\n' in self.received_data and self.received_data.startswith('POST')
|
|
|
+
|
|
|
+ def _connected_parsing_wait_for_header_1_guard(self, parameters):
|
|
|
+ return self.closed and len(self.received_data) == 0
|
|
|
+
|
|
|
+ def _connected_parsing_closing_0_exec(self, parameters):
|
|
|
+ self.raiseInternalEvent(Event("close", None, []))
|
|
|
+
|
|
|
+ def _connected_parsing_wait_for_payload_0_exec(self, parameters):
|
|
|
+ if self.length == float('inf'):
|
|
|
+ data = self.received_data
|
|
|
+ self.received_data = ""
|
|
|
+ else:
|
|
|
+ data = self.received_data[:self.length]
|
|
|
+ self.received_data = self.received_data[self.length:]
|
|
|
+
|
|
|
+ print("Got data: " + str(data))
|
|
|
+
|
|
|
+ # We support POST data only, so everything is in the data
|
|
|
+ #try:
|
|
|
+ # params = dict([p.split('=') for p in data.split('&')])
|
|
|
+ # data = {k: urllib.unquote_plus(v) for k, v in params.iteritems()}
|
|
|
+ #except:
|
|
|
+ # data = {}
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("HTTP_output", None, [self.association_name, data])]))
|
|
|
+
|
|
|
+ def _connected_parsing_wait_for_payload_0_guard(self, parameters):
|
|
|
+ return len(self.received_data) >= self.length or self.closed
|
|
|
+
|
|
|
+ def initializeStatechart(self):
|
|
|
+ # enter default state
|
|
|
+ self.default_targets = self.states["/init"].getEffectiveTargetStates()
|
|
|
+ RuntimeClassBase.initializeStatechart(self)
|
|
|
+
|
|
|
+class ObjectManager(ObjectManagerBase):
|
|
|
+ def __init__(self, controller):
|
|
|
+ ObjectManagerBase.__init__(self, controller)
|
|
|
+
|
|
|
+ def instantiate(self, class_name, construct_params):
|
|
|
+ if class_name == "Echo":
|
|
|
+ instance = Echo(self.controller, construct_params[0])
|
|
|
+ instance.associations = {}
|
|
|
+ instance.associations["to_server"] = Association("Server", 1, 1)
|
|
|
+ elif class_name == "Server":
|
|
|
+ instance = Server(self.controller, construct_params[0], construct_params[1])
|
|
|
+ instance.associations = {}
|
|
|
+ instance.associations["sockets"] = Association("Socket", 0, -1)
|
|
|
+ instance.associations["parent"] = Association("Echo", 1, 1)
|
|
|
+ elif class_name == "Socket":
|
|
|
+ instance = Socket(self.controller, construct_params[0])
|
|
|
+ instance.associations = {}
|
|
|
+ instance.associations["parent"] = Association("Server", 1, 1)
|
|
|
+ else:
|
|
|
+ raise Exception("Cannot instantiate class " + class_name)
|
|
|
+ return instance
|
|
|
+
|
|
|
+class Controller(ThreadsControllerBase):
|
|
|
+ def __init__(self, params, keep_running = None, behind_schedule_callback = None):
|
|
|
+ if keep_running == None: keep_running = True
|
|
|
+ if behind_schedule_callback == None: behind_schedule_callback = None
|
|
|
+ ThreadsControllerBase.__init__(self, ObjectManager(self), keep_running, behind_schedule_callback)
|
|
|
+ self.addInputPort("socket_in")
|
|
|
+ self.addOutputPort("socket_out")
|
|
|
+ self.object_manager.createInstance("Echo", [params])
|