Skip to content
Snippets Groups Projects
Commit 6b31ef77 authored by Michele Chiari's avatar Michele Chiari
Browse files

Add y1 DMC code.

parents
No related branches found
No related tags found
No related merge requests found
Showing with 975 additions and 0 deletions
*~
*__pycache__*
.vscode
docs/_build
FROM python:3.9.12-bullseye
COPY . /opt/mc_openapi
RUN useradd -mU mc
USER mc
ENV PATH="/home/mc/.local/bin:${PATH}"
RUN pip install -r /opt/mc_openapi/requirements.txt
WORKDIR /opt/mc_openapi
CMD ["uwsgi", "--http", ":80", "--yaml", "uwsgi_config.yaml"]
# PIACERE Model Checker REST API server
This project is packaged with [Poetry](https://python-poetry.org/).
## Build and Run
Build with
```sh
poetry install
```
then run with
```sh
poetry run python -m mc_openapi
```
Run tests with:
```sh
poetry run python -m pytest
```
## Run with uWSGI
The project may be run with [uWSGI](https://uwsgi-docs.readthedocs.io/) as follows:
```sh
uwsgi --http :8080 --yaml uwsgi_config.yaml
```
## Run with Docker
First, build the docker image with the usual
```sh
docker build -t wp4/dmc .
```
And then run it with
```sh
docker run -d wp4/dmc
```
The uWSGI server will be running and listening on port 80 of the container.
## REST APIs
The OpenAPI definition of the REST APIs is in `mc_openapi/openapi/model_checker.yaml`.
The APIs can also be browsed with [Swagger UI](https://swagger.io/tools/swagger-ui/) by appending `/ui/` to the API HTTP address.
For APIs usage examples, you may look into the tests, in `tests/test_mc_openapi.py`.
Two DOML examples in XMI format are sent to the server.
One of them is correct (`tests/doml/nginx-openstack_v2.domlx`), and the server answers with `"sat"` (meaning the requirements are satisfied), and the other one contains an error (`tests/doml/nginx-openstack_v2_wrong.domlx`), so the server answers with `"unsat"`.
**Note:** for the time being, the `model` field of the POST request's body accepts any XML object. This will be changed to the DOML XMI schema when possible.
appnope==0.1.3 ; python_version >= "3.9" and python_version < "4.0" and platform_system == "Darwin" or python_version >= "3.9" and python_version < "4.0" and sys_platform == "darwin"
asttokens==2.0.5 ; python_version >= "3.9" and python_version < "4.0"
atomicwrites==1.4.1 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32"
attrs==22.1.0 ; python_version >= "3.9" and python_version < "4.0"
backcall==0.2.0 ; python_version >= "3.9" and python_version < "4.0"
certifi==2022.6.15 ; python_version >= "3.9" and python_version < "4"
cffi==1.15.1 ; python_version >= "3.9" and python_version < "4.0" and implementation_name == "pypy"
charset-normalizer==2.1.0 ; python_version >= "3.9" and python_version < "4"
colorama==0.4.5 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.9" and python_version < "4.0" and platform_system == "Windows"
colorful==0.5.4 ; python_version >= "3.9" and python_version < "4.0"
debugpy==1.6.2 ; python_version >= "3.9" and python_version < "4.0"
decorator==5.1.1 ; python_version >= "3.9" and python_version < "4.0"
entrypoints==0.4 ; python_version >= "3.9" and python_version < "4.0"
executing==0.9.1 ; python_version >= "3.9" and python_version < "4.0"
idna==3.3 ; python_version >= "3.9" and python_version < "4"
iniconfig==1.1.1 ; python_version >= "3.9" and python_version < "4.0"
ipykernel==6.15.1 ; python_version >= "3.9" and python_version < "4.0"
ipython==8.4.0 ; python_version >= "3.9" and python_version < "4.0"
jedi==0.18.1 ; python_version >= "3.9" and python_version < "4.0"
jupyter-client==7.3.4 ; python_version >= "3.9" and python_version < "4.0"
jupyter-core==4.11.1 ; python_version >= "3.9" and python_version < "4.0"
matplotlib-inline==0.1.3 ; python_version >= "3.9" and python_version < "4.0"
nest-asyncio==1.5.5 ; python_version >= "3.9" and python_version < "4.0"
packaging==21.3 ; python_version >= "3.9" and python_version < "4.0"
parso==0.8.3 ; python_version >= "3.9" and python_version < "4.0"
pexpect==4.8.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32"
pickleshare==0.7.5 ; python_version >= "3.9" and python_version < "4.0"
pluggy==1.0.0 ; python_version >= "3.9" and python_version < "4.0"
prettyprinter==0.18.0 ; python_version >= "3.9" and python_version < "4.0"
prompt-toolkit==3.0.30 ; python_version >= "3.9" and python_version < "4.0"
psutil==5.9.1 ; python_version >= "3.9" and python_version < "4.0"
ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32"
pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "4.0"
py==1.11.0 ; python_version >= "3.9" and python_version < "4.0"
pycparser==2.21 ; python_version >= "3.9" and python_version < "4.0" and implementation_name == "pypy"
pygments==2.12.0 ; python_version >= "3.9" and python_version < "4.0"
pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "4.0"
pytest==6.2.5 ; python_version >= "3.9" and python_version < "4.0"
python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "4.0"
pywin32==304 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.9" and python_version < "4.0"
pyzmq==23.2.0 ; python_version >= "3.9" and python_version < "4.0"
requests==2.28.1 ; python_version >= "3.9" and python_version < "4"
six==1.16.0 ; python_version >= "3.9" and python_version < "4.0"
stack-data==0.3.0 ; python_version >= "3.9" and python_version < "4.0"
toml==0.10.2 ; python_version >= "3.9" and python_version < "4.0"
tornado==6.2 ; python_version >= "3.9" and python_version < "4.0"
traitlets==5.3.0 ; python_version >= "3.9" and python_version < "4.0"
urllib3==1.26.11 ; python_version >= "3.9" and python_version < "4"
wcwidth==0.2.5 ; python_version >= "3.9" and python_version < "4.0"
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import sphinx_rtd_theme
# -- Project information -----------------------------------------------------
project = 'DOML Model Checker'
copyright = '2022, Michele Chiari and Michele De Pascalis'
author = 'Michele Chiari and Michele De Pascalis'
# The full version, including alpha/beta/rc tags
release = '1.0.0'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx_rtd_theme'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = []
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []
.. DOML Model Checker documentation master file, created by
sphinx-quickstart on Mon Jul 11 15:00:34 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
DOML Model Checker's documentation
==================================
The DOML Model Checker is a component of the `PIACERE`_ framework
in charge of checking the correctness and consistency of `DOML`_ models.
.. toctree::
:maxdepth: 2
:caption: Contents:
installation
usage
requirements
restapis
..
Indices and tables
==================
.. * :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
This project has received funding from the European Union's Horizon 2020
research and innovation programme under grant agreement No. 101000162.
.. _PIACERE: https://www.piacere-project.eu/
.. _DOML: https://www.piacere-doml.deib.polimi.it/
Installation
============
The DOML Model Checker receives user inputs through its REST APIs.
In this guide we illuestrate saveral ways of setting up the server for these APIs.
Build and run locally for testing
---------------------------------
This project is packaged with `Poetry`_, which we assume you have already
`installed <https://python-poetry.org/docs/#installation>`_ into your system.
Build with::
poetry install
then run with::
poetry run python -m mc_openapi
this command serves the APIs through a `Flask`_ instance,
which is suitable for testing, but not recommended for production.
You may read the API specification generated by `Swagger-UI`_ by
pointing your browser to http://127.0.0.1:8080/ui/.
Then, run tests with::
poetry run python -m pytest
Run locally with uWSGI
----------------------
The project may be run with `uWSGI`_,
which is better-suited for production environments, as follows::
uwsgi --http :8080 -w mc_openapi.app_config -p 4
Run with Docker
---------------
The best way of deploying the DOML Model Checker is by using `Docker`_.
First, build the docker image with the usual::
docker build -t wp4/dmc .
And then run it with::
docker run -d wp4/dmc
The uWSGI server will be running and listening on port 80 of the container.
Building the Documentation
--------------------------
The documentation has been written in `Sphinx`_.
To build it, type::
poetry shell
and then::
cd docs
make html
The documentation will be generated in ``docs/_build``.
.. _Poetry: https://python-poetry.org/
.. _Flask: https://flask.palletsprojects.com/
.. _Swagger-UI: https://swagger.io/tools/swagger-ui/
.. _uWSGI: https://uwsgi-docs.readthedocs.io/
.. _Docker: https://www.docker.com/
.. _Sphinx: https://www.sphinx-doc.org/
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
Checked Requirements
====================
The DOML Model Checker verifies DOML models against a collection of requirements
devised to highlight the most common mistakes made by users when specifying cloud deployments.
Here we list and describe such requirements.
VM Network Interfaces
---------------------
All virtual machines must be connected to at least one network interface.
Virtual machines can communicate with other components of a deployment or with external clients
only through an appropriately configured network.
this check makes sure no virtual machines are isolated.
Concretization of Software Interfaces
-------------------------------------
All software packages can see the interfaces they need through a common network.
This check makes sure all exposed and consumed software interfaces at the application layer level
have been actually concretized through a network connection that allows the involved components
to communicate.
Duplicated Interfaces
---------------------
There are no duplicated interfaces.
Checks whether two or more interfaces have been assigned the same IP address in the same network.
Deployed Software Components
----------------------------
All software components have been deployed to some node.
Makes sure that all software components specified in the application layer have been
associated to at least one node in the abstract infrastructure layer
through the currently active deployment.
Concretization of Abstract Infrastructure
-----------------------------------------
All abstract infrastructure elements are mapped to an element in the active concretization.
Makes sure all abstract infrastructure are concretized by the currently active concretization layer.
REST APIs
=========
The `OpenAPI`_ definition of the REST APIs is in ``mc_openapi/openapi/model_checker.yaml``.
The APIs can also be browsed with `Swagger UI`_ by appending ``/ui/`` to the APIs' HTTP address.
For APIs usage examples, you may look into the tests, in ``tests/test_mc_openapi.py``.
Some DOML examples in XMI format are sent to the server.
One of them is correct (``tests/doml/nginx-openstack_v2.domlx``),
and the server answers with ``"sat"`` (meaning the requirements are satisfied),
and the other one contains an error (``tests/doml/nginx-openstack_v2_wrong.domlx``),
so the server answers with ``"unsat"``.
.. _OpenAPI: https://www.openapis.org/
.. _Swagger UI: https://swagger.io/tools/swagger-ui/
Usage through the PIACERE IDE
=============================
Invoking the DOML Model Checker from the PIACERE IDE
-----------------------------------------------------
The DOML Model Checker is usually invoked from the PIACERE IDE.
It expects a DOML file in XMI format as its input,
so plain DOML files must be manually converted.
The workflow is as follows:
1. Right-click the DOML file to be checked in the IDE's left sidebar;
2. In the context-menu, select *Piacere* -> *Generate DOMLX Model*;
3. Pick a name for the .domlx file to be generated and click OK;
4. Right-click the newly-generated .domlx file;
5. In the context-menu, select *Piacere* -> *Validate DOML*.
After some time, the IDE will report the model checker's results in a new window.
Normally, verification can have two outcomes:
* *Your requirements are SATISFIED*:
this means your DOML model passed all the standard checks for common mistakes;
* *Your requirements are UNSATISFIED*:
this means the model checker has found a problem in your DOML model.
A description of the problem follows.
In case of errors in the verification process, the IDE reports them in a new window,
together with a description.
A common error is the following:
The supplied DOMLX model is malformed or its DOML version is unsupported.
This often happens because of a mismatch between the DOML version supported by the IDE
and the one supported by the model checker.
Settings
--------
The only model-checker-related settings you may customize from the PIACERE IDE
are the endpoint connection data.
Select the *Preferences* entry of the *Window* menu of the PIACERE IDE,
and then choose *Piacere* -> *Model Checker Preferences*.
Here you may enter the endpoint address and port, which is useful in case you want to
run the DOML Model Checker locally, instead of using the official deployment.
__version__ = '0.2.0'
#!/usr/bin/env python3
from mc_openapi.app_config import app
app.run(port=8080)
import connexion
app = connexion.App(__name__, specification_dir='openapi/')
app.add_api('model_checker.yaml')
application = app.app
This diff is collapsed.
commons:
DOMLElement:
attributes:
name:
type: String
multiplicity: "0..1"
description:
type: String
multiplicity: "0..1"
associations:
annotations:
class: commons_Property
multiplicity: "0..*"
Property:
attributes:
key:
type: String
multiplicity: "0..1"
associations:
reference:
class: commons_DOMLElement
multiplicity: "0..1"
IProperty:
superclass: commons_Property
attributes:
value:
type: Integer
multiplicity: "0..1"
SProperty:
superclass: commons_Property
attributes:
value:
type: String
multiplicity: "0..1"
FProperty:
superclass: commons_Property
attributes:
value:
type: String
multiplicity: "0..1"
BProperty:
superclass: commons_Property
attributes:
value:
type: Boolean
multiplicity: "0..1"
Configuration:
superclass: commons_DOMLElement
associations:
deployments:
class: commons_Deployment
multiplicity: "0..*"
Deployment:
associations:
component:
class: application_ApplicationComponent
multiplicity: "1"
node:
class: infrastructure_InfrastructureElement
multiplicity: "1"
application:
ApplicationLayer:
superclass: commons_DOMLElement
associations:
components:
class: application_ApplicationComponent
multiplicity: "0..*"
ApplicationComponent:
superclass: commons_DOMLElement
SoftwareComponent:
superclass: application_ApplicationComponent
attributes:
isPersistent:
type: Boolean
multiplicity: "1"
default: false
licenseCost:
type: String
multiplicity: "0..1"
configFile:
type: String
multiplicity: "0..1"
associations:
exposedInterfaces:
class: application_SoftwareInterface
mutiplicity: "0..*"
consumedInterfaces:
class: application_SoftwareInterface
mutiplicity: "0..*"
SaaS:
superclass: application_ApplicationComponent
attributes:
licenseCost:
type: String
multiplicity: "0..1"
associations:
exposedInterfaces:
class: application_SoftwareInterface
mutiplicity: "0..*"
SoftwareInterface:
superclass: application_ApplicationComponent
attributes:
endPoint:
type: String
multiplicity: "0..1"
DBMS:
superclass: application_SoftwareComponent
SaaSDBMS:
superclass: application_SaaS
infrastructure:
InfrastructureLayer:
superclass: commons_DOMLElement
associations:
nodes:
class: infrastructure_ComputingNode
multiplicity: "0..*"
networks:
class: infrastructure_Network
multiplicity: "0..*"
generators:
class: infrastructure_ComputingNodeGenerator
multiplicity: "0..*"
storages:
class: infrastructure_Storage
multiplicity: "0..*"
faas:
class: infrastructure_FunctionAsAService
multiplicity: "0..*"
credentials:
class: infrastructure_Credentials
multiplicity: "0..*"
groups:
class: infrastructure_ComputingGroup
multiplicity: "0..*"
InfrastructureElement:
superclass: commons_DOMLElement
ComputingNode:
superclass: infrastructure_InfrastructureElement
attributes:
architecture:
type: String
multiplicity: "0..1"
os:
type: String
multiplicity: "0..1"
memory:
type: String
multiplicity: "0..1"
storage:
type: String
multiplicity: "0..1"
cpu:
type: String
multiplicity: "0..1"
cost:
type: Integer # in cents
multiplicity: "0..1"
associations:
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
location:
class: infrastructure_Location
multiplicity: "0..1"
credentials:
class: infrastructure_Credentials
multiplicity: "0..1"
group:
class: infrastructure_ComputingGroup
multiplicity: "0..1"
inverse_of: infrastructure_ComputingGroup::groupedNodes
PhysicalComputingNode:
superclass: infrastructure_ComputingNode
VirtualMachine:
superclass: infrastructure_ComputingNode
attributes:
sizeDescription:
type: String
multiplicity: "0..1"
associations:
generatedFrom:
class: infrastructure_VMImage
multiplicity: "0..1"
Location:
superclass: commons_DOMLElement
attributes:
region:
type: String
multiplicity: "0..1"
zone:
type: String
multiplicity: "0..1"
Container:
superclass: infrastructure_ComputingNode
associations:
generatedFrom:
class: infrastructure_ContainerImage
multiplicity: "0..1"
hosts:
class: infrastructure_ComputingNode
multiplicity: "0..*"
ComputingNodeGenerator:
superclass: commons_DOMLElement
attributes:
uri:
type: String
multiplicity: "0..1"
kind:
type: GeneratorKind # enum { SCRIPT, IMAGE }
VMImage:
superclass: infrastructure_ComputingNodeGenerator
associations:
generatedVMs:
class: infrastructure_VirtualMachine
multiplicity: "0..*"
inverse_of: infrastructure_VirtualMachine::generatedFrom
ContainerImage:
superclass: infrastructure_ComputingNodeGenerator
associations:
generatedContainers:
class: infrastructure_Container
multiplicity: "0..*"
inverse_of: infrastructure_Container::generatedFrom
AutoScalingGroup:
superclass: infrastructure_ComputingNode
attributes:
min:
type: Integer
multiplicity: "0..1"
max:
type: Integer
multiplicity: "0..1"
loadBalancer:
type: String
multiplicity: "0..1"
associations:
machineDefinition:
class: infrastructure_VirtualMachine
multiplicity: "1"
deploymentNetwork:
class: infrastructure_Network
multiplicity: "0..1"
securityGroup:
class: infrastructure_SecurityGroup
multiplicity: "0..1"
Storage:
superclass: infrastructure_InfrastructureElement
attributes:
label:
type: String
multiplicity: "0..1"
size:
type: Integer # in MBs
multiplicity: "0..1"
cost:
type: Integer # in cents
multiplicity: "0..1"
associations:
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
FunctionAsAService:
superclass: infrastructure_InfrastructureElement
attributes:
cost:
type: Integer # in cents
multiplicity: "0..1"
associations:
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
Network:
superclass: commons_DOMLElement
attributes:
protocol:
type: String
multiplicity: "0..1"
address_lb:
type: Integer
multiplicity: "0..1"
address_ub:
type: Integer
multiplicity: "0..1"
associations:
connectedIfaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
inverse_of: infrastructure_NetworkInterface::belongsTo
igws:
class: infrastructure_InternetGateway
multiplicity: "0..*"
VPC:
superclass: infrastructure_Network
associations:
subnets:
class: infrastructure_Subnet
multiplicity: "0..*"
Subnet:
superclass: infrastructure_Network
associations:
connectedTo:
class: infrastructure_Network
multiplicity: "0..1"
NetworkInterface:
superclass: infrastructure_InfrastructureElement
attributes:
endPoint:
type: Integer
multiplicity: "0..1"
speed:
type: String
multiplicity: "0..1"
associations:
belongsTo:
class: infrastructure_Network
multiplicity: "0..1" # This should be "1", but it would break InternetGateway
associated:
class: infrastructure_SecurityGroup
multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails
InternetGateway:
superclass: infrastructure_NetworkInterface
ComputingGroup:
superclass: commons_DOMLElement
associations:
groupedNodes:
class: infrastructure_ComputingNode
multiplicity: "0..*"
inverse_of: infrastructure_ComputingNode::group
SecurityGroup:
superclass: infrastructure_ComputingGroup
associations:
rules:
class: infrastructure_Rule
multiplicity: "0..*"
ifaces:
class: infrastructure_NetworkInterface
multiplicity: "0..*"
inverse_of: infrastructure_NetworkInterface::associated
Rule:
superclass: commons_DOMLElement
attributes:
kind:
type: String
multiplicity: "1"
protocol:
type: String
multiplicity: "1"
fromPort:
type: Integer
multiplicity: "1"
toPort:
type: Integer
multiplicity: "1"
cidr:
type: String
multiplicity: "0..*"
Credentials:
superclass: commons_DOMLElement
KeyPair:
superclass: infrastructure_Credentials
attributes:
user:
type: String
multiplicity: "0..1"
keyfile:
type: String
multiplicity: "0..1"
algorithm:
type: String
multiplicity: "0..1"
bits:
type: Integer
multiplicity: "0..1"
UserPass:
superclass: infrastructure_Credentials
attributes:
username:
type: String
multiplicity: "1"
password:
type: String
multiplicity: "1"
SwarmRole:
superclass: commons_DOMLElement
attributes:
kind:
type: String
multiplicity: "1"
associations:
nodes:
class: infrastructure_ComputingNode
multiplicity: "0..*"
Swarm:
superclass: infrastructure_ComputingGroup
associations:
roles:
class: infrastructure_SwarmRole
multiplicity: "0..*"
ExtInfrastructureElement:
superclass: infrastructure_InfrastructureElement
concrete:
ConcreteInfrastructure:
superclass: commons_DOMLElement
associations:
providers:
class: concrete_RuntimeProvider
multiplicity: "0..*"
ConcreteElement:
superclass: commons_DOMLElement
attributes:
configurationScript:
type: String
multiplicity: "0..1"
RuntimeProvider:
superclass: commons_DOMLElement
associations:
vms:
class: concrete_VirtualMachine
multiplicity: "0..*"
vmImages:
class: concrete_VMImage
multiplicity: "0..*"
containerImages:
class: concrete_ContainerImage
multiplicity: "0..*"
networks:
class: concrete_Network
multiplicity: "0..*"
storages:
class: concrete_Storage
multiplicity: "0..*"
faas:
class: concrete_FunctionAsAService
multiplicity: "0..*"
group:
class: concrete_ComputingGroup
multiplicity: "0..*"
VirtualMachine:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_VirtualMachine
multiplicity: "0..1"
VMImage:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_VMImage
multiplicity: "0..1"
ContainerImage:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_ContainerImage
multiplicity: "0..1"
Network:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_Network
multiplicity: "0..1"
Storage:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_Storage
multiplicity: "0..1"
FunctionAsAService:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_FunctionAsAService
multiplicity: "0..1"
ComputingGroup:
superclass: concrete_ConcreteElement
associations:
maps:
class: infrastructure_AutoScalingGroup
multiplicity: "1"
from pyecore.resources import URI
from io import BytesIO
class BytesURI(URI):
def __init__(self, uri, bytes=None):
super(BytesURI, self).__init__(uri)
if bytes is not None:
self.__stream = BytesIO(bytes)
def getvalue(self):
return self.__stream.getvalue()
def create_instream(self):
return self.__stream
def create_outstream(self):
self.__stream = BytesIO()
return self.__stream
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment