From 4a1285b8e0e156245956a87276b123e88b72baa1 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 22 Nov 2021 17:17:19 -0500 Subject: [PATCH] When validating a workflow, don't run the master workflow multiple times, its a huge waste of time. Provide decent data when calling get_study_associate(s) scripts. --- crc/api/workflow.py | 4 +++- crc/scripts/get_study_associate.py | 15 ++++++++++++++- crc/scripts/get_study_associates.py | 24 ++++++++++++++++++++++-- crc/scripts/study_info.py | 7 +------ crc/services/workflow_service.py | 19 +++++++++++-------- tests/test_verify_end_event.py | 3 +++ 6 files changed, 54 insertions(+), 18 deletions(-) diff --git a/crc/api/workflow.py b/crc/api/workflow.py index fa844ec2..126a2c92 100644 --- a/crc/api/workflow.py +++ b/crc/api/workflow.py @@ -5,7 +5,7 @@ from flask import g from crc import session from crc.api.common import ApiError, ApiErrorSchema from crc.models.api_models import WorkflowApiSchema -from crc.models.file import FileModel, LookupDataSchema +from crc.models.file import FileModel from crc.models.study import StudyModel, WorkflowMetadata, StudyStatus from crc.models.task_event import TaskEventModel, TaskEvent, TaskEventSchema from crc.models.workflow import WorkflowModel, WorkflowSpecModelSchema, WorkflowSpecModel, WorkflowSpecCategoryModel, \ @@ -101,8 +101,10 @@ def drop_workflow_spec_library(spec_id,library_id): libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all() return WorkflowLibraryModelSchema(many=True).dump(libraries) + def validate_workflow_specification(spec_id, study_id=None, test_until=None): try: + WorkflowService.raise_if_disabled(spec_id, study_id) WorkflowService.test_spec(spec_id, study_id, test_until) WorkflowService.test_spec(spec_id, study_id, test_until, required_only=True) except ApiError as ae: diff --git a/crc/scripts/get_study_associate.py b/crc/scripts/get_study_associate.py index 81fcf287..ceb1e501 100644 --- a/crc/scripts/get_study_associate.py +++ b/crc/scripts/get_study_associate.py @@ -18,7 +18,20 @@ example : get_study_associate('sbp3ey') => {'uid':'sbp3ey','role':'Unicorn Herde def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs): if len(args) < 1: raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function') - return {'uid': 'sbp3ey', 'role': 'Unicorn Herder', 'send_email': False, 'access': True} + return {'uid': 'sbp3ey', + 'role': 'Unicorn Herder', + 'send_email': False, + 'access': True, + 'ldap_info': { + 'uid': 'sbp3ey', + 'display_name': "Simply Delightful", + 'email_address': 'sbp3ey@virginia.edu', + 'telephone_number': '', + 'title': '', + 'department': '', + 'affiliation': '', + 'sponsor_type': '', + }} def do_task(self, task, study_id, workflow_id, *args, **kwargs): if len(args) < 1: diff --git a/crc/scripts/get_study_associates.py b/crc/scripts/get_study_associates.py index 83bbea86..4aca255f 100644 --- a/crc/scripts/get_study_associates.py +++ b/crc/scripts/get_study_associates.py @@ -20,8 +20,28 @@ example : get_study_associates() => [{'uid':'sbp3ey','role':'Unicorn Herder', 's def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs): study_associates = [ - {'uid': 'dhf8r', 'role': 'Chief Bee Keeper', 'send_email': True, 'access': True}, - {'uid': 'lb3dp', 'role': 'Chief Cat Herder', 'send_email': True, 'access': True} + {'uid': 'dhf8r', 'role': 'Chief Bee Keeper', 'send_email': True, 'access': True, + 'ldap_info': { + 'uid': 'dhf8r', + 'display_name': "Dan Funk", + 'email_address': 'dhf8r@virginia.edu', + 'telephone_number': '', + 'title': '', + 'department': '', + 'affiliation': '', + 'sponsor_type': '', + }}, + {'uid': 'lb3dp', 'role': 'Chief Cat Herder', 'send_email': True, 'access': True, + 'ldap_info': { + 'uid': 'dhf8r', + 'display_name': "Dan Funk", + 'email_address': 'dhf8r@virginia.edu', + 'telephone_number': '', + 'title': '', + 'department': '', + 'affiliation': '', + 'sponsor_type': '' + }}, ] return study_associates diff --git a/crc/scripts/study_info.py b/crc/scripts/study_info.py index 0850f33b..c2feb737 100644 --- a/crc/scripts/study_info.py +++ b/crc/scripts/study_info.py @@ -165,15 +165,10 @@ Please note this is just a few examples, ALL known document types are returned i ) def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs): - """For validation only, pretend no results come back from pb""" - self.check_args(args, 2) - # Assure the reference file exists (a bit hacky, but we want to raise this error early, and cleanly.) - FileService.get_reference_file_data(DocumentService.DOCUMENT_LIST) - FileService.get_reference_file_data(StudyService.INVESTIGATOR_LIST) # we call the real do_task so we can # seed workflow validations with settings from studies in PB Mock # in order to test multiple paths thru the workflow - return self.do_task(task, study_id, workflow_id, args[0]) + return self.do_task(task, study_id, workflow_id, *args, **kwargs) @timeit def do_task(self, task, study_id, workflow_id, *args, **kwargs): diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index 93147508..23edf646 100755 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -123,6 +123,16 @@ class WorkflowService(object): workflow_model.study_id, str(e))) + @staticmethod + def raise_if_disabled(spec_id, study_id): + """Raise an exception of the workflow is not enabled and can not be executed.""" + if study_id is not None: + study_model = session.query(StudyModel).filter(StudyModel.id == study_id).first() + spec_model = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == spec_id).first() + status = StudyService._get_study_status(study_model) + if spec_model.id in status and status[spec_model.id]['status'] == 'disabled': + raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.id]['message']}") + @staticmethod @timeit def test_spec(spec_id, validate_study_id=None, test_until=None, required_only=False): @@ -130,19 +140,12 @@ class WorkflowService(object): Not fool-proof, but a good sanity check. Returns the final data output form the last task if successful. - test_until + test_until - stop running the validation when you reach this task spec. required_only can be set to true, in which case this will run the spec, only completing the required fields, rather than everything. """ - # Get workflow state dictionary, make sure workflow is not disabled. - if validate_study_id is not None: - study_model = session.query(StudyModel).filter(StudyModel.id == validate_study_id).first() - spec_model = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == spec_id).first() - status = StudyService._get_study_status(study_model) - if spec_model.id in status and status[spec_model.id]['status'] == 'disabled': - raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.id]['message']}") workflow_model = WorkflowService.make_test_workflow(spec_id, validate_study_id) try: processor = WorkflowProcessor(workflow_model, validate_only=True) diff --git a/tests/test_verify_end_event.py b/tests/test_verify_end_event.py index 964a47ed..1b939cfb 100644 --- a/tests/test_verify_end_event.py +++ b/tests/test_verify_end_event.py @@ -25,3 +25,6 @@ class TestValidateEndEvent(BaseTest): self.assertEqual(8, e.line_number) self.assertEqual('{%- if value = 1 -%}', e.error_line) self.assertEqual('verify_end_event.bpmn', e.file_name) + + +