From 4615649938ddc1a6fde3184088a8b1a539895574 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 15 Apr 2021 11:21:51 -0400 Subject: [PATCH 1/5] Added delete_files argument to the workflow restart api endpoint --- crc/api.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crc/api.yml b/crc/api.yml index 6dc1afa6..37fcb147 100644 --- a/crc/api.yml +++ b/crc/api.yml @@ -874,6 +874,12 @@ paths: description: Set this to true to clear data when starting workflow. schema: type: boolean + - name: delete_files + in: query + required: false + description: Set this to true to delete associated files when starting workflow. + schema: + type: boolean tags: - Workflows and Tasks responses: From 3332b9c7c0bceff9ed8aea4d2854c7812dd80a2c Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 15 Apr 2021 11:23:20 -0400 Subject: [PATCH 2/5] Added delete_files argument to the restart_workflow api method, and pass it along to WorkflowProcessor.reset --- crc/api/workflow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crc/api/workflow.py b/crc/api/workflow.py index 46398904..3c942ea8 100644 --- a/crc/api/workflow.py +++ b/crc/api/workflow.py @@ -116,11 +116,11 @@ def get_workflow(workflow_id, do_engine_steps=True): return WorkflowApiSchema().dump(workflow_api_model) -def restart_workflow(workflow_id, clear_data=False): +def restart_workflow(workflow_id, clear_data=False, delete_files=False): """Restart a workflow with the latest spec. Clear data allows user to restart the workflow without previous data.""" workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by(id=workflow_id).first() - WorkflowProcessor.reset(workflow_model, clear_data=clear_data) + WorkflowProcessor.reset(workflow_model, clear_data=clear_data, delete_files=delete_files) return get_workflow(workflow_model.id) From 91e80d01bcc44e4f6d346e461708a763879057cc Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 15 Apr 2021 11:25:58 -0400 Subject: [PATCH 3/5] Added delete_files argument to the workflow_processor reset method. Added code to delete the files when delete_files is True. --- crc/services/workflow_processor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crc/services/workflow_processor.py b/crc/services/workflow_processor.py index 9016b807..f0a6fa72 100644 --- a/crc/services/workflow_processor.py +++ b/crc/services/workflow_processor.py @@ -174,7 +174,7 @@ class WorkflowProcessor(object): self.is_latest_spec = False @staticmethod - def reset(workflow_model, clear_data=False): + def reset(workflow_model, clear_data=False, delete_files=False): print('WorkflowProcessor: reset: ') # Try to execute a cancel notify @@ -194,6 +194,10 @@ class WorkflowProcessor(object): for task_event in task_events: task_event.form_data = {} session.add(task_event) + if delete_files: + files = FileModel.query.filter(FileModel.workflow_id == workflow_model.id).all() + for file in files: + FileService.delete_file(file.id) session.commit() return WorkflowProcessor(workflow_model) From 69396f9888a8a0e8cf1d8338d0d31bc06036e56b Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 15 Apr 2021 11:28:35 -0400 Subject: [PATCH 4/5] Modified base_test restart_workflow_api to accept and pass on the new delete_files argument when restarting a workflow --- tests/base_test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/base_test.py b/tests/base_test.py index a9fcfce1..c1486939 100644 --- a/tests/base_test.py +++ b/tests/base_test.py @@ -367,11 +367,12 @@ class BaseTest(unittest.TestCase): self.assertEqual(workflow.workflow_spec_id, workflow_api.workflow_spec_id) return workflow_api - def restart_workflow_api(self, workflow, clear_data=False, user_uid="dhf8r"): + def restart_workflow_api(self, workflow, clear_data=False, delete_files=False, user_uid="dhf8r"): user = session.query(UserModel).filter_by(uid=user_uid).first() self.assertIsNotNone(user) url = (f'/v1.0/workflow/{workflow.id}/restart' - f'?clear_data={str(clear_data)}') + f'?clear_data={str(clear_data)}' + f'&delete_files={str(delete_files)}') workflow_api = self.get_workflow_common(url, user) self.assertEqual(workflow.workflow_spec_id, workflow_api.workflow_spec_id) return workflow_api From 2d4a68da6d38ba4497ab85ac0d0ea3ea12c6a25f Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Thu, 15 Apr 2021 11:30:17 -0400 Subject: [PATCH 5/5] Added test for deleting files on restart. --- tests/workflow/test_workflow_restart.py | 42 ++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/workflow/test_workflow_restart.py b/tests/workflow/test_workflow_restart.py index 98688964..98cbf78a 100644 --- a/tests/workflow/test_workflow_restart.py +++ b/tests/workflow/test_workflow_restart.py @@ -2,6 +2,9 @@ from tests.base_test import BaseTest from crc import session from crc.models.study import StudyModel +from crc.services.file_service import FileService +from crc.scripts.is_file_uploaded import IsFileUploaded + class TestWorkflowRestart(BaseTest): @@ -33,7 +36,44 @@ class TestWorkflowRestart(BaseTest): self.assertEqual('Activity_GetData', first_task.name) self.assertNotIn('formdata', workflow_api.next_task.data) - print('Nice Test') + + def test_workflow_restart_delete_files(self): + self.load_example_data() + irb_code = 'Study_Protocol_Document' + + workflow = self.create_workflow('add_delete_irb_document') + study_id = workflow.study_id + + workflow_api = self.get_workflow_api(workflow) + first_task = workflow_api.next_task + + # Should not have any files yet + files = FileService.get_files_for_study(study_id) + self.assertEqual(0, len(files)) + self.assertEqual(False, IsFileUploaded.do_task( + IsFileUploaded, first_task, study_id, workflow.id, irb_code)) + + # Add a file + FileService.add_workflow_file(workflow_id=workflow.id, + name="filename.txt", content_type="text", + binary_data=b'1234', irb_doc_code=irb_code) + # Assert we have the file + self.assertEqual(True, IsFileUploaded.do_task( + IsFileUploaded, first_task, study_id, workflow.id, irb_code)) + + workflow_api = self.restart_workflow_api(workflow_api, delete_files=False) + first_task = workflow_api.next_task + + # Assert we still have the file + self.assertEqual(True, IsFileUploaded.do_task( + IsFileUploaded, first_task, study_id, workflow.id, irb_code)) + + workflow_api = self.restart_workflow_api(workflow_api, delete_files=True) + first_task = workflow_api.next_task + + # Assert we do not have the file + self.assertEqual(False, IsFileUploaded.do_task( + IsFileUploaded, first_task, study_id, workflow.id, irb_code)) def test_workflow_restart_on_cancel_notify(self): workflow = self.create_workflow('message_event')