Browse Source

Host both a coded and explicitly modelled Mv wrapper

Yentl Van Tendeloo 8 years ago
parent
commit
b0003d3811
2 changed files with 1158 additions and 99 deletions
  1. 95 99
      wrappers/modelverse_coded.py
  2. 1063 0
      wrappers/modelverse_sccd.py

+ 95 - 99
wrappers/modelverse_coded.py

@@ -1,10 +1,12 @@
 import urllib
 import urllib
+import urllib2
 import json
 import json
 import random
 import random
+from urllib2 import URLError
 import sys
 import sys
 import time
 import time
 import threading
 import threading
-import uuid
+import Queue
 
 
 from sccd.runtime.statecharts_core import Event
 from sccd.runtime.statecharts_core import Event
 
 
@@ -22,8 +24,6 @@ MODE_SERVICE = 6
 sys.path.append(COMPILER_PATH)
 sys.path.append(COMPILER_PATH)
 from hutn_compiler.compiler import main as do_compile
 from hutn_compiler.compiler import main as do_compile
 
 
-import socket2event
-
 # Exceptions
 # Exceptions
 class ModelverseException(Exception):
 class ModelverseException(Exception):
     pass
     pass
@@ -63,25 +63,20 @@ class UnknownMetamodellingHierarchy(ModelverseException):
 
 
 # Helper functions and configuration: do not use yourself!
 # Helper functions and configuration: do not use yourself!
 taskname = None
 taskname = None
+address = None
 mode = MODE_UNCONNECTED
 mode = MODE_UNCONNECTED
 prev_mode = None
 prev_mode = None
 current_model = None
 current_model = None
 registered_metamodels = {}
 registered_metamodels = {}
 outputs = [None]
 outputs = [None]
-ctrl_input = None
-ctrl_output = None
 
 
 def _output_thread(outputs, taskname):
 def _output_thread(outputs, taskname):
-    req_out = ctrl_output.addOutputListener("request_out")
-    my_id = str(uuid.uuid4())
+    while taskname is None:
+        time.sleep(0.1)
 
 
     try:
     try:
         while 1:
         while 1:
-            ctrl_output.addInput(Event("HTTP_input", "request_in", [urllib.urlencode({"op": "get_output", "taskname": taskname}), my_id]))
-
-            event = req_out.fetch(-1)
-            if event.parameters[1] == my_id:
-                outputs.append(json.loads(event.parameters[0]))
+            outputs.append(json.loads(urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "taskname": taskname}))).read()))
     except:
     except:
         pass
         pass
 
 
@@ -108,7 +103,7 @@ def _exec_on_statechart(statechart):
                 # Expand the event and make it HTTP input
                 # Expand the event and make it HTTP input
                 _input(input_event.parameters)
                 _input(input_event.parameters)
                 
                 
-            time.sleep(0.02)
+            time.sleep(0.01)
         
         
     thrd = threading.Thread(target=_exec_sc, args=statechart)
     thrd = threading.Thread(target=_exec_sc, args=statechart)
     thrd.daemon = True
     thrd.daemon = True
@@ -165,19 +160,20 @@ def _goto_mode(new_mode, model_name=None):
 
 
 def _input(value, port=None):
 def _input(value, port=None):
     # Ugly json encoding of primitives
     # Ugly json encoding of primitives
-    #print("[IN] %s" % value)
+    print("[IN] %s" % value)
     if port is None:
     if port is None:
         port = taskname
         port = taskname
     if isinstance(value, type([])):
     if isinstance(value, type([])):
         value = json.dumps(value)
         value = json.dumps(value)
-        ctrl_input.addInput(Event("HTTP_input", "request_in", [urllib.urlencode({"op": "set_input", "taskname": port, "data": value}), None]))
+        urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": value, "taskname": port}))).read()
     else:
     else:
         value = json.dumps(value)
         value = json.dumps(value)
-        ctrl_input.addInput(Event("HTTP_input", "request_in", [urllib.urlencode({"op": "set_input", "taskname": port, "value": value}), None]))
+        #print("Set input: " + str(value))
+        urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": port}))).read()
 
 
 def _input_raw(value, taskname):
 def _input_raw(value, taskname):
     # Ugly json encoding of primitives
     # Ugly json encoding of primitives
-    ctrl_input.addInput(Event("HTTP_input", "request_in", [urllib.urlencode({"op": "set_input", "taskname": taskname, "value": value}), None]))
+    urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": taskname}))).read()
 
 
 def _compile_AL(code):
 def _compile_AL(code):
     # Compile an action language file and send the compiled code
     # Compile an action language file and send the compiled code
@@ -216,10 +212,11 @@ def _compile_model(code):
 def _output(expected=None):
 def _output(expected=None):
     try:
     try:
         while len(outputs) < 2:
         while len(outputs) < 2:
