Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added types as def for server and tool +changed schema endpoint #2

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/digital_twin_tooling/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@

from digital_twin_tooling.app import project_api
from digital_twin_tooling.app import project_execution_api
from digital_twin_tooling.app import server_api
22 changes: 15 additions & 7 deletions src/digital_twin_tooling/app/project_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@

def add_ids(conf):
if 'configurations' in conf:
confgis= conf['configurations']
confgis = conf['configurations']
for c in confgis:
if 'id' not in c:
c.update({'id':str(uuid.uuid4())})
c.update({'id': str(uuid.uuid4())})
if 'tasks' in c:
for t in c['tasks']:
if 'id' not in t:
t.update({'id': str(uuid.uuid4())})


@app.route('/')
def index():
"""Base uel.
Expand All @@ -36,7 +37,7 @@ def index():
return "Welcome"


@app.route('/project/schemas', methods=['GET'])
@app.route('/project/schema', methods=['GET'])
def get_project_schemas():
"""List all schemas
---
Expand All @@ -49,7 +50,7 @@ def get_project_schemas():
with project_mgmt.get_schema(version="0.0.2") as stream:
schema = yaml.load(stream, Loader=yaml.FullLoader)
return app.response_class(
response=json.dumps([schema]),
response=json.dumps(schema),
status=200,
mimetype='application/json'
)
Expand All @@ -67,7 +68,7 @@ def project_list():
"""
base = Path(app.config["PROJECT_BASE"])

return json.dumps([f.parent.name for f in base.glob('*/projects.yml')])
return json.dumps([f.parent.name for f in base.glob('*/project.yml')])


@app.route('/projects/<projectname>', methods=['POST'])
Expand Down Expand Up @@ -322,13 +323,20 @@ def project_post_configurations_create(projectname):
if request.json:
new_data = request.json

new_data.update({'id': str(uuid.uuid4())})

with open(path, 'r') as f:
conf = yaml.load(f, Loader=yaml.FullLoader)

if 'configurations' not in conf:
conf['configurations'] = []

# Add id if not present. If present verify that id is unique
if not 'id' in new_data:
new_data.update({'id': str(uuid.uuid4())})
else:
for c in conf['configurations']:
if 'id' in c and c['id'] == new_data['id']:
abort(400, f"Id '{new_data['id']}' is not unique!")

conf['configurations'].append(new_data)

try:
Expand Down
29 changes: 29 additions & 0 deletions src/digital_twin_tooling/app/server_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@


from digital_twin_tooling.app import app
from flask import request

@app.route('/server/shutdown', methods=['GET'])
def get_server_shutdown():
"""List all schemas
---

responses:
200:
description: Accepted shutdown

"""
shutdown_server()

return app.response_class(
response="Shutting down..",
status=200,
mimetype='text/plain'
)


def shutdown_server():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
20 changes: 19 additions & 1 deletion src/digital_twin_tooling/data/schema-0.0.2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ properties:
"^[a-zA-Z0-9._-]+$":
type: object
properties:
type:
description: The type of tool
$ref: '#/$defs/tool_type'
path:
description: Local path to the tool may be relative to this file
type: string
Expand Down Expand Up @@ -53,7 +56,8 @@ $defs:
port:
type: integer
type:
type: string
description: The type of server
$ref: '#/$defs/server_type'
embedded:
type: boolean
required:
Expand Down Expand Up @@ -123,6 +127,9 @@ $defs:
"^.*$":
type: object
properties:
name:
description: User friendly name of the signal
type: string
source:
description: A source signal definition, describing how to obtain the signal and its type once decoded
type: object
Expand Down Expand Up @@ -169,6 +176,17 @@ $defs:
- boolean
- string

server_type:
description: The valid server types
enum:
- AMQP

tool_type:
description: The valid tool types
enum:
- rabbitmq
- maestroV2

maestro_v2:
description: 'Maestro v2 configuration'
type: object
Expand Down
4 changes: 2 additions & 2 deletions src/digital_twin_tooling/project_mgmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ def prepare_data_repeater(conf, data_repeater_conf, output_dir: Path, base_dir=P
import tempfile
with tempfile.NamedTemporaryFile(prefix="AMQP-PROXY", suffix=".fmu", dir=str(output_dir),
delete=False) as output_file:

tool_path = Path(conf['tools']['rabbitmq']['path'])
toolId = data_repeater_conf['prepare']['tool']
tool_path = Path(conf['tools'][toolId]['path'])
if not tool_path.is_absolute():
tool_path = base_dir / tool_path

Expand Down
7 changes: 0 additions & 7 deletions tests/digital_twin_tooling/basic2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ servers:
type: AMQP
embedded: true

server_98:
name: Implicit embedded SQLite datastore
type: MQLite
embedded: true



configurations:
- name: data loging of Watertank from Remote AMQP System 1
tasks:
Expand Down
5 changes: 3 additions & 2 deletions tests/digital_twin_tooling/test_api_project_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
class TestProjectData(BaseCase):

def test_project_schema(self):
response = self.app.get('/project/schemas')
response = self.app.get('/project/schema')
self.assertEqual(200, response.status_code)
self.assertEqual(1, len(response.json))
self.assertTrue(response.is_json)
self.assertEqual(5, len(response.json))


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions tests/digital_twin_tooling/test_api_project_manipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_post_sub_element_server(self):
server_json = yaml.safe_load('''
server_98:
name: Implicit embedded SQLite datastore
type: MQLite
type: AMQP
embedded: true''')

response = self.app.post('/projects/p1/config/servers', headers={"Content-Type": "application/json"},
Expand All @@ -110,7 +110,7 @@ def test_post_sub_element_tools(self):
server_json = yaml.safe_load('''
my_tool:
name: Some random toop
type: MaestroV2
type: maestroV2
path: tools/something.jar''')

response = self.app.post('/projects/p1/config/tools', headers={"Content-Type": "application/json"},
Expand Down