2 This module implements a simple REST API that behaves like SONATA's gatekeeper.
4 It is only used to support the development of SONATA's SDK tools and to demonstrate
5 the year 1 version of the emulator until the integration with WP4's orchestrator is done.
12 from flask
import Flask
, request
13 import flask_restful
as fr
15 logging
.getLogger("werkzeug").setLevel(logging
.WARNING
)
18 UPLOAD_FOLDER
= "/tmp/son-dummy-gk/uploads/"
19 CATALOG_FOLDER
= "/tmp/son-dummy-gk/catalog/"
22 class Gatekeeper(object):
25 self
.packages
= dict()
26 self
.instantiations
= dict()
27 logging
.info("Create SONATA dummy gatekeeper.")
29 def unpack_service_package(self
, service_uuid
):
30 # TODO implement method
31 # 1. unzip *.son file and store contents in CATALOG_FOLDER/services/<service_uuid>/
34 def start_service(self
, service_uuid
):
35 # TODO implement method
36 # 1. parse descriptors
37 # 2. do the corresponding dc.startCompute(name="foobar") calls
38 # 3. store references to the compute objects in self.instantiations
43 Resource definitions and API endpoints
47 class Packages(fr
.Resource
):
51 We expect request with a *.son file and store it in UPLOAD_FOLDER
55 file = request
.files
['file']
56 # generate a uuid to reference this package
57 service_uuid
= str(uuid
.uuid4())
58 hash = hashlib
.sha1(str(file)).hexdigest()
59 # ensure that upload folder exists
60 ensure_dir(UPLOAD_FOLDER
)
61 upload_path
= os
.path
.join(UPLOAD_FOLDER
, "%s.son" % service_uuid
)
62 # store *.son file to disk
63 file.save(upload_path
)
64 size
= os
.path
.getsize(upload_path
)
65 # store a reference to the uploaded package in our gatekeeper
66 GK
.packages
[service_uuid
] = upload_path
67 # generate the JSON result
68 return {"service_uuid": service_uuid
, "size": size
, "sha1": hash, "error": None}
69 except Exception as ex
:
70 logging
.exception("Service package upload failed:")
71 return {"service_uuid": None, "size": 0, "sha1": None, "error": "upload failed"}
74 return {"service_uuid_list": list(GK
.packages
.iterkeys())}
77 class Instantiations(fr
.Resource
):
80 # TODO implement method
84 # TODO implement method
87 # create a single, global GK object
91 app
.config
['MAX_CONTENT_LENGTH'] = 512 * 1024 * 1024 # 512 MB max upload
94 api
.add_resource(Packages
, '/api/packages/uploads')
95 api
.add_resource(Instantiations
, '/api/instantiations')
98 def start_rest_api(host
, port
):
99 # start the Flask server (not the best performance but ok for our use case)
103 use_reloader
=False # this is needed to run Flask in a non-main thread
107 def ensure_dir(name
):
108 if not os
.path
.exists(name
):
112 if __name__
== '__main__':
114 Lets allow to run the API in standalone mode.
116 logging
.getLogger("werkzeug").setLevel(logging
.INFO
)
117 start_rest_api("0.0.0.0", 8000)