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.
This commit is contained in:
Dan 2021-11-22 17:17:19 -05:00
parent 5bb7dbfb19
commit 4a1285b8e0
6 changed files with 54 additions and 18 deletions

View File

@ -5,7 +5,7 @@ from flask import g
from crc import session from crc import session
from crc.api.common import ApiError, ApiErrorSchema from crc.api.common import ApiError, ApiErrorSchema
from crc.models.api_models import WorkflowApiSchema 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.study import StudyModel, WorkflowMetadata, StudyStatus
from crc.models.task_event import TaskEventModel, TaskEvent, TaskEventSchema from crc.models.task_event import TaskEventModel, TaskEvent, TaskEventSchema
from crc.models.workflow import WorkflowModel, WorkflowSpecModelSchema, WorkflowSpecModel, WorkflowSpecCategoryModel, \ 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() libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all()
return WorkflowLibraryModelSchema(many=True).dump(libraries) return WorkflowLibraryModelSchema(many=True).dump(libraries)
def validate_workflow_specification(spec_id, study_id=None, test_until=None): def validate_workflow_specification(spec_id, study_id=None, test_until=None):
try: 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)
WorkflowService.test_spec(spec_id, study_id, test_until, required_only=True) WorkflowService.test_spec(spec_id, study_id, test_until, required_only=True)
except ApiError as ae: except ApiError as ae:

View File

@ -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): def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
if len(args) < 1: if len(args) < 1:
raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function') 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): def do_task(self, task, study_id, workflow_id, *args, **kwargs):
if len(args) < 1: if len(args) < 1:

View File

@ -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): def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
study_associates = [ study_associates = [
{'uid': 'dhf8r', 'role': 'Chief Bee Keeper', 'send_email': True, 'access': True}, {'uid': 'dhf8r', 'role': 'Chief Bee Keeper', 'send_email': True, 'access': True,
{'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': '',
}},
{'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 return study_associates

View File

@ -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): 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 # we call the real do_task so we can
# seed workflow validations with settings from studies in PB Mock # seed workflow validations with settings from studies in PB Mock
# in order to test multiple paths thru the workflow # 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 @timeit
def do_task(self, task, study_id, workflow_id, *args, **kwargs): def do_task(self, task, study_id, workflow_id, *args, **kwargs):

View File

@ -123,6 +123,16 @@ class WorkflowService(object):
workflow_model.study_id, workflow_model.study_id,
str(e))) 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 @staticmethod
@timeit @timeit
def test_spec(spec_id, validate_study_id=None, test_until=None, required_only=False): 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 Not fool-proof, but a good sanity check. Returns the final data
output form the last task if successful. 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 required_only can be set to true, in which case this will run the
spec, only completing the required fields, rather than everything. 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) workflow_model = WorkflowService.make_test_workflow(spec_id, validate_study_id)
try: try:
processor = WorkflowProcessor(workflow_model, validate_only=True) processor = WorkflowProcessor(workflow_model, validate_only=True)

View File

@ -25,3 +25,6 @@ class TestValidateEndEvent(BaseTest):
self.assertEqual(8, e.line_number) self.assertEqual(8, e.line_number)
self.assertEqual('{%- if value = 1 -%}', e.error_line) self.assertEqual('{%- if value = 1 -%}', e.error_line)
self.assertEqual('verify_end_event.bpmn', e.file_name) self.assertEqual('verify_end_event.bpmn', e.file_name)