123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- <class name="Modelverse">
- <relationships>
- <association name="http_client" class="HTTPClient" min="2" max="2"/>
- </relationships>
- <method name="load_action">
- <parameter name="context"/>
- <body>
- action = self.actions[None].pop(0)
- self.parameters = action["parameters"]
- self.current_ID = action["ID"]
- </body>
- </method>
- <method name="expect_response">
- <parameter name="expected"/>
- <parameter name="pop" default="False"/>
- <body>
- if self.responses and self.responses[0] == expected:
- if pop:
- del self.responses[0]
- return True
- else:
- return False
- </body>
- </method>
- <method name="expect_response_partial">
- <parameter name="expected"/>
- <parameter name="pop" default="False"/>
- <body>
- print("Checking for partial resonse, got: " + str(self.responses))
- if self.responses and self.responses.startswith(expected):
- if pop:
- del self.responses[0]
- return True
- else:
- return False
- </body>
- </method>
- <method name="expect_action">
- <parameter name="context"/>
- <parameter name="expected"/>
- <body>
- return self.actions[context] and self.actions[context][0]["name"] == expected
- </body>
- </method>
- <constructor>
- <body>
- self.actions = {None: []}
- self.responses = []
- self.http_clients = []
- </body>
- </constructor>
- <scxml initial="init">
- <state id="init">
- <onentry>
- <raise scope="cd" event="create_instance">
- <parameter expr="'http_client'"/>
- <parameter expr="'HTTPClient'"/>
- </raise>
- <raise scope="cd" event="create_instance">
- <parameter expr="'http_client'"/>
- <parameter expr="'HTTPClient'"/>
- </raise>
- </onentry>
- <transition event="instance_created" target=".">
- <parameter name="instance"/>
- <script>
- self.http_clients.append(instance)
- </script>
- <raise scope="cd" event="start_instance">
- <parameter expr="instance"/>
- </raise>
- </transition>
- <transition cond="len(self.http_clients) == 2" target="../waiting"/>
- </state>
- <state id="waiting">
- <transition event="http_client_initialized" target="../initialized"/>
- </state>
- <parallel id="initialized">
- <onentry>
- <raise scope="output" port="ready" event="ready"/>
- </onentry>
- <state id="http_mapper" initial="init">
- <state id="init">
- <transition event="request" cond="isinstance(value, type([]))" target=".">
- <parameter name="value"/>
- <raise event="HTTP_input" target="self.http_clients[0]">
- <parameter expr='urllib.urlencode({"op": "set_input", "data": json.dumps(value), "taskname": self.taskname})'/>
- <parameter expr='None'/>
- </raise>
- <script>
- print("Sent out value: " + str(urllib.urlencode({"op": "set_input", "data": json.dumps(value), "taskname": self.taskname})))
- </script>
- </transition>
- <transition event="request" cond="not isinstance(value, type([]))" target=".">
- <parameter name="value"/>
- <raise event="HTTP_input" target="self.http_clients[0]">
- <parameter expr='urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": self.taskname})'/>
- <parameter expr='None'/>
- </raise>
- <script>
- print("Sent out value: " + str(urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": self.taskname})))
- </script>
- </transition>
- <transition event="request_raw" target=".">
- <parameter name="value"/>
- <parameter name="taskname"/>
- <parameter name="http_client"/>
- <raise event="HTTP_input" target="self.http_clients[http_client]">
- <parameter expr='urllib.urlencode({"op": "set_input", "value": json.dumps(value), "taskname": taskname})'/>
- <parameter expr='"parent"'/>
- </raise>
- </transition>
- <transition event="HTTP_output" target=".">
- <parameter name="data"/>
- <raise event="HTTP_input" target="self.http_clients[1]">
- <parameter expr='urllib.urlencode({"op": "get_output", "taskname": self.taskname})'/>
- <parameter expr='"parent"'/>
- </raise>
- <script>
- print("Got output " + str(data))
- self.responses.append(json.loads(data))
- </script>
- </transition>
- </state>
- </state>
- <state id="behaviour" initial="wait_for_action">
- <state id="connecting" initial="connect_http_client">
- <onentry>
- <script>
- self.address, self.timeout = self.parameters
- self.address = self.address.rsplit(":", 1)
- self.address = (self.address[0], int(self.address[1]))
- self.i = 0
- self.taskname = str(uuid.uuid4())
- </script>
- </onentry>
- <state id="connect_http_client">
- <transition cond="self.i < 2" target="../waiting_http_client">
- <raise scope="narrow" target="self.http_clients[self.i]" event="connect">
- <parameter expr="self.address"/>
- <parameter expr="self.timeout"/>
- </raise>
- </transition>
- <transition cond="self.i == 2" target="../../wait_for_action/connected">
- <!-- Start polling for output -->
- <raise event="HTTP_input" target="self.http_clients[1]">
- <parameter expr='urllib.urlencode({"op": "get_output", "taskname": self.taskname})'/>
- <parameter expr='"parent"'/>
- </raise>
- <!-- Sent out completion -->
- <raise event="result">
- <parameter expr="[]"/>
- </raise>
- </transition>
- </state>
- <state id="waiting_http_client">
- <transition event="http_client_ready" target="../wait_for_taskname_ack">
- <!-- Request the task to be created -->
- <raise event="request_raw">
- <parameter expr="self.taskname"/>
- <parameter expr="'task_manager'"/>
- <parameter expr="self.i"/>
- </raise>
- <script>
- self.i += 1
- </script>
- </transition>
- <transition event="http_client_timeout" target="../../wait_for_action/disconnected">
- <raise scope="broad" event="exception">
- <parameter expr="self.current_ID"/>
- <parameter expr="'Connection timeout'"/>
- </raise>
- </transition>
- </state>
- <state id="wait_for_taskname_ack">
- <transition cond="self.expect_response('OK', pop=True)" target="../connect_http_client"/>
- </state>
- </state>
- <state id="logging_in" initial="wait_prompt_1">
- <state id="wait_prompt_1">
- <transition cond="self.expect_response('Log on as which user?', pop=True)" target="../wait_prompt_2">
- <raise event="request">
- <parameter expr="self.parameters[0]"/>
- </raise>
- </transition>
- </state>
- <state id="wait_prompt_2">
- <transition cond="self.expect_response('Password for existing user?', pop=True)" target="../wait_prompt_existing">
- <raise event="request">
- <parameter expr="self.parameters[1]"/>
- </raise>
- </transition>
- <transition cond="self.expect_response('This is a new user: please give password!', pop=True)" target="../wait_prompt_existing">
- <raise event="request">
- <parameter expr="self.parameters[1]"/>
- </raise>
- </transition>
- </state>
- <state id="wait_prompt_existing">
- <transition cond="self.expect_response('Welcome to the Model Management Interface v2.0!', pop=True)" target="../login_ok"/>
- <transition cond="self.expect_response('Wrong password!', pop=True)" target="../../wait_for_action/connected">
- <raise event="exception">
- <parameter expr="{'name': 'PermissionDenied'}"/>
- </raise>
- </transition>
- </state>
- <state id="login_ok">
- <transition cond="self.expect_response('Use the \'help\' command for a list of possible commands', pop=True)" target="../../wait_for_action/megamodelling">
- <raise event="request">
- <parameter expr="'quiet'"/>
- </raise>
- <raise event="result">
- <parameter expr="[]"/>
- </raise>
- </transition>
- </state>
- </state>
- <state id="model_list">
- <onentry>
- <raise event="request">
- <parameter expr="'model_list'"/>
- </raise>
- <script>
- print("Raised model_list!")
- </script>
- </onentry>
- <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../wait_for_action/history">
- <raise event="result">
- <parameter expr="self.split_response('Success: ')"/>
- </raise>
- </transition>
- </state>
- <state id="wait_for_action" initial="disconnected">
- <state id="disconnected">
- <transition cond="self.expect_action(None, 'init')" target="../../connecting">
- <script>
- self.load_action(None)
- </script>
- </transition>
- </state>
- <state id="connected">
- <transition cond="self.expect_action(None, 'login')" target="../../logging_in">
- <script>
- self.load_action(None)
- </script>
- </transition>
- </state>
- <state id="megamodelling">
- <transition cond="self.expect_action(None, 'model_list')" target="../../model_list">
- <script>
- self.load_action(None)
- </script>
- </transition>
- </state>
- <state id="modelling" initial="manual">
- <state id="manual">
- </state>
- <state id="scripted">
- </state>
- </state>
- <history id="history" type="deep"/>
- </state>
- </state>
- <state id="queue">
- <state id="queue">
- <transition port="action_in" event="action" target=".">
- <parameter name="action_name"/>
- <parameter name="ID"/>
- <parameter name="context_ID"/>
- <parameter name="parameters"/>
- <script>
- self.actions[context_ID].append({"name": action_name, "ID": ID, "parameters": parameters})
- </script>
- </transition>
- <transition event="result" target=".">
- <parameter name="parameters"/>
- <raise scope="output" event="result" port="action_out">
- <parameter expr="self.current_ID"/>
- <parameter expr="parameters"/>
- </raise>
- </transition>
- <transition event="exception" target=".">
- <parameter name="parameters"/>
- <raise scope="output" event="exception" port="action_out">
- <parameter expr="self.current_ID"/>
- <parameter expr="parameters"/>
- </raise>
- </transition>
- <transition port="input_in" event="input" target=".">
- <parameter name="value"/>
- <parameter name="context_ID"/>
- <script>
- self.inputs[context_ID].append(value)
- </script>
- </transition>
- </state>
- </state>
- </parallel>
- </scxml>
- </class>
|