The master workflow now generates a dictionary of dictionaries, rather than a dictionary of strings.

Each entry in status is a dictionary with 'status' and 'message' keys.
We updated the StudyService._update_status_of_workflow_meta method to accommodate the master workflow changes.

Changed the order of some if statements so we move forward while we have good data, and run all the error states at the end.
Added some comments to explain the cascading if statements

We changed the names of private methods to begin with one underscore, so they work in the test environment.
Changed  some internal calls to accommodate the underscore change.
This commit is contained in:
mike cullerton 2021-03-22 17:46:39 -04:00
parent 47ff29e3ab
commit a201e49d21
1 changed files with 25 additions and 14 deletions

View File

@ -71,7 +71,7 @@ class StudyService(object):
study.last_activity_user = LdapService.user_info(last_event.user_uid).display_name
study.last_activity_date = last_event.date
study.categories = StudyService.get_categories()
workflow_metas = StudyService.__get_workflow_metas(study_id)
workflow_metas = StudyService._get_workflow_metas(study_id)
files = FileService.get_files_for_study(study.id)
files = (File.from_models(model, FileService.get_file_data(model.id),
FileService.get_doc_dictionary()) for model in files)
@ -83,8 +83,9 @@ class StudyService(object):
# this line is taking 99% of the time that is used in get_study.
# see ticket #196
if do_status:
status = StudyService.__get_study_status(study_model)
study.warnings = StudyService.__update_status_of_workflow_meta(workflow_metas, status)
# __get_study_status() runs the master workflow to generate the status dictionary
status = StudyService._get_study_status(study_model)
study.warnings = StudyService._update_status_of_workflow_meta(workflow_metas, status)
# Group the workflows into their categories.
for category in study.categories:
@ -416,26 +417,36 @@ class StudyService(object):
db.session.commit()
@staticmethod
def __update_status_of_workflow_meta(workflow_metas, status):
def _update_status_of_workflow_meta(workflow_metas, status):
# Update the status on each workflow
warnings = []
for wfm in workflow_metas:
# do we have a status for you
if wfm.name in status.keys():
if not WorkflowState.has_value(status[wfm.name]['status']):
warnings.append(ApiError("invalid_status",
"Workflow '%s' can not be set to '%s', should be one of %s" % (
wfm.name, status[wfm.name], ",".join(WorkflowState.list())
)))
# is it a dictionary
if isinstance(status[wfm.name], dict):
if 'status' in status[wfm.name].keys():
# is 'status' a valid WorkflowState
if WorkflowState.has_value(status[wfm.name]['status']):
wfm.state = WorkflowState[status[wfm.name]['status']]
if 'message' in status[wfm.name].keys():
wfm.state_message = status[wfm.name]['message']
else:
wfm.state_message = ''
else:
warnings.append(ApiError("invalid_state",
"Workflow '%s' can not be set to '%s', should be one of %s" % (
wfm.name, status[wfm.name]['status'], ",".join(WorkflowState.list())
)))
else:
wfm.state = WorkflowState[status[wfm.name]['status']]
if status[wfm.name]['message']:
wfm.state_message = status[wfm.name]['message']
warnings.append(ApiError(code='invalid_status',
message=f'Status must be a dictionary with "status" and "message" keys. Name is {wfm.name}. Status is {status[wfm.name]}'))
else:
warnings.append(ApiError("missing_status", "No status specified for workflow %s" % wfm.name))
return warnings
@staticmethod
def __get_workflow_metas(study_id):
def _get_workflow_metas(study_id):
# Add in the Workflows for each category
workflow_models = db.session.query(WorkflowModel). \
join(WorkflowSpecModel). \
@ -448,7 +459,7 @@ class StudyService(object):
return workflow_metas
@staticmethod
def __get_study_status(study_model):
def _get_study_status(study_model):
"""Uses the Top Level Workflow to calculate the status of the study, and it's
workflow models."""
master_specs = db.session.query(WorkflowSpecModel). \