-            time.sleep(0.02)
+            time.sleep(0.5)
+            print("Sleep for output: " + str(outputs))
 
 
         del outputs[0]
         del outputs[0]
-        #print("[OUT] %s" % outputs[0])
+        print("[OUT] %s" % outputs[0])
     except:
     except:
         raise UnknownError()
         raise UnknownError()
 
 
@@ -231,7 +228,7 @@ def _last_output():
     return outputs[0]
     return outputs[0]
 
 
 # Raise common exceptions
 # Raise common exceptions
-def _handle_output(requested=None, split=False):
+def _handle_output(requested=None, split=None):
     value = _output()
     value = _output()
     if value.startswith("Model exists: "):
     if value.startswith("Model exists: "):
         raise ModelExists(value.split(": ", 1)[1])
         raise ModelExists(value.split(": ", 1)[1])
@@ -246,14 +243,14 @@ def _handle_output(requested=None, split=False):
     elif value.startswith("Attribute not found: "):
     elif value.startswith("Attribute not found: "):
         raise NoSuchAttribute(value.split(": ", 1)[1])
         raise NoSuchAttribute(value.split(": ", 1)[1])
     elif requested is not None and value.startswith(requested):
     elif requested is not None and value.startswith(requested):
-        if not split:
+        if split is None:
             return value
             return value
         else:
         else:
-            splitted = value.strip().split(" ", 1)
-            if len(splitted) > 1:
-                return splitted[1].split("\n")
+            splitted = value.strip().split(split, 1)
+            if len(splitted) == 1:
+                return ""
             else:
             else:
-                return []
+                return splitted[1].rstrip()
     else:
     else:
         raise InterfaceMismatch(value)
         raise InterfaceMismatch(value)
     
     
@@ -299,52 +296,23 @@ def alter_context(model_name, metamodel_name):
     registered_metamodels[model_name] = metamodel_name
     registered_metamodels[model_name] = metamodel_name
 
 
 # Main MvC operations
 # Main MvC operations
-def init(address_param="127.0.0.1:8001", timeout=20.0):
+def init(address_param="http://127.0.0.1:8001", timeout=20.0):
     """Starts up the connection to the Modelverse."""
     """Starts up the connection to the Modelverse."""
-    # Start up the HTTP Client SC
-    import http_client
-    global ctrl_input
-    global ctrl_output
-
-    if ctrl_input is not None:
-        ctrl_input.stop()
-    if ctrl_output is not None:
-        ctrl_output.stop()
-
-    ctrl_input = http_client.Controller()
-    ctrl_output = http_client.Controller()
-    controllers = [ctrl_input, ctrl_output]
-
-    addr, port = address_param.split(":", 1)
-    port = int(port)
-
-    for ctrl in controllers:
-        listener = ctrl.addOutputListener("request_out")
-        socket2event.boot_translation_service(ctrl)
-        thrd = threading.Thread(target=ctrl.start)
-        thrd.daemon = True
-        thrd.start()
-
-        evt = listener.fetch(-1)
-        if evt.name != "http_client_initialized":
-            raise Exception("HTTP client did not behave as expected during init: " + str(evt.name))
-
-        ctrl.addInput(Event("connect", "request_in", [(addr, port), timeout]))
-
-        evt = listener.fetch(-1)
-
-        if evt.name == "http_client_timeout":
-            raise Exception("HTTP client timeout")
-        if evt.name != "http_client_ready":
-            raise Exception("HTTP client did not behave as expected during connect: " + str(evt.name))
-
     global mode
     global mode
+    global address
+    address = address_param
     start_time = time.time()
     start_time = time.time()
     task = random.random()
     task = random.random()
-
-    _input_raw('"%s"' % task, "task_manager")
-
-    mode = MODE_UNAUTHORIZED
+    while 1:
+        try:
+            _input_raw('"%s"' % task, "task_manager")
+            mode = MODE_UNAUTHORIZED
+            break
+        except URLError as e:
+            if time.time() - start_time > timeout:
+                raise ConnectionError(e.reason)
+            else:
+                time.sleep(0.1)
 
 
     global outputs
     global outputs
     global taskname
     global taskname
@@ -431,16 +399,19 @@ def model_list(location):
     """List all models."""
     """List all models."""
     _goto_mode(MODE_MODELLING)
     _goto_mode(MODE_MODELLING)
     _input(["model_list", location])
     _input(["model_list", location])
-    return set(_handle_output("Success: ", split=True))
+    return set(_handle_output("Success: ", split=" ").split("\n"))
 
 
 def model_list_full(location):
 def model_list_full(location):
     """List full information on all models."""
     """List full information on all models."""
     _goto_mode(MODE_MODELLING)
     _goto_mode(MODE_MODELLING)
     _input(["model_list_full", location])
     _input(["model_list_full", location])
