def test_get_activity_executions(self, get_nodes_mock): get_nodes_mock.return_value = { 'nodes': [{ 'id': 1, 'labels': ['Activity Execution'], 'properties': [{ 'key': 'test', 'value': 'test' }] }, { 'id': 2, 'labels': ['Activity Execution'], 'properties': [{ 'key': 'test2', 'value': 'test3' }] }] } activity_execution_one = BasicActivityExecutionOut( additional_properties=[PropertyIn(key='test', value='test')], id=1) activity_execution_two = BasicActivityExecutionOut( additional_properties=[PropertyIn(key='test2', value='test3')], id=2) activity_executions = ActivityExecutionsOut(activity_executions=[ activity_execution_one, activity_execution_two ]) activity_executions_service = ActivityExecutionService() result = activity_executions_service.get_activity_executions() self.assertEqual(result, activity_executions) get_nodes_mock.assert_called_once_with("`Activity Execution`")
def test_update_activity_execution_without_error( self, get_node_relationships_mock, delete_node_properties_mock, get_node_mock, create_properties_mock): id_node = 1 create_properties_mock.return_value = {} delete_node_properties_mock.return_value = {} get_node_relationships_mock.return_value = { "relationships": [{ "start_node": id_node, "end_node": 19, "name": "testRelation", "id": 0, "properties": None }, { "start_node": 15, "end_node": id_node, "name": "testReversedRelation", "id": 0, "properties": None }] } get_node_mock.return_value = { 'id': id_node, 'labels': ['Activity Execution'], 'properties': [{ 'key': 'identifier', 'value': 5 }], "errors": None, 'links': None } additional_properties = [PropertyIn(key='identifier', value=5)] activity_execution_in = ActivityExecutionPropertyIn( id=id_node, additional_properties=additional_properties) activity_execution_out = ActivityExecutionOut( additional_properties=additional_properties, id=id_node, relations=[ RelationInformation(second_node_id=19, name="testRelation", relation_id=0) ], reversed_relations=[ RelationInformation(second_node_id=15, name="testReversedRelation", relation_id=0) ]) calls = [mock.call(1)] activity_execution_service = ActivityExecutionService() result = activity_execution_service.update_activity_execution( id_node, activity_execution_in) self.assertEqual(result, activity_execution_out) get_node_mock.assert_has_calls(calls) create_properties_mock.assert_called_once_with(id_node, activity_execution_in) get_node_relationships_mock.assert_called_once_with(id_node)
def test_get_activity_executions_empty(self, get_nodes_mock): get_nodes_mock.return_value = {'nodes': []} activity_executions = ActivityExecutionsOut(activity_execution=[]) activity_executions_service = ActivityExecutionService() result = activity_executions_service.get_activity_executions() self.assertEqual(result, activity_executions) get_nodes_mock.assert_called_once_with("`Activity Execution`")
def test_save_activity_execution_with_node_error(self, create_node_mock): id_node = 1 create_node_mock.return_value = {'id': id_node, 'properties': None, "errors": ['error'], 'links': None} activity_execution = ActivityExecutionIn(activity_id=2, arrangement_id=3) activity_execution_service = ActivityExecutionService() result = activity_execution_service.save_activity_execution(activity_execution) self.assertEqual(result, ActivityExecutionOut(errors=['error'])) create_node_mock.assert_called_once_with('`Activity Execution`')
def test_delete_activity_execution_with_error(self, get_node_mock): id_node = 1 get_node_mock.return_value = { 'id': id_node, 'errors': ['error'], 'links': None } not_found = NotFoundByIdModel(id=id_node, errors=['error']) activity_execution_service = ActivityExecutionService() result = activity_execution_service.delete_activity_execution(id_node) self.assertEqual(result, not_found) get_node_mock.assert_called_once_with(id_node)
def test_get_activity_execution_without_label(self, get_node_mock): id_node = 1 get_node_mock.return_value = { 'id': id_node, 'labels': ['Test'], 'properties': None, "errors": None, 'links': None } not_found = NotFoundByIdModel(id=id_node, errors="Node not found.") activity_execution_service = ActivityExecutionService() result = activity_execution_service.get_activity_execution(id_node) self.assertEqual(result, not_found) get_node_mock.assert_called_once_with(id_node)
def test_delete_activity_execution_without_error( self, get_node_relationships_mock, get_node_mock, delete_node_mock): id_node = 1 delete_node_mock.return_value = get_node_mock.return_value = { 'id': id_node, 'labels': ['Activity Execution'], 'properties': [], "errors": None, 'links': None } get_node_relationships_mock.return_value = { "relationships": [{ "start_node": id_node, "end_node": 19, "name": "testRelation", "id": 0, "properties": None }, { "start_node": 15, "end_node": id_node, "name": "testReversedRelation", "id": 0, "properties": None }] } activity_execution = ActivityExecutionOut( additional_properties=[], id=id_node, relations=[ RelationInformation(second_node_id=19, name="testRelation", relation_id=0) ], reversed_relations=[ RelationInformation(second_node_id=15, name="testReversedRelation", relation_id=0) ]) activity_execution_service = ActivityExecutionService() result = activity_execution_service.delete_activity_execution(id_node) self.assertEqual(result, activity_execution) get_node_mock.assert_called_once_with(id_node) delete_node_mock.assert_called_once_with(id_node)
def test_update_activity_execution_with_error(self, get_node_mock): id_node = 1 get_node_mock.return_value = { 'id': id_node, 'errors': ['error'], 'links': None } not_found = NotFoundByIdModel(id=id_node, errors=['error']) additional_properties = [PropertyIn(key='identifier', value=5)] activity_execution_in = ActivityExecutionPropertyIn( id=id_node, additional_properties=additional_properties) activity_execution_service = ActivityExecutionService() result = activity_execution_service.update_activity_execution( id_node, activity_execution_in) self.assertEqual(result, not_found) get_node_mock.assert_called_once_with(id_node)
def test_save_activity_execution_without_errors(self, get_node_relationships_mock, get_node_mock, create_relationships_mock, create_properties_mock, create_node_mock): id_node = 1 get_node_mock.return_value = {'id': id_node, 'labels': ['Activity Execution'], 'properties': [], "errors": None, 'links': None} get_node_relationships_mock.return_value = {"relationships": [ {"start_node": id_node, "end_node": 19, "name": "testRelation", "id": 0, "properties": None}, {"start_node": 15, "end_node": id_node, "name": "testReversedRelation", "id": 0, "properties": None}]} create_node_mock.return_value = {'id': id_node, 'properties': None, "errors": None, 'links': None} create_properties_mock.return_value = {'id': id_node, 'errors': None, 'links': None} create_relationships_mock.return_value = {'start_node': 1, 'end_node': 2, 'name': 'hasParticipant', 'errors': None} additional_properties = [] activity_execution_in = ActivityExecutionIn(activity_id=2, arrangement_id=3) activity_execution_out = ActivityExecutionOut(additional_properties=additional_properties, relations= [RelationInformation(second_node_id=19, name="testRelation", relation_id=0)], reversed_relations= [RelationInformation(second_node_id=15, name="testReversedRelation", relation_id=0)], id=id_node) calls = [mock.call(2), mock.call(3), mock.call(1)] activity_execution_service = ActivityExecutionService() result = activity_execution_service.save_activity_execution(activity_execution_in) self.assertEqual(result, activity_execution_out) create_node_mock.assert_called_once_with('`Activity Execution`') # create_properties_mock.assert_not_called() create_relationships_mock.assert_not_called() get_node_mock.assert_has_calls(calls)
class ParticipationService: """ Object to handle logic of participation requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API activity_execution_service (ActivityExecutionService): Service to send activity execution requests participant_state_service (ParticipantStateService): Service to send participant state requests """ graph_api_service = GraphApiService() activity_execution_service = ActivityExecutionService() participant_state_service = ParticipantStateService() def save_participation(self, participation: ParticipationIn): """ Send request to graph api to create new participation Args: participation (ParticipationIn): Participation to be added Returns: Result of request as participation object """ node_response = self.graph_api_service.create_node("Participation") if node_response["errors"] is not None: return ParticipationOut(errors=node_response["errors"]) participation_id = node_response["id"] if participation.activity_execution_id is not None and \ type(self.activity_execution_service.get_activity_execution(participation.activity_execution_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.activity_execution_id, "hasActivityExecution") if participation.participant_state_id is not None and \ type(self.participant_state_service.get_participant_state(participation.participant_state_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.participant_state_id, "hasParticipantState") return self.get_participation(participation_id) def get_participations(self): """ Send request to graph api to get participations Returns: Result of request as list of participation objects """ get_response = self.graph_api_service.get_nodes("Participation") participations = [] for participation_node in get_response["nodes"]: properties = {'id': participation_node['id']} participation = BasicParticipationOut(**properties) participations.append(participation) return ParticipationsOut(participations=participations) def get_participation(self, participation_id: int): """ Send request to graph api to get given participation Args: participation_id (int): Id of participation Returns: Result of request as participation object """ get_response = self.graph_api_service.get_node(participation_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=participation_id, errors=get_response["errors"]) if get_response["labels"][0] != "Participation": return NotFoundByIdModel(id=participation_id, errors="Node not found.") participation = { 'id': get_response['id'], 'relations': [], 'reversed_relations': [] } relations_response = self.graph_api_service.get_node_relationships( participation_id) for relation in relations_response["relationships"]: if relation["start_node"] == participation_id: participation['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: participation['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ParticipationOut(**participation) def delete_participation(self, participation_id: int): """ Send request to graph api to delete given participation Args: participation_id (int): Id of participation Returns: Result of request as participation object """ get_response = self.get_participation(participation_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(participation_id) return get_response def update_participation_relationships(self, participation_id: int, participation: ParticipationIn): """ Send request to graph api to update given participation relationships Args: participation_id (int): Id of participation participation (ParticipationIn): Relationships to update Returns: Result of request as participation object """ get_response = self.get_participation(participation_id) if type(get_response) is NotFoundByIdModel: return get_response if participation.activity_execution_id is not None and \ type(self.activity_execution_service.get_activity_execution(participation.activity_execution_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.activity_execution_id, "hasActivityExecution") if participation.participant_state_id is not None and \ type(self.participant_state_service.get_participant_state(participation.participant_state_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.participant_state_id, "hasParticipantState") return self.get_participation(participation_id)
class ActivityExecutionRouter: """ Class for routing activity execution based requests Attributes: activity_execution_service (ActivityExecutionService): Service instance for activity execution """ activity_execution_service = ActivityExecutionService() @router.post("/activity_executions", tags=["activity executions"], response_model=ActivityExecutionOut) async def create_activity_execution( self, activity_execution: ActivityExecutionIn, response: Response): """ Create activity execution in database """ create_response = self.activity_execution_service.save_activity_execution( activity_execution) if create_response.errors is not None: response.status_code = 422 # add links from hateoas create_response.links = get_links(router) return create_response @router.get("/activity_executions", tags=["activity executions"], response_model=ActivityExecutionsOut) async def get_activity_executions(self, response: Response): """ Get activity executions from database """ get_response = self.activity_execution_service.get_activity_executions( ) # add links from hateoas get_response.links = get_links(router) return get_response @router.get("/activity_executions/{activity_execution_id}", tags=["activity executions"], response_model=Union[ActivityExecutionOut, NotFoundByIdModel]) async def get_activity_execution(self, activity_execution_id: int, response: Response): """ Get activity executions from database """ get_response = self.activity_execution_service.get_activity_execution( activity_execution_id) if get_response.errors is not None: response.status_code = 404 # add links from hateoas get_response.links = get_links(router) return get_response @router.delete("/activity_executions/{activity_execution_id}", tags=["activity executions"], response_model=Union[ActivityExecutionOut, NotFoundByIdModel]) async def delete_activity_execution(self, activity_execution_id: int, response: Response): """ Delete activity executions from database """ get_response = self.activity_execution_service.delete_activity_execution( activity_execution_id) if get_response.errors is not None: response.status_code = 404 # add links from hateoas get_response.links = get_links(router) return get_response @router.put("/activity_executions/{activity_execution_id}", tags=["activity executions"], response_model=Union[ActivityExecutionOut, NotFoundByIdModel]) async def update_activity_execution( self, activity_execution_id: int, activity_execution: ActivityExecutionPropertyIn, response: Response): """ Update activity execution model in database """ update_response = self.activity_execution_service.update_activity_execution( activity_execution_id, activity_execution) if update_response.errors is not None: response.status_code = 404 # add links from hateoas update_response.links = get_links(router) return update_response @router.put("/activity_executions/{activity_execution_id}/relationships", tags=["activity executions"], response_model=Union[ActivityExecutionOut, NotFoundByIdModel]) async def update_activity_execution_relationships( self, activity_execution_id: int, activity_execution: ActivityExecutionRelationIn, response: Response): """ Update activity executions relations in database """ update_response = self.activity_execution_service.update_activity_execution_relationships( activity_execution_id, activity_execution) if update_response.errors is not None: response.status_code = 404 # add links from hateoas update_response.links = get_links(router) return update_response
class ScenarioService: """ Object to handle logic of scenarios requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API activity_execution_service (ActivityExecutionService): Service used to communicate with ActivityExecution experiment_service (ExperimentService): Service used to communicate with Experiment """ graph_api_service = GraphApiService() activity_execution_service = ActivityExecutionService() experiment_service = ExperimentService() def save_scenario(self, scenario: ScenarioIn): """ Send request to graph api to create new scenario Args: scenario (ScenarioIn): Scenario to be added Returns: Result of request as scenario object """ activity_executions = [ self.activity_execution_service.save_activity_execution( activity_execution=activity_execution) for activity_execution in scenario.activity_executions ] self.graph_api_service.create_relationships(scenario.experiment_id, activity_executions[0].id, 'hasScenario') [ self.graph_api_service.create_relationships( activity_executions[index - 1].id, activity_executions[index].id, 'nextActivityExecution') for index in range(1, len(activity_executions)) ] return ScenarioOut(experiment_id=scenario.experiment_id, activity_executions=activity_executions) def add_activity_execution(self, previous_id: int, activity_execution: ActivityExecutionIn): """ Send request to graph api to add activity_execution to scenario Args: previous_id (int): Id of previous activity_execution or experiment activity_execution (ActivityExecutionIn): ActivityExecution to be added Returns: Result of request as activity_execution object """ relationships = self.graph_api_service.get_node_relationships( previous_id)['relationships'] activity_execution_result = self.activity_execution_service.save_activity_execution( activity_execution) if previous_id in [ relation['start_node'] for relation in relationships if relation['name'] == 'hasScenario' ]: self.graph_api_service.create_relationships( previous_id, activity_execution_result.id, 'hasScenario') else: self.graph_api_service.create_relationships( previous_id, activity_execution_result.id, 'nextActivityExecution') try: next_id, relation_id = [ (relation['end_node'], relation['id']) for relation in relationships if relation['name'] in ['hasScenario', 'nextActivityExecution'] and relation['start_node'] == previous_id ][0] except IndexError: return activity_execution_result self.graph_api_service.create_relationships( activity_execution_result.id, next_id, 'nextActivityExecution') self.graph_api_service.delete_relationship(relation_id) return activity_execution_result def change_order_middle_with_last(self, middle_id, last_id, middle_relationships, last_relationships): """ Changes order of the middle node and the last node Args: middle_id (int): Id of the middle node last_id (ActivityExecutionIn): Id of the last node middle_relationships: Relationships of the middle node last_relationships: Relationships of the last node Returns: """ start_node, end_node, relation_name = ( middle_relationships[0]['start_node'], last_id, middle_relationships[0]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) if middle_relationships[1] == last_relationships[0]: # nodes are next to each other start_node, end_node, relation_name = ( last_id, middle_relationships[1]['start_node'], middle_relationships[1]['name']) self.graph_api_service.create_relationships( start_node, end_node, relation_name) return # nodes are separated by other nodes start_node, end_node, relation_name = ( last_id, middle_relationships[1]['end_node'], middle_relationships[1]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) start_node, end_node, relation_name = ( last_relationships[0]['start_node'], middle_id, last_relationships[0]['name']) if start_node != end_node: self.graph_api_service.create_relationships( start_node, end_node, relation_name) return def change_order_middle_with_middle(self, middle_id, last_id, middle_relationships, last_relationships): """ Changes order of the two middle nodes Args: middle_id (int): Id of the middle node last_id (ActivityExecutionIn): Id of the middle node but second in order middle_relationships: Relationships of the middle node last_relationships: Relationships of the last node Returns: """ start_node, end_node, relation_name = ( middle_relationships[0]['start_node'], last_id, middle_relationships[0]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) if middle_relationships[1] == last_relationships[0]: # nodes are next to each other start_node, end_node, relation_name = ( last_id, middle_id, middle_relationships[1]['name']) self.graph_api_service.create_relationships( start_node, end_node, relation_name) start_node, end_node, relation_name = ( middle_id, last_relationships[1]['end_node'], last_relationships[1]['name']) self.graph_api_service.create_relationships( start_node, end_node, relation_name) return start_node, end_node, relation_name = ( last_id, middle_relationships[1]['end_node'], middle_relationships[1]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) start_node, end_node, relation_name = ( last_relationships[0]['start_node'], middle_id, last_relationships[0]['name']) if start_node != end_node: self.graph_api_service.create_relationships( start_node, end_node, relation_name) start_node, end_node, relation_name = ( middle_id, last_relationships[1]['end_node'], last_relationships[1]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) return def what_order(self, previous_relationships, activity_execution_relationships): """ Finds which node is in which order (starting from experiment) in the scenario Args: previous_relationships: Relationships of the previous node activity_execution_relationships: Relationships of the activity execution node Returns: True when is the first in order False when is the second in order """ p_relationships = previous_relationships p_count = False a_relationships = activity_execution_relationships a_count = False while True: if p_relationships[0]['name'] is not None and p_relationships[0][ 'name'] in ['hasScenario']: p_count = True break if a_relationships[0]['name'] is not None and a_relationships[0][ 'name'] in ['hasScenario']: a_count = True break p_id = p_relationships[0]['start_node'] p_relationships = self.graph_api_service.get_node_relationships( p_id)['relationships'] p_relationships = [ relation for relation in p_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] and relation['end_node'] == p_id ] a_id = a_relationships[0]['start_node'] a_relationships = self.graph_api_service.get_node_relationships( a_id)['relationships'] a_relationships = [ relation for relation in a_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] and relation['end_node'] == a_id ] return p_count, a_count def swap_order_in_relationships_array(self, relationships, node_id): """ Swaps order of relationships list so they are saved in order starting from experiment Args: relationships: List of relationships node_id: Id of node, that relationships belong to Returns: relationships: List of relationships in specified order """ if relationships[0]['start_node'] == node_id: relationships[0], relationships[1] = relationships[ 1], relationships[0] return relationships def change_order(self, order_change: OrderChangeIn): """ Send request to graph api to change order in scenario Args: order_change (OrderChangeIn): Ids of activity_executions to change order by Returns: Result of request as changed order ids """ # save all relationships in lists previous_relationships = self.graph_api_service.get_node_relationships( order_change.previous_id)['relationships'] activity_execution_relationships = \ self.graph_api_service.get_node_relationships(order_change.activity_execution_id)['relationships'] # check which node is before the other previous_first, activity_execution_first = self.what_order( previous_relationships, activity_execution_relationships) # delete nextActivityExecution and hasScenario relationships [ self.graph_api_service.delete_relationship(relation['id']) for relation in previous_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] [ self.graph_api_service.delete_relationship(relation['id']) for relation in activity_execution_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] # save nextActivityExecution and hasScenario relationships previous_relationships = [ relation for relation in previous_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] activity_execution_relationships = [ relation for relation in activity_execution_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] # swap order of relationships if needed previous_relationships = self.swap_order_in_relationships_array( previous_relationships, order_change.previous_id) activity_execution_relationships = self.swap_order_in_relationships_array( activity_execution_relationships, order_change.activity_execution_id) if len(activity_execution_relationships) == 1: # change order when activity execution node is last self.change_order_middle_with_last( middle_id=order_change.previous_id, last_id=order_change.activity_execution_id, middle_relationships=previous_relationships, last_relationships=activity_execution_relationships) elif len(previous_relationships) == 1: # change order when previous node is last self.change_order_middle_with_last( middle_id=order_change.activity_execution_id, last_id=order_change.previous_id, middle_relationships=activity_execution_relationships, last_relationships=previous_relationships) elif len(previous_relationships) == 2 and len( activity_execution_relationships) == 2: if previous_first is True: # change order when previous node is before activity execution node self.change_order_middle_with_middle( middle_id=order_change.previous_id, last_id=order_change.activity_execution_id, middle_relationships=previous_relationships, last_relationships=activity_execution_relationships) elif activity_execution_first is True: # change order when activity execution node is before previous node self.change_order_middle_with_middle( middle_id=order_change.activity_execution_id, last_id=order_change.previous_id, middle_relationships=activity_execution_relationships, last_relationships=previous_relationships) return OrderChangeOut( previous_id=order_change.previous_id, activity_execution_id=order_change.activity_execution_id) def delete_activity_execution(self, activity_execution_id: int): """ Send request to graph api to delete activity_execution from scenario Args: activity_execution_id (int): Id of activity_execution to delete Returns: Result of request as activity_execution object """ relationships = self.graph_api_service.get_node_relationships( activity_execution_id)['relationships'] if len(relationships) == 0: return ActivityExecutionOut(errors='Relationships not found') activity_execution = self.graph_api_service.delete_node( activity_execution_id) properties = { p['key']: p['value'] for p in activity_execution['properties'] } additional_properties = [ PropertyIn(key=key, value=value) for key, value in properties.items() if key not in ['activity'] ] activity_execution_response = ActivityExecutionOut( id=activity_execution['id'], activity=properties['activity'], additional_properties=additional_properties) if len([ relationship for relationship in relationships if relationship['name'] in ['hasScenario', 'nextActivityExecution'] ]) == 1: return activity_execution_response start_node = [ relationship['start_node'] for relationship in relationships if relationship['end_node'] == activity_execution_id and relationship['name'] in ['hasScenario', 'nextActivityExecution'] ][0] end_node = [ relationship['end_node'] for relationship in relationships if relationship['start_node'] == activity_execution_id and relationship['name'] == 'nextActivityExecution' ][0] self.graph_api_service.create_relationships(start_node, end_node, relationships[0]['name']) return activity_execution_response def get_scenario(self, node_id: int): """ Send request to graph api to get activity executions and experiment from scenario Args: node_id (int): Id of experiment or activity execution which is included in scenario Returns: Result of request as Scenario object """ get_response = self.graph_api_service.get_node(node_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=node_id, errors=get_response["errors"]) if get_response["labels"][0] not in [ "Activity Execution", "Experiment" ]: return NotFoundByIdModel(id=node_id, errors="Node not found.") if get_response["labels"][0] == "Activity Execution": return self.get_scenario_by_activity_execution(node_id) elif get_response["labels"][0] == "Experiment": return self.get_scenario_by_experiment(node_id) def get_scenario_by_experiment(self, experiment_id: int): """ Send request to graph api to get activity_executions from scenario which starts in experiment Args: experiment_id (int): Id of experiment where scenario starts Returns: Result of request as Scenario object """ activity_executions = [] experiment = self.experiment_service.get_experiment(experiment_id) if type(experiment) is NotFoundByIdModel: return experiment scenario = {'experiment_id': experiment_id, 'activity_executions': []} for relation in experiment.relations: if relation.name == "hasScenario": self.get_scenario_after_activity_execution( relation.second_node_id, activity_executions) [ scenario['activity_executions'].append(a) for a in activity_executions if a not in scenario['activity_executions'] ] return ScenarioOut(**scenario) def get_scenario_by_activity_execution(self, activity_execution_id: int): """ Send request to graph api to get activity_executions from scenario which has activity execution id incuded Args: activity_execution_id (int): Id of activity execution included in scenario Returns: Result of request as Scenario object """ activity_executions = [] activity_executions_before = [] activity_execution = self.activity_execution_service.get_activity_execution( activity_execution_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution experiment_id = self.get_scenario_before_activity_execution( activity_execution_id, activity_executions_before) [ activity_executions.append(a) for a in activity_executions_before if a not in activity_executions ] activity_executions_after = [] self.get_scenario_after_activity_execution(activity_execution_id, activity_executions_after) [ activity_executions.append(a) for a in activity_executions_after if a not in activity_executions ] scenario = {'experiment_id': experiment_id, 'activity_executions': []} [ scenario['activity_executions'].append(a) for a in activity_executions ] return ScenarioOut(**scenario) def get_scenario_after_activity_execution(self, activity_execution_id: int, activity_executions: []): """ Gets activity executions from scenario which are saved after activity_execution_id Args: activity_execution_id (int): Id of activity execution included in scenario activity_executions: List of activity executions in scenario """ activity_execution = self.activity_execution_service.get_activity_execution( activity_execution_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) for relation in activity_execution.relations: if relation.name == "nextActivityExecution": activity_execution = self.activity_execution_service.get_activity_execution( relation.second_node_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) [ self.get_scenario_after_activity_execution( activity_execution.id, activity_executions) for r in activity_execution.relations if r.name == "nextActivityExecution" ] def get_scenario_before_activity_execution(self, activity_execution_id: int, activity_executions: []): """ Gets activity executions from scenario which are saved before activity_execution_id Args: activity_execution_id (int): Id of activity execution included in scenario activity_executions: List of activity executions in scenario """ activity_execution = self.activity_execution_service.get_activity_execution( activity_execution_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) for relation in activity_execution.reversed_relations: if relation.name == "nextActivityExecution": activity_execution = self.activity_execution_service.get_activity_execution( relation.second_node_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) return self.get_scenario_before_activity_execution( activity_execution.id, activity_executions) elif relation.name == "hasScenario": experiment = self.experiment_service.get_experiment( relation.second_node_id) if type(experiment) is NotFoundByIdModel: return experiment return experiment.id