|
@@ -52,38 +52,108 @@ def _next_ID():
|
|
|
ID += 1
|
|
|
return ID
|
|
|
|
|
|
-def _process_SC(statechart, port_sc, context):
|
|
|
- print("Context: " + str(context))
|
|
|
+def __run_new_modelverse(address, username, password, callback, model):
|
|
|
+ print("RUN NEW")
|
|
|
+ init(address)
|
|
|
+ login(username, password)
|
|
|
+ print("LOGIN OK")
|
|
|
+ if callback is not None:
|
|
|
+ callback(model)
|
|
|
+ exit_save(model)
|
|
|
+ print("CALLBACK DONE")
|
|
|
+
|
|
|
+def __run_new_modelverse_activity(address, username, password, taskname, pipe, callback):
|
|
|
+ print("Run MV activity")
|
|
|
+ init(address, taskname=taskname)
|
|
|
+ controller.username = username
|
|
|
+ controller.password = password
|
|
|
+ print("INIT OK")
|
|
|
+ t = OUTPUT()
|
|
|
+ print("Got type: " + str(t))
|
|
|
+
|
|
|
+ if t == "OP":
|
|
|
+ print("Requesting model...")
|
|
|
+ model = OUTPUT()
|
|
|
+ print("Do manual operations on " + str(model))
|
|
|
+ __invoke(callback, model)
|
|
|
+ print("Invocation OK")
|
|
|
+ controller.addInput(Event("data_input", "action_in", [None, None]))
|
|
|
+ print("Waiting on output")
|
|
|
+ # TODO fix this to something using OUTPUT or so
|
|
|
+ time.sleep(5)
|
|
|
+ elif t == "SC":
|
|
|
+ while 1:
|
|
|
+ empty = True
|
|
|
+
|
|
|
+ # Fetch output from the MV
|
|
|
+ response = responses.fetch(0)
|
|
|
+ if response is not None:
|
|
|
+ print("Output of MV to SC: " + str(response))
|
|
|
+ if response.name == "data_output":
|
|
|
+ # Got output of MV, so forward to SCCD
|
|
|
+ pipe.send(("input", response.parameters))
|
|
|
+ elif response.name == "result":
|
|
|
+ # Finished execution, so continue and return result
|
|
|
+ pipe.send(("terminate", []))
|
|
|
+ pipe.close()
|
|
|
+ return response.parameters[1]
|
|
|
+ else:
|
|
|
+ raise Exception("Unknown data from MV to SC: " + str(response))
|
|
|
+ empty = False
|
|
|
+
|
|
|
+ # Fetch output from the SC
|
|
|
+ if pipe.poll():
|
|
|
+ response = pipe.recv()
|
|
|
+
|
|
|
+ if response.name == "output":
|
|
|
+ controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
|
|
|
+ else:
|
|
|
+ raise Exception("Unknown data from SC to MV: " + str(response))
|
|
|
+ empty = False
|
|
|
+
|
|
|
+ if empty:
|
|
|
+ time.sleep(0.05)
|
|
|
+
|
|
|
+def __invoke(callback, model):
|
|
|
+ import multiprocessing
|
|
|
+ print("Invoked action!")
|
|
|
+ p = multiprocessing.Process(target=__run_new_modelverse, args=[controller.address, controller.username, controller.password, callback, model])
|
|
|
+ p.start()
|
|
|
+ p.join()
|
|
|
+ print("Invocation done")
|
|
|
+
|
|
|
+def _process_SC(statechart, port_sc, taskname):
|
|
|
+ import multiprocessing
|
|
|
+ p2c_pipe, c2p_pipe = multiprocessing.Pipe()
|
|
|
+ p = multiprocessing.Process(target=__run_new_modelverse_activity, args=[controller.address, controller.username, controller.password, taskname, c2p_pipe, None])
|
|
|
+ p.start()
|
|
|
while 1:
|
|
|
empty = True
|
|
|
|
|
|
- # Fetch output from the MV
|
|
|
- response = responses.fetch(0)
|
|
|
- if response is not None:
|
|
|
- print("Output of MV to SC")
|
|
|
- if response.name == "data_output":
|
|
|
- # Got output of MV, so forward to SCCD
|
|
|
- statechart[0].addInput(Event("input", statechart[1], response.parameters))
|
|
|
- elif response.name == "result":
|
|
|
- # Finished execution, so continue and return result
|
|
|
- statechart[0].addInput(Event("terminate", statechart[1], []))
|
|
|
- return response.parameters[1]
|
|
|
- else:
|
|
|
- raise Exception("Unknown data from MV to SC: " + str(response))
|
|
|
+ if p2c_pipe.poll():
|
|
|
+ response = p2c_pipe.recv()
|
|
|
+ statechart[0].addInput(Event(response[0], statechart[1], response[1]))
|
|
|
+
|
|
|
+ if response[0] == "terminate":
|
|
|
+ p2c_pipe.close()
|
|
|
+ break
|
|
|
empty = False
|
|
|
|
|
|
- # Fetch output from the SC
|
|
|
response = port_sc.fetch(0)
|
|
|
if response is not None:
|
|
|
- print("Output of SC to MV")
|
|
|
- if response.name == "output":
|
|
|
- controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
|
|
|
- else:
|
|
|
- raise Exception("Unknown data from SC to MV: " + str(response))
|
|
|
+ p2c_pipe.send(response)
|
|
|
empty = False
|
|
|
|
|
|
if empty:
|
|
|
- time.sleep(0.5)
|
|
|
+ time.sleep(0.05)
|
|
|
+ p.join()
|
|
|
+
|
|
|
+def _process_OP(callback, taskname):
|
|
|
+ import multiprocessing
|
|
|
+ print("Running remote operation for taskname " + taskname)
|
|
|
+ p = multiprocessing.Process(target=__run_new_modelverse_activity, args=[controller.address, controller.username, controller.password, taskname, None, callback])
|
|
|
+ p.start()
|
|
|
+ p.join()
|
|
|
|
|
|
def INPUT(action, context, parameters):
|
|
|
controller.addInput(Event("action", "action_in", [action, _next_ID(), context, parameters]))
|
|
@@ -102,12 +172,12 @@ def OUTPUT():
|
|
|
print("Unknown error: " + str(response.parameters))
|
|
|
raise UnknownError()
|
|
|
|
|
|
-def init(address_param="127.0.0.1:8001", timeout=20.0):
|
|
|
+def init(address_param="127.0.0.1:8001", timeout=20.0, taskname=None):
|
|
|
global controller
|
|
|
global ID
|
|
|
global responses
|
|
|
|
|
|
- controller = modelverse_SCCD.Controller()
|
|
|
+ controller = modelverse_SCCD.Controller(taskname)
|
|
|
socket2event.boot_translation_service(controller)
|
|
|
|
|
|
ID = 0
|
|
@@ -124,6 +194,8 @@ def init(address_param="127.0.0.1:8001", timeout=20.0):
|
|
|
return OUTPUT()
|
|
|
|
|
|
def login(username, password):
|
|
|
+ controller.username = username
|
|
|
+ controller.password = password
|
|
|
INPUT("login", None, [username, password])
|
|
|
return OUTPUT()
|
|
|
|
|
@@ -173,31 +245,36 @@ def transformation_between(sources, targets):
|
|
|
|
|
|
def transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=None):
|
|
|
INPUT("transformation_add_MT", None, [source_metamodels, target_metamodels, operation_name, code, True])
|
|
|
- context, model = OUTPUT()
|
|
|
+ model = OUTPUT()
|
|
|
+
|
|
|
if callback is not None:
|
|
|
- callback(context)
|
|
|
- INPUT("exit", context, [])
|
|
|
+ __invoke(callback, model)
|
|
|
+ controller.addInput(Event("data_input", "action_in", [None, None]))
|
|
|
+
|
|
|
return OUTPUT()
|
|
|
|
|
|
def transformation_add_AL(source_metamodels, target_metamodels, operation_name, code, callback=None):
|
|
|
INPUT("transformation_add_AL", None, [source_metamodels, target_metamodels, operation_name, code, True])
|
|
|
- context, model = OUTPUT()
|
|
|
+ model = OUTPUT()
|
|
|
|
|
|
- if context is None:
|
|
|
+ if model is None:
|
|
|
# In case the source and target metamodels are empty, the context will be None, indicating that we are finished already (no callbacks allowed)
|
|
|
return
|
|
|
|
|
|
if callback is not None:
|
|
|
- callback(context)
|
|
|
- INPUT("exit", context, [])
|
|
|
+ __invoke(callback, model)
|
|
|
+ controller.addInput(Event("data_input", "action_in", [None, None]))
|
|
|
+
|
|
|
return OUTPUT()
|
|
|
|
|
|
def transformation_add_MANUAL(source_metamodels, target_metamodels, operation_name, callback=None):
|
|
|
INPUT("transformation_add_MANUAL", None, [source_metamodels, target_metamodels, operation_name, True])
|
|
|
- context, model = OUTPUT()
|
|
|
+ model = OUTPUT()
|
|
|
+
|
|
|
if callback is not None:
|
|
|
- callback(context)
|
|
|
- INPUT("exit", context, [])
|
|
|
+ __invoke(callback, model)
|
|
|
+ controller.addInput(Event("data_input", "action_in", [None, None]))
|
|
|
+
|
|
|
return OUTPUT()
|
|
|
|
|
|
def __transformation_execute(operation_name, input_models_dict, output_models_dict, statechart, tracability_model, fetch_output):
|
|
@@ -205,13 +282,10 @@ def __transformation_execute(operation_name, input_models_dict, output_models_di
|
|
|
port_sc = statechart[0].addOutputListener(statechart[2])
|
|
|
|
|
|
INPUT("transformation_execute", None, [operation_name, input_models_dict, output_models_dict, tracability_model, fetch_output])
|
|
|
- op, name, context = OUTPUT()
|
|
|
+ taskname = OUTPUT()
|
|
|
if statechart is not None:
|
|
|
- threading.Thread(target=_process_SC, args=[statechart, port_sc, context]).start()
|
|
|
- else:
|
|
|
- val = OUTPUT()
|
|
|
- print("Transformation result: " + str(val))
|
|
|
- return val
|
|
|
+ threading.Thread(target=_process_SC, args=[statechart, port_sc, taskname]).start()
|
|
|
+ return OUTPUT()
|
|
|
|
|
|
def transformation_execute_MT(operation_name, input_models_dict, output_models_dict, statechart=None, tracability_model="", fetch_output=True):
|
|
|
return __transformation_execute(operation_name, input_models_dict, output_models_dict, statechart, tracability_model, fetch_output)
|
|
@@ -221,10 +295,12 @@ def transformation_execute_AL(operation_name, input_models_dict, output_models_d
|
|
|
|
|
|
def transformation_execute_MANUAL(operation_name, input_models_dict, output_models_dict, callback=None, tracability_model=""):
|
|
|
INPUT("transformation_execute", None, [operation_name, input_models_dict, output_models_dict, tracability_model])
|
|
|
- op, name, context, model = OUTPUT()
|
|
|
- if callback is not None:
|
|
|
- callback(context)
|
|
|
- INPUT("exit", context, [])
|
|
|
+ taskname = OUTPUT()
|
|
|
+
|
|
|
+ print("Running manual task at " + str(taskname))
|
|
|
+ _process_OP(callback, taskname)
|
|
|
+ print("Process OP called")
|
|
|
+
|
|
|
return OUTPUT()
|
|
|
|
|
|
def transformation_signature(operation_name):
|
|
@@ -439,6 +515,10 @@ def get_taskname():
|
|
|
"""Fetch the taskname of the current connection."""
|
|
|
return controller.taskname
|
|
|
|
|
|
+def exit_save(model_name):
|
|
|
+ INPUT("exit_save", None, [model_name])
|
|
|
+ return OUTPUT()
|
|
|
+
|
|
|
""" Some hardcoded functions... Way easier to express them with code than with statecharts!"""
|
|
|
import json
|
|
|
import urllib
|