-    output = _handle_output("Success: ", split=True)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
 
 
     lst = set([])
     lst = set([])
-    for v in output:
+    value = output.strip().split("\n")
+    for v in value:
         m = v.strip()
         m = v.strip()
         perm, own, grp, m = m.split(" ", 3)
         perm, own, grp, m = m.split(" ", 3)
         lst.add((m, own, grp, perm))
         lst.add((m, own, grp, perm))
@@ -455,7 +426,7 @@ def verify(model_name, metamodel_name=None):
         metamodel_name = _get_metamodel(model_name)
         metamodel_name = _get_metamodel(model_name)
 
 
     _input(["verify", model_name, metamodel_name])
     _input(["verify", model_name, metamodel_name])
-    return _handle_output("Success: ", split=True)[0]
+    return _handle_output("Success: ", split=" ")
 
 
 def model_overwrite(model_name, new_model=None, metamodel_name=None):
 def model_overwrite(model_name, new_model=None, metamodel_name=None):
     """Upload a new model and overwrite an existing model."""
     """Upload a new model and overwrite an existing model."""
@@ -497,14 +468,16 @@ def model_render(model_name, mapper_name):
     _goto_mode(MODE_MODELLING)
     _goto_mode(MODE_MODELLING)
 
 
     _input(["model_render", model_name, mapper_name])
     _input(["model_render", model_name, mapper_name])
-    return json.loads(_handle_output("Success: ", split=True)[0])
+    return json.loads(_handle_output("Success: ", split=" "))
 
 
 def transformation_between(source, target):
 def transformation_between(source, target):
     _goto_mode(MODE_MODELLING)
     _goto_mode(MODE_MODELLING)
 
 
     _input(["transformation_between", source, target])
     _input(["transformation_between", source, target])
-    output = _handle_output("Success: ", split=True)
-    return set(output)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    return set([v for v in output.split("\n")])
 
 
 def transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=lambda: None):
 def transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=lambda: None):
     """Create a new model transformation."""
     """Create a new model transformation."""
@@ -666,10 +639,13 @@ def transformation_list():
     _goto_mode(MODE_MODELLING)
     _goto_mode(MODE_MODELLING)
 
 
     _input("transformation_list")
     _input("transformation_list")
-    output = _handle_output("Success: ", split=True)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
 
 
     lst = set([])
     lst = set([])
-    for v in output:
+    value = output.strip().split("\n")
+    for v in value:
         t, m = v.strip().split(" ", 1)
         t, m = v.strip().split(" ", 1)
         t = t[1:-1].strip()
         t = t[1:-1].strip()
         m = m.strip().split(":")[0].strip()
         m = m.strip().split(":")[0].strip()
@@ -791,8 +767,10 @@ def element_list(model_name):
 
 
     _input("list_full")
     _input("list_full")
     lst = set([])
     lst = set([])
-    output = _handle_output("Success: ", split=True)
-    for v in output:
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    for v in output.split("\n"):
         m, mm = v.split(":")
         m, mm = v.split(":")
         m = m.strip()
         m = m.strip()
         mm = mm.strip()
         mm = mm.strip()
@@ -805,8 +783,10 @@ def types(model_name):
 
 
     _input("types")
     _input("types")
     lst = set([])
     lst = set([])
-    output = _handle_output("Success: ", split=True)
-    for v in output:
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    for v in output.split("\n"):
         m, mm = v.split(":")
         m, mm = v.split(":")
         m = m.strip()
         m = m.strip()
         lst.add(m)
         lst.add(m)
@@ -818,8 +798,10 @@ def types_full(model_name):
 
 
     _input("types")
     _input("types")
     lst = set([])
     lst = set([])
-    output = _handle_output("Success: ", split=True)
-    for v in output:
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    for v in output.split("\n"):
         m, mm = v.split(":")
         m, mm = v.split(":")
         m = m.strip()
         m = m.strip()
         mm = mm.strip()
         mm = mm.strip()
@@ -831,7 +813,8 @@ def read(model_name, ID):
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["read", ID])
     _input(["read", ID])
-    v = _handle_output("Success: ", split=True)
+    output = _handle_output("Success: ", split=" ")
+    v = output.split("\n")
     t = v[1].split(":")[1].strip()
     t = v[1].split(":")[1].strip()
     if (not v[2].startswith("Source:")):
     if (not v[2].startswith("Source:")):
         rval = (t, None)
         rval = (t, None)
@@ -846,10 +829,11 @@ def read_attrs(model_name, ID):
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["read", ID])
     _input(["read", ID])
-    output = _handle_output("Success: ", split=True)
+    output = _handle_output("Success: ", split=" ")
+    v = output.split("\n")
     searching = True
     searching = True
     rval = {}
     rval = {}
