-
Notifications
You must be signed in to change notification settings - Fork 2
/
ScyllaApi.py
130 lines (96 loc) · 4.76 KB
/
ScyllaApi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from os.path import isfile, join
from flask import Flask, request, send_file
from flask_restful import Resource, Api
from flask_cors import CORS
import subprocess
import os
import sys
from werkzeug.utils import secure_filename
# Usage: TODO add some documentation here
#TODO react to cancellation
scyllaPath = sys.argv[1]
# helper functions:
def fileInDirectory(my_dir: str):
return [f for f in os.listdir(my_dir) if isfile(join(my_dir, f))]
def listCompare(beforeList: list, afterList: list):
return [x for x in afterList if x not in beforeList]
def inDirectory(myDir: str):
return [x for x in os.listdir(myDir)]
def runScylla(projectDir : str, globConfigPath, simConfigPath, bpmnPath):
# run Scylla: #LB: Just give the output folder as parameter to scylla ...
beforeList = inDirectory(projectDir)
run_scylla_command = ('java -jar ' + scyllaPath + ' --headless --enable-bps-logging').split() + ['--config=' + globConfigPath, '--bpmn=' + bpmnPath, '--sim=' + simConfigPath]
print(' '.join(run_scylla_command))
process = subprocess.Popen(run_scylla_command, stdout=subprocess.PIPE)
output, errors = process.communicate()
console = output.decode('utf-8')
afterList = inDirectory(projectDir)
# new folder created from Scylla:
newInDir = listCompare(beforeList, afterList)
if len(newInDir) == 0:
raise Exception("No output folders created by scylla!")
elif len(newInDir) == 1:
newScyllaOutFolder = newInDir.pop()
else:
raise Exception("More folders than one created by scylla!")
return (console, newScyllaOutFolder)
# define Api
app = Flask("ScyllaApi")
CORS(app)
api = Api(app)
# this is the functionality of the Scylla-Api-endpoint to SimuBridge
class ScyllaApi(Resource):
def get(self):
print(
"This is a GET request. Please use a POST instead to get scylla output from SimuBridge input. See request form in repo readme")
return 201
def post(self):
try:
requestsFolder = 'requests'
if not os.path.exists(requestsFolder):
os.makedirs(requestsFolder)
# get requestId from header and create project Directory:
if 'requestId' in request.headers and request.headers['requestId'] != '':
requestId = request.headers['requestId']
else:
return 'please define header requestId: <enter request ID>'
if requestId in inDirectory(requestsFolder):
return ("requestID exists already. Please choose different ID")
projectDir = os.path.join(requestsFolder, requestId)
os.mkdir(projectDir)
# save BPMN and Parameter file from request:
if 'bpmn' in request.files and request.files['bpmn'] != '':
bpmn = request.files['bpmn']
else:
raise 'No proces model .bpmn file attached'
if 'globalConfig' in request.files and request.files['globalConfig'] != '':
globalConfig = request.files['globalConfig']
else:
raise 'No global simulation configuration .xml file attached'
if 'simConfig' in request.files and request.files['simConfig'] != '':
simConfig = request.files['simConfig']
else:
raise 'No model-specific simulation configuration .xml file attached'
bpmnPath = os.path.join(projectDir, secure_filename(bpmn.filename))
globalConfigPath = os.path.join(projectDir, secure_filename(globalConfig.filename))
simConfigPath = os.path.join(projectDir, secure_filename(simConfig.filename))
bpmn.save(bpmnPath)
globalConfig.save(globalConfigPath)
simConfig.save(simConfigPath)
(console, newScyllaOutFolder) = runScylla(projectDir, globalConfigPath, simConfigPath, bpmnPath)
# get filenames created from Scylla:
newScyllaFiles = fileInDirectory(join(projectDir, newScyllaOutFolder))
print('These are the Scylla simulation output: ' + str(newScyllaFiles))
return {
"message": console,
"files": list(map(lambda fileName: { "name": fileName, 'data' : open(join(projectDir, newScyllaOutFolder, fileName)).read(), 'type': 'xml'}, newScyllaFiles))
}
except Exception as err:
print(err)
return {
"message": 'An error occured: ' + str(err)
}, 500
api.add_resource(ScyllaApi, '/scyllaapi') # endpoint to SimuBridge
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
app.run(port=port, host='0.0.0.0', debug=True)