|
|
@@ -5,19 +5,19 @@ If you want to use the Modelverse on an as of yet unsupported platform, you will
|
|
|
While it is possible to directly send HTTP requests, it is recommended to create a wrapper, similar to the Python wrapper mentioned before.
|
|
|
Otherwise, many of the more complex operations (e.g., process enactment) will quickly result in problems.
|
|
|
Now follows a detailed description of how the HTTP interface works.
|
|
|
-An explanation of the semantics of these operations can be found in the Python wrapper.
|
|
|
-An example implementation can be found in the Python wrapper, which should prove a valuable starting point for creating a new interface.
|
|
|
+An explanation of the semantics of these operations can be found in the Python wrapper, as these operations are almost a 1-to-1 mapping, with the Python wrapper being a reference implementation.
|
|
|
+The Python wrapper proves a valuable starting point for creating new interfaces.
|
|
|
|
|
|
Request and Reply format
|
|
|
------------------------
|
|
|
|
|
|
HTTP requests to the Modelverse use the POST format, and should be directed at the location at which the Modelverse server is running.
|
|
|
-The request itself is a URL encoded form of the following dictionary: {"op": operation, "value": value, "taskname": taskname}.
|
|
|
+The request itself is a URL encoded form of the following dictionary: ``{"op": operation, "value": value, "taskname": taskname}``.
|
|
|
In this format, the operation is either *set_input* or *get_output*, with the logical meanings (see further).
|
|
|
Value is only present if the operation is *set_input*, and contains a JSON serialized value to set as input.
|
|
|
For multiple simultaneous requests, it is possible to not use a key *value*, but a key *data*.
|
|
|
If the data key is present, this should contain a JSON serialized representation of multiple invocations.
|
|
|
-The semantics is identical, except that only a single HTTP request (and reply) is used.
|
|
|
+The semantics is identical, except that only a single HTTP request (and reply) is used, thereby optimizing performance.
|
|
|
Finally, the taskname indicates the task to which the request is targetted.
|
|
|
Tasknames are provided by the Modelverse when necessary.
|
|
|
Fetching data from the Modelverse is done using the *get_output* operation, which is blocking until an output is present.
|
|
|
@@ -27,42 +27,44 @@ Output requests are handled in a FIFO manner, as multiple calls can be made for
|
|
|
|
|
|
Apart from the primitive types usually supported by JSON, action language primitives can also be sent.
|
|
|
These are JSON serialized as a dictionary, with a single key *value* and its value being the string representation of the element.
|
|
|
-For example, an *If* construct is serialized as {"value":"If"}.
|
|
|
-The Modelverse understands this special case, but your interface should also be able to handle such data.
|
|
|
+For example, an *If* construct is serialized as ``{"value":"If"}``.
|
|
|
+The Modelverse understands this special case, but the interface should also be able to handle such data.
|
|
|
Note that communication of these internal primitive types is extremely rare.
|
|
|
|
|
|
-The reply to this request is simple.
|
|
|
+The reply is always very simple.
|
|
|
For a *set_input* operation, the reply merely indicates that the input is put in the input queue of the task, and the content of the reply can be ignored.
|
|
|
+This does **NOT** mean that the input has been processed by the task itself, but only that the input is visible to the task.
|
|
|
For a *get_output* operation, the reply contains a JSON serialized representation of the output data put in the Modelverse.
|
|
|
This is always a primitive type of JSON, and will never be a list or dictionary.
|
|
|
|
|
|
.. note::
|
|
|
- Communication over HTTP uses a POST request to allow for unlimited amounts of data to be transfered.
|
|
|
- Instead, the request parameters, normally part of the GET URL, are sent as data of the POST request.
|
|
|
+ Communication over HTTP uses a POST request to allow for arbitrary amounts of data to be transfered.
|
|
|
The Modelverse ignores GET requests.
|
|
|
- This nicely follows the REST standards, as all requests indeed alter the state of the Modelverse (contrary to GET requests).
|
|
|
+ This nicely follows the REST standards, as all requests indeed have the potential to alter the state of the Modelverse: only the MvK gives semantics to the operations, and a *read* command could very well write out something.
|
|
|
|
|
|
Examples
|
|
|
^^^^^^^^
|
|
|
|
|
|
-To send the integer 1 to the task with name abc in the Modelverse, send the following data in the POST request::
|
|
|
+To send the integer 1 to the task with name *abc* in the Modelverse, send the following data in the POST request::
|
|
|
|
|
|
op=set_input&value=1&taskname=abc
|
|
|
|
|
|
-To send the string def to the task with name xyz in the Modelverse, send the following data in the POST request::
|
|
|
+To send the string *def* to the task with name *xyz* in the Modelverse, send the following data in the POST request::
|
|
|
|
|
|
op=set_input&value="def"&taskname=xyz
|
|
|
|
|
|
-To send both the integer 1 and the string def to the task with name abc in the Modelverse, send either two seperate requests, or a single request::
|
|
|
+To send both the integer 1 and the string *def* to the task with name *abc* in the Modelverse, send either two seperate requests, or a single request::
|
|
|
|
|
|
op=set_input&data=[1,"def"]&taskname=xyz
|
|
|
|
|
|
-To fetch the output value of a task xyz in the Modelverse, send the following HTTP request, which yields (possibly) the following answer::
|
|
|
+To fetch the output value of a task *xyz* in the Modelverse, send the following HTTP request, which yields (possibly) the following answer::
|
|
|
|
|
|
op=get_output&taskname=xyz
|
|
|
|
|
|
"The output value is a string containing a JSON serialized value."
|
|
|
|
|
|
+Additional keys can be provided, but they are ignored by the Modelverse.
|
|
|
+
|
|
|
Startup
|
|
|
-------
|
|
|
|
|
|
@@ -72,20 +74,21 @@ This is done by fetching the output of the task manager as follows::
|
|
|
|
|
|
op=get_output&taskname=task_manager
|
|
|
|
|
|
-The reply to this query contains the taskname that can be used in subsequent requests.
|
|
|
+The reply to this query contains a new taskname to be used in subsequent requests.
|
|
|
|
|
|
-For legacy purposes, it is also possible to send a new taskname to the task manager directly, which will subsequently be generated.
|
|
|
+For legacy purposes, it is also possible to send a new taskname to the task manager directly, which will subsequently be generated if it doesn't exist yet.
|
|
|
This approach is deprecated, as it is easy to run into problems when two users request the same taskname.
|
|
|
-These problems are avoided when using the new approach.
|
|
|
-Additionally, the new approach allows the task manager to cache new tasks, such that they are available much sooner.
|
|
|
+These problems are avoided when using the new approach, as the Modelverse guarantees that it always outputs a unique taskname.
|
|
|
+Additionally, the new approach allows the task manager to prepare new tasks, such that they are available much sooner.
|
|
|
|
|
|
Operations
|
|
|
----------
|
|
|
|
|
|
Upon startup of a task, the communication starts in verbose mode to allow for interactive use.
|
|
|
This means that initially, every sent input will result in one (or multiple) output values.
|
|
|
-For a wrapper this is cumbersome, as it creates a lot of HTTP requests, and therefore it can be disabled with the input *quiet*.
|
|
|
-A more detailed overview of all operations, their order and possible interleavings, and their possible responses, we refer to the SCCD model in *wrappers/classes/modelverse.xml*.
|
|
|
+For a wrapper this is cumbersome, as it creates a lot of HTTP requests (and overhead).
|
|
|
+It is possible to reduce the amount of communication by sending the input *quiet*.
|
|
|
+For a more detailed overview of all operations, their order and possible interleavings, and their possible responses, we refer to the SCCD model in *wrappers/classes/modelverse.xml*.
|
|
|
|
|
|
The first two input values that are to be sent are the username and password, which can happen using the following request::
|
|
|
|
|
|
@@ -104,7 +107,7 @@ Megamodelling
|
|
|
|
|
|
In megamodelling mode, which is the first mode to be entered after login, users can modify the megamodel, containing the relation of all models in the Modelverse.
|
|
|
It is in this mode that new models should be created, models should be deleted, or new transformations be defined.
|
|
|
-Additionally, as all user access control is modelled explicitly, this is also the mode in which user management is done.
|
|
|
+Additionally, as all user access control is modelled explicitly in this same megamodel, this is also the mode in which user management is done.
|
|
|
|
|
|
There are two operations to allow mode switching: *model_modify* and *service_register*.
|
|
|
To go to modelling, send *model_modify*, followed by the name of the model you wish to open and the name of the metamodel that should be used.
|
|
|
@@ -124,14 +127,14 @@ Most are trivial to deserialize when the result comes in, and therefore we refer
|
|
|
While operation and parameters are shown distinct in the table, the HTTP request merely sends them in exactly the same fashion.
|
|
|
For example::
|
|
|
|
|
|
- op=set_input&data=["model_mode","formalisms/ProcessModel","formalisms/PM"]&taskname=xyz
|
|
|
+ op=set_input&data=["model_modify","formalisms/ProcessModel","formalisms/PM"]&taskname=xyz
|
|
|
|
|
|
For each operation, we specify some information on the return value.
|
|
|
-If the return value is only "Success", this means that no return value is sent.
|
|
|
-Otherwise, the return value starts with "Success: ", and the return value starts afterwards.
|
|
|
+If the return value is only *"Success"*, this means that no return value is sent.
|
|
|
+Otherwise, the return value starts with *"Success: "*, and the return value starts afterwards.
|
|
|
This is used to distinguish successful execution from exceptions.
|
|
|
The returnvalue can consist of a single value, or of a list of values, encoded as a single string, separated by newline characters.
|
|
|
-For example, the result of "model_list" can be the string "Success: a\nb\nc", indicating that execution was successful and that the models a, b, and c are present at the requested location.
|
|
|
+For example, the result of *"model_list"* can be the string *"Success: a\nb\nc"*, indicating that execution was successful and that the models *a*, *b*, and *c* are present at the requested location.
|
|
|
More complex returnvalues specify multiple elements in a single line (i.e., a tuple), for which the order and encoding is described in more detail.
|
|
|
|
|
|
Some more complex operations are mentioned below these standard operations.
|
|
|
@@ -187,13 +190,13 @@ process_execute process_name, model_bindings\* (none)
|
|
|
|
|
|
Parameters marked with a \* are actually dictionaries, and should be sent as such.
|
|
|
Since the Modelverse has no primitive notion of dictionaries, a dictionary is expanded as a sequence of key value pairs, terminated with an empty key.
|
|
|
-For example, the dictionary {"abc": "def", "ghi": "jkl"} is sent as five individual requests (or a single data request)::
|
|
|
+For example, the dictionary ``{"abc": "def", "ghi": "jkl"}`` is sent as five individual requests (or a single data request)::
|
|
|
|
|
|
...&data=["abc","def","ghi","jkl",""]&...
|
|
|
|
|
|
For the model_overwrite operation, the Modelverse will first perform some checks as to whether the overwritten model can indeed be overwritten.
|
|
|
If so, it will output the reply *Waiting for model constructors...*, after which the actual code may be sent.
|
|
|
-The operations starting with transformation_add are similar, but they have two phases.
|
|
|
+The operations starting with *transformation_add* are similar, but they have two phases.
|
|
|
First, they output the name of the merged metamodel, ready to be RAMified.
|
|
|
There is then the possibility to modify this metamodel before RAMification starts, by logging in using a different task, modifying the model, and storing the changes.
|
|
|
As soon as all changes are made, any input will initiate RAMification.
|
|
|
@@ -201,13 +204,13 @@ Second, the Modelverse will query for the code that specify the transformation.
|
|
|
For manual operations, this query is not done.
|
|
|
For AL, this query expects ActionLanguage code.
|
|
|
For MT, this query expects a model conforming to the RAMified metamodel.
|
|
|
-Of course, these constructors can be passed an empty model, in which case the models have to be updated later on using model_modify.
|
|
|
+Of course, these constructors can be passed an empty model, in which case the models have to be updated later on using *model_modify*.
|
|
|
|
|
|
-The transformation_execute operation and process_execute are special operations, in the sense that they (potentially) spawn other tasks.
|
|
|
+The *transformation_execute* operation and *process_execute* are special operations, in the sense that they (potentially) spawn other tasks.
|
|
|
The output value of these operations is the name of a newly spawned task, on which execution should continue.
|
|
|
These tasks might not be identical to other tasks, in the sense that they are purely able to communicate with the currently executing operation.
|
|
|
This operation is rather complex, and we refer to the SCCD model for detailed information.
|
|
|
-The process_execute operation is similar, but instead of outputting only a single taskname, we output multiple, combined with the activity that spawned it.
|
|
|
+The *process_execute* operation is similar, but instead of outputting only a single taskname, we output multiple, combined with the activity that spawned it.
|
|
|
|
|
|
Modelling
|
|
|
^^^^^^^^^
|
|
|
@@ -246,9 +249,10 @@ undefine_attribute element, attribute (none)
|
|
|
============================ ============================= ======================================================
|
|
|
|
|
|
Some additional operations are again available that work in two phases.
|
|
|
-These operations are *attr_add_code* and *upload*, which first perform some checks and then wait for AL code or a model, again using the "Waiting for X constructors..." output.
|
|
|
+These operations are *attr_add_code* and *upload*, which first perform some checks and then wait for AL code or a model, again using the *"Waiting for X constructors..."* output.
|
|
|
|
|
|
Service
|
|
|
^^^^^^^
|
|
|
|
|
|
In service mode, the Modelverse blocks until the input *service_stop* is received, and this task is used to process the service.
|
|
|
+While in this mode, this task is used to communicate with the various external services connecting to it.
|