Merge pull request #213 from sartography/dev

A hard or soft reset should also cause a 'cancel_notify' which will k…
This commit is contained in:
Dan Funk 2020-12-30 13:18:10 -05:00 committed by GitHub
commit c4ad71e5b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 55 deletions

View File

@ -102,7 +102,16 @@ def get_workflow(workflow_id, soft_reset=False, hard_reset=False, do_engine_step
Read Only will return the workflow in a read only state, without running any Read Only will return the workflow in a read only state, without running any
engine tasks or logging any events. """ engine tasks or logging any events. """
workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by(id=workflow_id).first() workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by(id=workflow_id).first()
processor = WorkflowProcessor(workflow_model, soft_reset=soft_reset, hard_reset=hard_reset) processor = WorkflowProcessor(workflow_model)
if soft_reset or hard_reset:
try:
processor.cancel_notify()
except Exception as e:
raise e
finally:
# In the event of a reset, ALWAYS allow the reset, even if the cancel_notify fails for some reason.
processor = WorkflowProcessor(workflow_model, soft_reset=soft_reset, hard_reset=hard_reset)
if do_engine_steps: if do_engine_steps:
processor.do_engine_steps() processor.do_engine_steps()
processor.save() processor.save()
@ -148,7 +157,7 @@ def set_current_task(workflow_id, task_id):
"currently set to COMPLETE or READY.") "currently set to COMPLETE or READY.")
# If we have an interrupt task, run it. # If we have an interrupt task, run it.
processor.bpmn_workflow.cancel_notify() processor.cancel_notify()
# Only reset the token if the task doesn't already have it. # Only reset the token if the task doesn't already have it.
if spiff_task.state == spiff_task.COMPLETED: if spiff_task.state == spiff_task.COMPLETED:

View File

@ -16,12 +16,12 @@ class Email(Script):
def get_description(self): def get_description(self):
return """ return """
Creates an email, using the provided arguments (a list of UIDs)" Creates an email, using the provided arguments. The first argument is the subject of the email,
Each argument will be used to look up personal information needed for all subsequent arguments should be email addresses in quotes, or variables containing an email address or a list
the email creation. of email addresses."
The "documentation" should contain markdown that will become the body of the email message.
Example: Example:
Email Subject ApprvlApprvr1 PIComputingID email ("My Subject", "dhf8r@virginia.edu", pi.email)
""" """
def do_task_validate_only(self, task, *args, **kwargs): def do_task_validate_only(self, task, *args, **kwargs):
@ -29,15 +29,13 @@ Email Subject ApprvlApprvr1 PIComputingID
self.get_email_recipients(task, args) self.get_email_recipients(task, args)
self.get_content(task) self.get_content(task)
def do_task(self, task, *args, **kwargs): def do_task(self, task, study_id, workflow_id, *args, **kwargs):
args = [arg for arg in args if type(arg) == str or type(arg) == list]
if len(args) < 1:
raise ApiError(code="missing_argument",
message="Email script requires a subject and at least one email address as arguments")
subject = args[0] subject = args[0]
recipients = None recipients = self.get_email_recipients(task, args)
try:
recipients = self.get_email_recipients(task, args)
except ApiError:
raise
content, content_html = self.get_content(task) content, content_html = self.get_content(task)
if recipients: if recipients:
send_mail( send_mail(
@ -59,58 +57,30 @@ Email Subject ApprvlApprvr1 PIComputingID
def get_email_recipients(self, task, args): def get_email_recipients(self, task, args):
emails = [] emails = []
if len(args[1]) < 1: if len(args) < 2:
raise ApiError(code="missing_argument", raise ApiError(code="missing_argument",
message="Email script requires at least one email address as an argument. " message="Email script requires at least one email address as an argument. "
"Multiple email addresses are accepted.") "Multiple email addresses are accepted.")
if isinstance(args[1], str): # Every argument following the subject should be an email, or a list of emails.
if self.check_valid_email(args[1]): for arg in args[1:]:
emails.append(args[1]) if isinstance(arg, str):
emails_to_check = [arg]
elif isinstance(arg, list):
emails_to_check = arg
else: else:
raise ApiError(code="invalid_argument", raise ApiError(code="invalid_argument",
message="The email address you provided could not be parsed. " message=f"Email script requires a valid email address, but received '{arg}'")
"The value you provided is '%s" % args[1])
if isinstance(args[1], list): for e in emails_to_check:
for address in args[1]: if self.check_valid_email(e):
if self.check_valid_email(address): emails.append(e)
emails.append(address)
else: else:
raise ApiError(code="invalid_argument", raise ApiError(code="invalid_argument",
message="The email address you provided could not be parsed. " message="The email address you provided could not be parsed. "
"The value you provided is '%s" % address) "The value you provided is '%s" % e)
if len(emails) > 0: return emails
return emails
else:
raise ApiError(code="invalid_argument",
message="Email script requires a valid email address.")
# def get_users_info(self, task, args):
# if len(args) < 1:
# raise ApiError(code="missing_argument",
# message="Email script requires at least one argument. The "
# "name of the variable in the task data that contains user"
# "id to process. Multiple arguments are accepted.")
# emails = []
# for arg in args:
# try:
# uid = task.workflow.script_engine.evaluate_expression(task, arg)
# except Exception as e:
# app.logger.error(f'Workflow engines could not parse {arg}', exc_info=True)
# continue
# user_info = LdapService.user_info(uid)
# email = user_info.email_address
# emails.append(user_info.email_address)
# if not isinstance(email, str):
# raise ApiError(code="invalid_argument",
# message="The Email script requires at least 1 UID argument. The "
# "name of the variable in the task data that contains subject and"
# " user ids to process. This must point to an array or a string, but "
# "it currently points to a %s " % emails.__class__.__name__)
#
# return emails
def get_subject(self, task, args): def get_subject(self, task, args):
# subject = '' # subject = ''

View File

@ -377,6 +377,12 @@ class WorkflowProcessor(object):
except WorkflowTaskExecException as we: except WorkflowTaskExecException as we:
raise ApiError.from_task("task_error", str(we), we.task) raise ApiError.from_task("task_error", str(we), we.task)
def cancel_notify(self):
try:
self.bpmn_workflow.cancel_notify()
except WorkflowTaskExecException as we:
raise ApiError.from_task("task_error", str(we), we.task)
def serialize(self): def serialize(self):
return self._serializer.serialize_workflow(self.bpmn_workflow,include_spec=True) return self._serializer.serialize_workflow(self.bpmn_workflow,include_spec=True)