From 8c2d94b50f6d23895f1c8d4516b9b7bb92f92c83 Mon Sep 17 00:00:00 2001 From: Alexey Weyl Date: Sun, 13 Nov 2016 15:16:45 +0200 Subject: [PATCH] remove edges which are is_deleted=true Change-Id: I4f56c55c861885c459199d39d7fe6986c10e9300 --- vitrage/api_handler/apis/base.py | 2 ++ vitrage/api_handler/apis/rca.py | 17 +++++----- vitrage/api_handler/apis/topology.py | 31 ++++++++++--------- vitrage/graph/algo_driver/algorithm.py | 12 +++++-- .../graph/algo_driver/networkx_algorithm.py | 27 +++++++++++++--- vitrage/graph/driver/graph.py | 4 ++- vitrage/graph/driver/networkx_graph.py | 7 +++-- 7 files changed, 67 insertions(+), 33 deletions(-) diff --git a/vitrage/api_handler/apis/base.py b/vitrage/api_handler/apis/base.py index 6281415b3..4df244944 100644 --- a/vitrage/api_handler/apis/base.py +++ b/vitrage/api_handler/apis/base.py @@ -78,6 +78,8 @@ ALARM_QUERY = { VProps.IS_PLACEHOLDER: False } +EDGE_QUERY = {'==': {EProps.IS_DELETED: False}} + class EntityGraphApisBase(object): TENANT_PROPERTY = 'tenant' diff --git a/vitrage/api_handler/apis/rca.py b/vitrage/api_handler/apis/rca.py index 518c49ec2..fbb1a22ef 100644 --- a/vitrage/api_handler/apis/rca.py +++ b/vitrage/api_handler/apis/rca.py @@ -15,6 +15,7 @@ from oslo_log import log from vitrage.api_handler.apis.base import ALARMS_ALL_QUERY +from vitrage.api_handler.apis.base import EDGE_QUERY from vitrage.api_handler.apis.base import EntityGraphApisBase from vitrage.api_handler.apis.base import RCA_QUERY from vitrage.graph import create_algorithm @@ -38,14 +39,14 @@ class RcaApis(EntityGraphApisBase): is_admin_project = ctx.get(self.IS_ADMIN_PROJECT_PROPERTY, False) ga = create_algorithm(self.entity_graph) - found_graph_out = ga.graph_query_vertices( - query_dict=RCA_QUERY, - root_id=root, - direction=Direction.OUT) - found_graph_in = ga.graph_query_vertices( - query_dict=RCA_QUERY, - root_id=root, - direction=Direction.IN) + found_graph_out = ga.graph_query_vertices(query_dict=RCA_QUERY, + root_id=root, + direction=Direction.OUT, + edge_query_dict=EDGE_QUERY) + found_graph_in = ga.graph_query_vertices(query_dict=RCA_QUERY, + root_id=root, + direction=Direction.IN, + edge_query_dict=EDGE_QUERY) if all_tenants == '1': unified_graph = found_graph_in diff --git a/vitrage/api_handler/apis/topology.py b/vitrage/api_handler/apis/topology.py index 647697b95..c8f088637 100644 --- a/vitrage/api_handler/apis/topology.py +++ b/vitrage/api_handler/apis/topology.py @@ -15,6 +15,7 @@ from oslo_log import log from vitrage.api_handler.apis.base import ALARMS_ALL_QUERY +from vitrage.api_handler.apis.base import EDGE_QUERY from vitrage.api_handler.apis.base import EntityGraphApisBase from vitrage.api_handler.apis.base import TOPOLOGY_AND_ALARMS_QUERY from vitrage.common.constants import EntityCategory @@ -54,24 +55,24 @@ class TopologyApis(EntityGraphApisBase): {'==': {VProps.PROJECT_ID: None}}]} current_query = {'and': [query, project_query]} - graph = ga.graph_query_vertices( - query_dict=current_query, - root_id=root, - depth=depth) + graph = ga.graph_query_vertices(query_dict=current_query, + root_id=root, + depth=depth, + edge_query_dict=EDGE_QUERY) # By default the graph_type is 'graph' else: if all_tenants: q = query if query else TOPOLOGY_AND_ALARMS_QUERY - graph = \ - ga.create_graph_from_matching_vertices(query_dict=q) + graph = ga.create_graph_from_matching_vertices( + query_dict=q, + edge_attr_filter={VProps.IS_DELETED: False}) else: - graph = \ - self._get_topology_for_specific_project( - ga, - query, - project_id, - is_admin_project, - root) + graph = self._get_topology_for_specific_project( + ga, + query, + project_id, + is_admin_project, + root) alarms = graph.get_vertices(query_dict=ALARMS_ALL_QUERY) self._add_resource_details_to_alarms(alarms) @@ -113,7 +114,9 @@ class TopologyApis(EntityGraphApisBase): default_query = {'or': [resource_query, alarm_query]} q = default_query - tmp_graph = ga.create_graph_from_matching_vertices(query_dict=q) + tmp_graph = ga.create_graph_from_matching_vertices( + query_dict=q, + edge_attr_filter={VProps.IS_DELETED: False}) graph = ga.subgraph(self._topology_for_unrooted_graph(ga, tmp_graph, root)) diff --git a/vitrage/graph/algo_driver/algorithm.py b/vitrage/graph/algo_driver/algorithm.py index c5e8adfec..846773df0 100644 --- a/vitrage/graph/algo_driver/algorithm.py +++ b/vitrage/graph/algo_driver/algorithm.py @@ -32,8 +32,12 @@ class GraphAlgorithm(object): self.graph = graph @abc.abstractmethod - def graph_query_vertices(self, query_dict=None, root_id=None, depth=None, - direction=None): + def graph_query_vertices(self, + query_dict=None, + root_id=None, + depth=None, + direction=None, + edge_query_dict=None): """Create a sub graph of all the matching vertices and their edges BFS traversal over the graph starting from root, each vertex is @@ -93,7 +97,8 @@ class GraphAlgorithm(object): @abc.abstractmethod def create_graph_from_matching_vertices(self, vertex_attr_filter=None, - query_dict=None): + query_dict=None, + edge_attr_filter=None): """Generate graph using the query Finds all the vertices in the graph matching the query, and returns @@ -101,6 +106,7 @@ class GraphAlgorithm(object): :type vertex_attr_filter: dictionary :type query_dict: dictionary + :type edge_attr_filter: dictionary :rtype: NXGraph """ pass diff --git a/vitrage/graph/algo_driver/networkx_algorithm.py b/vitrage/graph/algo_driver/networkx_algorithm.py index 9eb5ce5df..5ac52cc48 100644 --- a/vitrage/graph/algo_driver/networkx_algorithm.py +++ b/vitrage/graph/algo_driver/networkx_algorithm.py @@ -21,6 +21,7 @@ from vitrage.graph.algo_driver.algorithm import GraphAlgorithm from vitrage.graph.algo_driver.sub_graph_matching import subgraph_matching from vitrage.graph.driver import Direction from vitrage.graph.driver import NXGraph +from vitrage.graph.filter import check_filter from vitrage.graph.query import create_predicate LOG = logging.getLogger(__name__) @@ -36,8 +37,12 @@ class NXAlgorithm(GraphAlgorithm): """ super(NXAlgorithm, self).__init__(graph) - def graph_query_vertices(self, query_dict=None, root_id=None, depth=None, - direction=Direction.BOTH): + def graph_query_vertices(self, + query_dict=None, + root_id=None, + depth=None, + direction=Direction.BOTH, + edge_query_dict=None): graph = NXGraph('graph') @@ -50,6 +55,11 @@ class NXAlgorithm(GraphAlgorithm): else: match_func = create_predicate(query_dict) + if not edge_query_dict: + edge_match_func = lambda item: True + else: + edge_match_func = create_predicate(edge_query_dict) + if not match_func(root_data): LOG.info('graph_query_vertices: root %s does not match filter %s', str(root_id), str(query_dict)) @@ -67,7 +77,8 @@ class NXAlgorithm(GraphAlgorithm): (n_list, e_list) = self.graph._neighboring_nodes_edges_query( node_id, direction=direction, - vertex_predicate=match_func) + vertex_predicate=match_func, + edge_predicate=edge_match_func) n_result.extend([v_id for v_id, data in n_list]) nodes_q.extend([(v_id, curr_depth + 1) for v_id, data in n_list]) @@ -85,7 +96,8 @@ class NXAlgorithm(GraphAlgorithm): def create_graph_from_matching_vertices(self, vertex_attr_filter=None, - query_dict=None): + query_dict=None, + edge_attr_filter=None): if query_dict: vertices = self.graph.get_vertices(query_dict=query_dict) elif vertex_attr_filter: @@ -98,6 +110,13 @@ class NXAlgorithm(GraphAlgorithm): graph = NXGraph('graph') graph._g = self.graph._g.subgraph(vertices_ids) + + # delete non matching edges + if edge_attr_filter: + for source, target, edge_data in graph._g.edges_iter(data=True): + if not check_filter(edge_data, edge_attr_filter): + graph.remove_edge(u=source, v=target) + LOG.debug('match query, find graph: nodes %s, edges %s', str(graph._g.nodes(data=True)), str(graph._g.edges(data=True))) diff --git a/vitrage/graph/driver/graph.py b/vitrage/graph/driver/graph.py index b4c97a335..c508e0eec 100644 --- a/vitrage/graph/driver/graph.py +++ b/vitrage/graph/driver/graph.py @@ -253,7 +253,9 @@ class Graph(object): pass @abc.abstractmethod - def get_vertices(self, vertex_attr_filter=None, query_dict=None): + def get_vertices(self, + vertex_attr_filter=None, + query_dict=None): """Get vertices list with an optional match filter To filter the vertices, specify property values for diff --git a/vitrage/graph/driver/networkx_graph.py b/vitrage/graph/driver/networkx_graph.py index 1dc3c7830..5c39d0d52 100644 --- a/vitrage/graph/driver/networkx_graph.py +++ b/vitrage/graph/driver/networkx_graph.py @@ -206,7 +206,9 @@ class NXGraph(Graph): """ self._g.remove_edge(u=e.source_id, v=e.target_id, key=e.label) - def get_vertices(self, vertex_attr_filter=None, query_dict=None): + def get_vertices(self, + vertex_attr_filter=None, + query_dict=None): def check_vertex(vertex_data): return check_filter(vertex_data[1], vertex_attr_filter) @@ -242,8 +244,7 @@ class NXGraph(Graph): def _neighboring_nodes_edges_query(self, v_id, vertex_predicate=None, edge_predicate=None, - direction=Direction.BOTH, - ): + direction=Direction.BOTH): if not direction: LOG.error("_neighboring_nodes_edges: direction cannot be None") raise AttributeError("neighbors: direction cannot be None")