-    for r in output:
+    for r in v:
         if searching:
         if searching:
             if r == "Attributes:":
             if r == "Attributes:":
                 # Start working on attributes
                 # Start working on attributes
@@ -878,7 +862,7 @@ def instantiate(model_name, typename, edge=None, ID=""):
         _input(["instantiate_node", typename, ID])
         _input(["instantiate_node", typename, ID])
     else:
     else:
         _input(["instantiate_edge", typename, ID, edge[0], edge[1]])
         _input(["instantiate_edge", typename, ID, edge[0], edge[1]])
-    return _handle_output("Success: ", split=True)[0]
+    return _handle_output("Success: ", split=" ")
 
 
 def delete_element(model_name, ID):
 def delete_element(model_name, ID):
     """Delete the element with the given ID"""
     """Delete the element with the given ID"""
@@ -922,30 +906,36 @@ def read_outgoing(model_name, ID, typename):
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["read_outgoing", ID, typename])
     _input(["read_outgoing", ID, typename])
-    output = _handle_output("Success: ", split=True)
-    return set(output)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    else:
+        return set(output.split("\n"))
 
 
 def read_incoming(model_name, ID, typename):
 def read_incoming(model_name, ID, typename):
     """Returns a list of all incoming associations of a specific type ("" = all)"""
     """Returns a list of all incoming associations of a specific type ("" = all)"""
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["read_incoming", ID, typename])
     _input(["read_incoming", ID, typename])
-    output = _handle_output("Success: ", split=True)
-    return set(output)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    else:
+        return set(output.split("\n"))
 
 
 def read_association_source(model_name, ID):
 def read_association_source(model_name, ID):
     """Returns the source of an association."""
     """Returns the source of an association."""
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["read_association_source", ID])
     _input(["read_association_source", ID])
-    return _handle_output("Success: ", split=True)[0]
+    return _handle_output("Success: ", split=" ")
 
 
 def read_association_destination(model_name, ID):
 def read_association_destination(model_name, ID):
     """Returns the destination of an association."""
     """Returns the destination of an association."""
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["read_association_destination", ID])
     _input(["read_association_destination", ID])
-    return _handle_output("Success: ", split=True)[0]
+    return _handle_output("Success: ", split=" ")
 
 
 ##### To document:
 ##### To document:
 
 
@@ -965,7 +955,7 @@ def service_register(name, function):
 
 
     # Now we are in service-mode
     # Now we are in service-mode
     mode = MODE_SERVICE
     mode = MODE_SERVICE
-    port = _handle_output("Success: ", split=True)[0]
+    port = _handle_output("Success: ", split=" ")
 
 
     # Process events in the background!
     # Process events in the background!
     threading.Thread(target=service_process, args=[port]).start()
     threading.Thread(target=service_process, args=[port]).start()
@@ -1006,7 +996,7 @@ def element_list_nice(model_name):
 
 
     _input(["element_list_nice", model_name, _get_metamodel(model_name)])
     _input(["element_list_nice", model_name, _get_metamodel(model_name)])
 
 
-    data = _handle_output("Success: ", split=True)[0]
+    data = _handle_output("Success: ", split=" ")
     try:
     try:
         return json.loads(data)
         return json.loads(data)
     except:
     except:
@@ -1018,23 +1008,29 @@ def connections_between(model_name, source_element, target_element):
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["connections_between", source_element, target_element])
     _input(["connections_between", source_element, target_element])
-    output = _handle_output("Success: ", split=True)
-    return set(output)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    else:
+        return set(output.split("\n"))
 
 
 def define_attribute(model_name, node, attr_name, attr_type):
 def define_attribute(model_name, node, attr_name, attr_type):
     """Create a new attribute, which can be instantiated one meta-level below."""
     """Create a new attribute, which can be instantiated one meta-level below."""
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["define_attribute", node, attr_name, attr_type])
     _input(["define_attribute", node, attr_name, attr_type])
-    return _handle_output("Success: ", split=True)[0]
+    return _handle_output("Success: ", split=" ")
 
 
 def all_instances(model_name, type_name):
 def all_instances(model_name, type_name):
     """Returns a list of all elements of a specific type."""
     """Returns a list of all elements of a specific type."""
     _goto_mode(MODE_MODIFY, model_name)
     _goto_mode(MODE_MODIFY, model_name)
 
 
     _input(["all_instances", type_name])
     _input(["all_instances", type_name])
-    output = _handle_output("Success: ", split=True)
-    return set(output)
+    output = _handle_output("Success: ", split=" ")
+    if output == "":
+        return set([])
+    else:
+        return set(output.split("\n"))
 
 
 def service_poll(port):
 def service_poll(port):
     """Checks whether or not the Modelverse side has any input ready to be processed."""
     """Checks whether or not the Modelverse side has any input ready to be processed."""

File diff suppressed because it is too large
+ 1063 - 0
wrappers/modelverse_sccd.py