def load_workflow(app_label, version_slug, force=False): workflow_directory = django_apps.get_app_config(app_label).path data = parse_workflow_directory(workflow_directory) # Create the workflow object if it doesn't exist workflow_data = data['workflow'] workflow, workflow_created = Workflow.objects.update_or_create( slug=workflow_data['slug'], defaults={ 'name': workflow_data['name'], 'description': workflow_data['description'], 'code_directory': workflow_directory, 'sample_data_load_function': workflow_data.get( 'sample_data_load_function') } ) # Create all certifications for the workflow for certification_data in workflow_data['certifications']: Certification.objects.update_or_create( slug=certification_data['slug'], workflow=workflow, defaults={ 'name': certification_data['name'], 'description': certification_data['description'], } ) # Create the certification dependencies once all certs are in the db # Allow updating these over time so that a workflow's certifications can # evolve. This means that the user is responsible for ensuring that all # workers have the proper certifications after updating these dependencies. for certification_data in workflow_data['certifications']: certification = Certification.objects.get( slug=certification_data['slug'], workflow=workflow ) required_certification_slugs = certification_data.get( 'required_certifications', []) required_certifications = Certification.objects.filter( workflow=workflow, slug__in=required_certification_slugs ) if required_certifications.count() != len( required_certification_slugs): raise WorkflowError( 'Certification {} requires non-existent certification.' .format(certification_data['slug'])) certification.required_certifications.set( list(required_certifications)) # Load the desired versions desired_versions = [version_data for version_data in data['versions'] if version_data['slug'] == version_slug] if len(desired_versions) != 1: raise WorkflowError('Invalid version requested: {}' .format(version_slug)) load_workflow_version(desired_versions[0], workflow, force=force)
def load_workflow(app_label, version_slug, force=False): workflow_directory = django_apps.get_app_config(app_label).path data = parse_workflow_directory(workflow_directory) # Create the workflow object if it doesn't exist workflow_data = data['workflow'] workflow, workflow_created = Workflow.objects.update_or_create( slug=workflow_data['slug'], defaults={ 'name': workflow_data['name'], 'description': workflow_data['description'], 'code_directory': workflow_directory, 'sample_data_load_function': workflow_data.get( 'sample_data_load_function') } ) # Create all certifications for the workflow for certification_data in workflow_data['certifications']: Certification.objects.update_or_create( slug=certification_data['slug'], workflow=workflow, defaults={ 'name': certification_data['name'], 'description': certification_data['description'], } ) # Create the certification dependencies once all certs are in the db # Allow updating these over time so that a workflow's certifications can # evolve. This means that the user is responsible for ensuring that all # workers have the proper certifications after updating these dependencies. for certification_data in workflow_data['certifications']: certification = Certification.objects.get( slug=certification_data['slug'], workflow=workflow ) required_certification_slugs = certification_data.get( 'required_certifications', []) required_certifications = Certification.objects.filter( workflow=workflow, slug__in=required_certification_slugs ) if required_certifications.count() != len( required_certification_slugs): raise WorkflowError( 'Certification {} requires non-existent certification.' .format(certification_data['slug'])) certification.required_certifications = list(required_certifications) # Load the desired versions desired_versions = [version_data for version_data in data['versions'] if version_data['slug'] == version_slug] if len(desired_versions) != 1: raise WorkflowError('Invalid version requested: {}' .format(version_slug)) load_workflow_version(desired_versions[0], workflow, force=force)
def get_workflow_version_slugs(): versions = {} for app_name in settings.ORCHESTRA_WORKFLOWS: # App label is the last part of the app name by default app_label = app_name.split('.')[-1] workflow_directory = django_apps.get_app_config(app_label).path data = parse_workflow_directory(workflow_directory) workflow_slug = data['workflow']['slug'] if versions.get(workflow_slug) is not None: raise WorkflowError( 'Workflow {} present in multiple apps: {}, {}'.format( workflow_slug, versions[workflow_slug]['app_label'], app_label)) else: versions[workflow_slug] = { 'app_label': app_label, 'versions': (version['slug'] for version in data['versions']) } return versions
def get_workflow_version_slugs(): versions = {} for app_name in settings.ORCHESTRA_WORKFLOWS: # App label is the last part of the app name by default app_label = app_name.split('.')[-1] workflow_directory = django_apps.get_app_config(app_label).path data = parse_workflow_directory(workflow_directory) workflow_slug = data['workflow']['slug'] if versions.get(workflow_slug) is not None: raise WorkflowError('Workflow {} present in multiple apps: {}, {}' .format(workflow_slug, versions[workflow_slug]['app_label'], app_label)) else: versions[workflow_slug] = { 'app_label': app_label, 'versions': (version['slug'] for version in data['versions']) } return versions
def get_workflow_version_slugs(): versions = {} for app_name in settings.ORCHESTRA_WORKFLOWS: # App label is the last part of the app name by default app_label = app_name.split(".")[-1] workflow_directory = django_apps.get_app_config(app_label).path data = parse_workflow_directory(workflow_directory) workflow_slug = data["workflow"]["slug"] if versions.get(workflow_slug) is not None: raise WorkflowError( "Workflow {} present in multiple apps: {}, {}".format( workflow_slug, versions[workflow_slug]["app_label"], app_label ) ) else: versions[workflow_slug] = { "app_label": app_label, "versions": (version["slug"] for version in data["versions"]), } return versions
def test_parse_workflow_directory(self): """ Ensure that workflow version directories are parsed correctly. """ # Shouldn't be able to parse a non-existent directory. directory_error = 'Workflow directory does not exist.' with self.assertRaisesMessage(WorkflowError, directory_error): parse_workflow_directory(NONEXISTENT_DIR) # Shouldn't be able to parse a directory with no workflow.json. with self.assertRaisesMessage( WorkflowError, 'No "workflow.json" manifest file found'): parse_workflow_directory(INVALID_WORKFLOW_DIR) # Shouldn't be able to parse a directory with no valid versions. with self.assertRaisesMessage( WorkflowError, 'Workflow directory {} does not contain any versions'.format( EMPTY_WORKFLOW_DIR)): parse_workflow_directory(EMPTY_WORKFLOW_DIR) # Should be able to parse a valid directory with two versions. parsed = parse_workflow_directory(VALID_WORKFLOW_DIR) workflow_json_path = os.path.join(VALID_WORKFLOW_DIR, 'workflow.json') with open(workflow_json_path, 'r') as workflow_json_file: workflow_data = json.load(workflow_json_file) self.assertEqual(workflow_data, parsed['workflow']) v1_json_path = os.path.join(VALID_WORKFLOW_DIR, 'v1/version.json') with open(v1_json_path, 'r') as v1_json_file: v1_data = json.load(v1_json_file) self.assertIn(v1_data, parsed['versions']) v2_json_path = os.path.join(VALID_WORKFLOW_DIR, 'v2/version.json') with open(v2_json_path, 'r') as v2_json_file: v2_data = json.load(v2_json_file) self.assertIn(v2_data, parsed['versions'])