def _create_workflow_model(study: StudyModel, spec): workflow_model = WorkflowModel(status=WorkflowStatus.not_started, study=study, workflow_spec_id=spec.id, last_updated=datetime.now()) session.add(workflow_model) session.commit() return workflow_model
def from_workflow(cls, workflow: WorkflowModel): instance = cls(id=workflow.id, name=workflow.workflow_spec.name, display_name=workflow.workflow_spec.display_name, description=workflow.workflow_spec.description, spec_version=workflow.spec_version(), category_id=workflow.workflow_spec.category_id, state=WorkflowState.optional, status=workflow.status, total_tasks=workflow.total_tasks, completed_tasks=workflow.completed_tasks, display_order=workflow.workflow_spec.display_order) return instance
def make_test_workflow(spec_id): user = db.session.query(UserModel).filter_by(uid="test").first() if not user: db.session.add(UserModel(uid="test")) study = db.session.query(StudyModel).filter_by(user_uid="test").first() if not study: db.session.add(StudyModel(user_uid="test", title="test")) db.session.commit() workflow_model = WorkflowModel(status=WorkflowStatus.not_started, workflow_spec_id=spec_id, last_updated=datetime.now(), study=study) return workflow_model
def __init__(self, workflow_model: WorkflowModel, validate_only=False): """Create a Workflow Processor based on the serialized information available in the workflow model.""" self.workflow_model = workflow_model spec = None if workflow_model.bpmn_workflow_json is None: self.spec_files = SpecFileService().get_spec_files( workflow_spec_id=workflow_model.workflow_spec_id, include_libraries=True) spec = self.get_spec(self.spec_files, workflow_model.workflow_spec_id) self.workflow_spec_id = workflow_model.workflow_spec_id try: self.bpmn_workflow = self.__get_bpmn_workflow( workflow_model, spec, validate_only) self.bpmn_workflow.script_engine = self._script_engine if UserService.has_user(): current_user = UserService.current_user( allow_admin_impersonate=True) current_user_data = UserModelSchema().dump(current_user) tasks = self.bpmn_workflow.get_tasks(SpiffTask.READY) for task in tasks: task.data['current_user'] = current_user_data if self.WORKFLOW_ID_KEY not in self.bpmn_workflow.data: if not workflow_model.id: session.add(workflow_model) session.commit() # If the model is new, and has no id, save it, write it into the workflow model # and save it again. In this way, the workflow process is always aware of the # database model to which it is associated, and scripts running within the model # can then load data as needed. self.bpmn_workflow.data[ WorkflowProcessor.WORKFLOW_ID_KEY] = workflow_model.id workflow_model.bpmn_workflow_json = WorkflowProcessor._serializer.serialize_workflow( self.bpmn_workflow, include_spec=True) self.save() except MissingSpecError as ke: raise ApiError(code="unexpected_workflow_structure", message="Failed to deserialize workflow" " '%s' due to a mis-placed or missing task '%s'" % (self.workflow_spec_id, str(ke)))
def create_user_with_study_and_workflow(self): # clear it all out. from example_data import ExampleDataLoader ExampleDataLoader.clean_db() # Assure some basic models are in place, This is a damn mess. Our database models need an overhaul to make # this easier - better relationship modeling is now critical. self.load_test_spec("top_level_workflow", master_spec=True) user = db.session.query(UserModel).filter( UserModel.uid == "dhf8r").first() if not user: user = UserModel(uid="dhf8r", email_address="*****@*****.**", display_name="Stayathome Smellalots") db.session.add(user) db.session.commit() else: for study in db.session.query(StudyModel).all(): StudyService().delete_study(study.id) study = StudyModel( title="My title", protocol_builder_status=ProtocolBuilderStatus.ACTIVE, user_uid=user.uid) db.session.add(study) cat = WorkflowSpecCategoryModel(name="approvals", display_name="Approvals", display_order=0) db.session.add(cat) db.session.commit() self.assertIsNotNone(cat.id) self.load_test_spec("random_fact", category_id=cat.id) self.assertIsNotNone(study.id) workflow = WorkflowModel(workflow_spec_id="random_fact", study_id=study.id, status=WorkflowStatus.not_started, last_updated=datetime.now()) db.session.add(workflow) db.session.commit() # Assure there is a master specification, one standard spec, and lookup tables. ExampleDataLoader().load_reference_documents() return user
def __init__(self, workflow_model: WorkflowModel, soft_reset=False, hard_reset=False, validate_only=False): """Create a Workflow Processor based on the serialized information available in the workflow model. If soft_reset is set to true, it will try to use the latest version of the workflow specification without resetting to the beginning of the workflow. This will work for some minor changes to the spec. If hard_reset is set to true, it will use the latest spec, and start the workflow over from the beginning. which should work in casees where a soft reset fails. If neither flag is set, it will use the same version of the specification that was used to originally create the workflow model. """ self.workflow_model = workflow_model if soft_reset or len( workflow_model.dependencies ) == 0: # Depenencies of 0 means the workflow was never started. self.spec_data_files = FileService.get_spec_data_files( workflow_spec_id=workflow_model.workflow_spec_id) else: self.spec_data_files = FileService.get_spec_data_files( workflow_spec_id=workflow_model.workflow_spec_id, workflow_id=workflow_model.id) spec = self.get_spec(self.spec_data_files, workflow_model.workflow_spec_id) self.workflow_spec_id = workflow_model.workflow_spec_id try: self.bpmn_workflow = self.__get_bpmn_workflow( workflow_model, spec, validate_only) self.bpmn_workflow.script_engine = self._script_engine if self.WORKFLOW_ID_KEY not in self.bpmn_workflow.data: if not workflow_model.id: session.add(workflow_model) session.commit() # If the model is new, and has no id, save it, write it into the workflow model # and save it again. In this way, the workflow process is always aware of the # database model to which it is associated, and scripts running within the model # can then load data as needed. self.bpmn_workflow.data[ WorkflowProcessor.WORKFLOW_ID_KEY] = workflow_model.id workflow_model.bpmn_workflow_json = WorkflowProcessor._serializer.serialize_workflow( self.bpmn_workflow) self.save() except MissingSpecError as ke: raise ApiError( code="unexpected_workflow_structure", message="Failed to deserialize workflow" " '%s' version %s, due to a mis-placed or missing task '%s'" % (self.workflow_spec_id, self.get_version_string(), str(ke)) + " This is very likely due to a soft reset where there was a structural change." ) if hard_reset: # Now that the spec is loaded, get the data and rebuild the bpmn with the new details self.hard_reset() workflow_model.bpmn_workflow_json = WorkflowProcessor._serializer.serialize_workflow( self.bpmn_workflow) self.save() if soft_reset: self.save() # set whether this is the latest spec file. if self.spec_data_files == FileService.get_spec_data_files( workflow_spec_id=workflow_model.workflow_spec_id): self.is_latest_spec = True else: self.is_latest_spec = False