Commit 47d82d27 authored by Zdralovic Edim's avatar Zdralovic Edim

Added error handling

parent 8446e02d
......@@ -58,7 +58,7 @@ class CWLRestAPI(FlaskView):
route_base = '/' #flask_classful specific, class variable
def __init__(self):
self.baseDir = './workflows/' #for developing only
self.sharedStorage = './datasets/'
self.sharedStorage = "" #'./datasets/'
self.__wfManager = WorkflowManager()
############################################################
#Section: Routed Methods
......@@ -77,20 +77,23 @@ class CWLRestAPI(FlaskView):
byteData = request.data
data = json.loads(byteData.decode("utf-8"))
wf = WorkflowWrapper(userToken = data["usertoken"], sharedStorage = self.sharedStorage+data["sharedStoragePath"], workflowName = data["workflowName"], baseDir = self.baseDir)
self.__wfManager.addWorkflow(wf)
try:
if data["usertoken"] is not "" and data["sharedStoragePath"] is not "" and data["workflowName"] is not "":
if self.__wfManager.wfNameAlreadyInUse(data["usertoken"], data["workflowName"]):
raise WorkflowError('This workflow name is already in use', status_code="406")
return json.dumps(self.__wfManager.startWorkflow(wf.workflowName))
try:
wf = WorkflowWrapper(userToken = data["usertoken"], sharedStorage = self.sharedStorage+data["sharedStoragePath"], workflowName = data["workflowName"], baseDir = self.baseDir)
except IndexError:
raise RessourceError("The submitted Git repository does not follow expected conventions", status_code="406")
self.__wfManager.addWorkflow(wf)
@route('/workflows', methods=['GET'])
def getAllWorkflows(self):
"""
All workflows that belong to given user (usertoken in the body) are returned in JSON format.
"""
byteData = request.data
data = json.loads(byteData.decode("utf-8"))
allWfs = json.dumps(self.__wfManager.getAllWorkflows(data["usertoken"]))
return allWfs
return json.dumps(self.__wfManager.startWorkflow(wf.workflowName))
else:
raise WorkflowError('Not all needed parameters were supplied', status_code="406")
except KeyError:
raise WorkflowError('Not all needed parameters were supplied', status_code="406")
@route('/workflows/<workflowID>', methods=['GET'])
def getDetailedWorkflowStatus(self, workflowID):
......@@ -267,7 +270,7 @@ class WorkflowManager:
if result is not None:
return result.retrieveDetailedInfoWorkflow()
else:
return "This Workflow does not exist"
raise RessourceError("This Workflow does not exist", status_code="404")
def killWorkflowByID(self, id):
"""
......@@ -284,7 +287,7 @@ class WorkflowManager:
result.killToilRunner()
return {"workflow_id":result.workflowID}
else:
return "This Workflow does not exist"
raise RessourceError("This Workflow does not exist", status_code="404")
def getWorkflowStatusByID(self, id):
"""
......@@ -299,7 +302,7 @@ class WorkflowManager:
if result is not None:
return result.retrieveStatusWorkflow()
else:
return "This Workflow does not exist"
raise RessourceError("This Workflow does not exist", status_code="404")
def getAllWorkflows(self, usertoken):
"""
......@@ -308,6 +311,13 @@ class WorkflowManager:
"""
return wesDAO.get_all_user_workflows(usertoken)
def wfNameAlreadyInUse(self, usertoken, workflowname):
for wf in self.workflowList:
if wf.userToken == usertoken:
if wf.workflowName == workflowname:
return True
return False
class WorkflowWrapper(threading.Thread):
"""
This class represents one workflow submitted to the API and is
......@@ -353,6 +363,7 @@ class WorkflowWrapper(threading.Thread):
#Section: Variables
############################################################
def __init__(self, userToken="", baseDir="", workflowName="", gitRepoUrl="", restart=False, sharedStorage=""): #Constructor
self.userToken = userToken
self.restart = restart
self.sharedStorage = sharedStorage
self.workflowID = ""
......@@ -365,12 +376,14 @@ class WorkflowWrapper(threading.Thread):
self.toilProcess = None
self.workflowName = workflowName
self.gitRepoUrl = gitRepoUrl
self.outDir = sys.intern(self.sharedStorage+"/out/")
os.makedirs(self.outDir)
self.workDir = sys.intern(baseDir+userToken+"/work/")
self.jobStore = sys.intern(baseDir+userToken+"/jobStore/")
self.logDir = sys.intern(baseDir+userToken+"/logs/")
self.userToken = userToken
self.outDir = self.sharedStorage+"/out/"
if not os.path.exists(self.outDir):
os.makedirs(self.outDir)
self.workDir = self.baseDir+userToken+"/work/"
self.jobStore = self.baseDir+self.userToken+"/jobStore/"
self.logDir = self.baseDir+self.userToken+"/logs/"
self.workflowDBID = None
self.stopped = False
......@@ -448,6 +461,50 @@ class WorkflowWrapper(threading.Thread):
"""
return wesDAO.get_workflow_status(self.workflowDBID)
############################################################
#Section: Error Handling
############################################################
class WorkflowError(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
class RessourceError(Exception):
status_code = 406
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
@app.errorhandler(WorkflowError)
def handleWorkflowError(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
@app.errorhandler(RessourceError)
def handleRessourceError(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
############################################################
#Section: Main
############################################################
if __name__ == '__main__':
......
......@@ -13,18 +13,12 @@ sudo docker build -t cwlflask .
sudo docker run -it cwlflask /bin/sh --> gets into the docker container, enables usage of terminal
sudo docker run -p 5000:5000 cwlflask
curl -d \
'{"giturl":"https://github.com/shinra-tensei/toilCWLTest.git","usertoken":"user1","workflowName":"myHornyWorkflow"}' \
-H "Content-Type: application/json" -X POST http://localhost:5000/workflows/gitURL
curl -d \
'{"workflowName":"myHornyWorkflow", "yaml": {"path2localRepo": "/home/christina/Work/CWL_projects/CWL_test_pAp", "fastqgz": {"class": "File", "path": "./tests/testfiles_Aseq_cl/A_seq_test.fq.gz"}, "outFileName": "q2a_renamed_valid5p.fa", "adapter5p": "....TTT"}}' \
-H "Content-Type: application/json" -X POST http://localhost:5000/workflows
curl -d \
'{"workflowName":"myHornyWorkflow", "usertoken": "hornyBoi", "sharedStoragePath": "/home/cuhoni66/toilCWLTest/"}' \
-H "Content-Type: application/json" -X POST http://localhost:5000/workflows
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:5000/workflows/user/hornyBoi
toil-cwl-runner --debugWorker --outdir=/home/cuhoni66/Schreibtisch/dot/data/outdir/ --workDir=/home/cuhoni66/Schreibtisch/dot/data/workdir/ --jobStore=/home/cuhoni66/Schreibtisch/dot/data/jobStore/ --singularity ex3.cwl ex2.yml
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment