public static List<GraphVertex> calculateImpact(BusinessServiceGraph graph, GraphVertex vertex) { if (vertex == null) { return Collections.emptyList(); } // Gather the list of parent vertices that are impacted by the current vertex final List<GraphVertex> impactedParentVertices = graph.getInEdges(vertex).stream() .filter(e -> calculateImpacting(graph, graph.getOpposite(vertex, e)).contains(e)) .map(e -> graph.getOpposite(vertex, e)) .sorted() .collect(Collectors.toList()); // Recurse final List<GraphVertex> impacts = Lists.newArrayList(impactedParentVertices); for (GraphVertex impactedParentVertex : impactedParentVertices) { impacts.addAll(calculateImpact(graph, impactedParentVertex)); } return impacts; }
private static Set<GraphVertex> getImpactingVertices(BusinessServiceStateMachine stateMachine, BusinessServiceGraph graph, BusinessService businessService) { // Only consider a feasible amount of edges. See NMS-8501 and NMS-8527 for more details if (graph.getOutEdges(graph.getVertexByBusinessServiceId(businessService.getId())).size() <= MAX_EDGES_FOR_IMPACTING) { return stateMachine.calculateImpacting(businessService) .stream() .map(edge -> graph.getDest(edge)) // DO NOT CONVERT to lamda method reference. See NMS-10529 .collect(Collectors.toSet()); } LOG.warn("Try to calculate impacting vertices for more than {} edges. This is currently not supported. See http://http://issues.opennms.org/browse/NMS-8527.", MAX_EDGES_FOR_IMPACTING); return Sets.newHashSet(); } }
@Override public Void visit(ApplicationVertex vertex) { graphVertex.set(graph.getVertexByApplicationId(vertex.getApplicationId())); return null; } });
@Override public void handleAllAlarms(List<AlarmWrapper> alarms) { final Set<String> reductionKeysFromGivenAlarms = new HashSet<>(alarms.size()); m_rwLock.writeLock().lock(); try { for (AlarmWrapper alarm : alarms) { // Recursively propagate the status for all of the given alarms updateAndPropagateVertex(m_g, m_g.getVertexByReductionKey(alarm.getReductionKey()), alarm.getStatus()); // Keep track of the reduction keys that have been processed reductionKeysFromGivenAlarms.add(alarm.getReductionKey()); } for (String missingReductionKey : Sets.difference(m_g.getReductionKeys(), reductionKeysFromGivenAlarms)) { // There is a vertex on the graph that corresponds to this reduction key // but no alarm with this reduction key exists updateAndPropagateVertex(m_g, m_g.getVertexByReductionKey(missingReductionKey), Status.INDETERMINATE); } } finally { m_rwLock.writeLock().unlock(); } }
@Override public ThresholdResultExplanation explain(BusinessService businessService, Threshold threshold) { final GraphVertex vertex = getGraph().getVertexByBusinessServiceId(businessService.getId()); // Calculate the weighed statuses from the child edges List<StatusWithIndex> statusesWithIndices = weighEdges(getGraph().getOutEdges(vertex)); List<Status> statuses = statusesWithIndices.stream() .map(StatusWithIndex::getStatus) .collect(Collectors.toList()); // Reduce Status reducedStatus = threshold.reduce(statusesWithIndices) .orElse(new StatusWithIndices(MIN_SEVERITY, Collections.emptyList())) .getStatus(); ThresholdResultExplanation explanation = new ThresholdResultExplanation(); explanation.setStatus(reducedStatus); explanation.setHitsByStatus(threshold.getHitsByStatus(statuses)); explanation.setGraphEdges(getGraph().getOutEdges(vertex)); explanation.setWeightStatuses(statuses); explanation.setFunction(threshold); Map<GraphEdge, GraphVertex> graphEdgeToGraphVertex = new HashMap<>(); for (Edge eachEdge : businessService.getEdges()) { GraphVertex vertexForEdge = getGraph().getVertexByEdgeId(eachEdge.getId()); GraphEdge graphEdge = getGraph().getGraphEdgeByEdgeId(eachEdge.getId()); if (vertexForEdge != null && graphEdge != null) { graphEdgeToGraphVertex.put(graphEdge, vertexForEdge); } } explanation.setGraphEdgeToGraphVertexMapping(graphEdgeToGraphVertex); return explanation; }
private void addVertex(BusinessServiceGraph graph, GraphVertex graphVertex, AbstractBusinessServiceVertex topologyVertex) { if (topologyVertex == null) { // Create a topology vertex for the current vertex topologyVertex = createTopologyVertex(graphVertex); addVertices(topologyVertex); } for (GraphEdge graphEdge : graph.getOutEdges(graphVertex)) { GraphVertex childVertex = graph.getOpposite(graphVertex, graphEdge); // Create a topology vertex for the child vertex AbstractBusinessServiceVertex childTopologyVertex = createTopologyVertex(childVertex); graph.getInEdges(childVertex).stream() .map(GraphEdge::getFriendlyName) .filter(s -> !Strings.isNullOrEmpty(s)) .findFirst() .ifPresent(childTopologyVertex::setLabel); addVertices(childTopologyVertex); // Connect the two childTopologyVertex.setParent(topologyVertex); Edge edge = new BusinessServiceEdge(graphEdge, topologyVertex, childTopologyVertex); addEdges(edge); // Recurse addVertex(graph, childVertex, childTopologyVertex); } }
@Override public Void visit(BusinessServiceVertex vertex) { graphVertex.set(graph.getVertexByBusinessServiceId(vertex.getServiceId())); return null; }
private void createRowForVertex(BusinessServiceGraph graph, GraphVertex graphVertex, BusinessServiceRow parentRow) { final BusinessService businessService = graphVertex.getBusinessService(); if (businessService == null) { return; } final long rowId = rowIdCounter.incrementAndGet(); final Long parentBusinessServiceId = parentRow != null ? parentRow.getBusinessService().getId() : null; final BusinessServiceRow row = new BusinessServiceRow(rowId, businessService, parentBusinessServiceId); if (parentRow != null) { rowIdToParentRowIdMapping.put(rowId, parentRow.getRowId()); } addBean(row); // Recurse with all of the children graph.getOutEdges(graphVertex).stream() .map(e -> graph.getOpposite(graphVertex, e)) .filter(v -> v.getBusinessService() != null) .sorted((v1, v2) -> v1.getBusinessService().getName().compareTo(v2.getBusinessService().getName())) .forEach(v -> createRowForVertex(graph, v, row)); }
sm.setBusinessServices(graph.getVertices().stream() .map(GraphVertex::getBusinessService) .filter(Objects::nonNull) for (String reductionKey : graph.getReductionKeys()) { GraphVertex reductionKeyVertex = graph.getVertexByReductionKey(reductionKey); sm.handleNewOrUpdatedAlarm(new AlarmWrapper() { @Override
public static Set<GraphEdge> calculateImpacting(BusinessServiceGraph graph, GraphVertex parent) { // Grab all of the child edges List<GraphEdge> childEdges = graph.getOutEdges(parent).stream() .collect(Collectors.toList()); // Weigh and reduce the statuses List<StatusWithIndex> statuses = DefaultBusinessServiceStateMachine.weighEdges(childEdges); Optional<StatusWithIndices> reducedStatus = parent.getReductionFunction().reduce(statuses); if (!reducedStatus.isPresent()) { return Collections.emptySet(); } else { return reducedStatus.get().getIndices().stream() .map(childEdges::get) .collect(Collectors.toSet()); } } }
@Override public List<GraphVertex> calculateImpact(String reductionKey) { m_rwLock.readLock().lock(); try { final GraphVertex vertex = m_g.getVertexByReductionKey(reductionKey); return calculateImpact(vertex); } finally { m_rwLock.readLock().unlock(); } }
public static List<GraphVertex> calculateRootCause(BusinessServiceGraph graph, GraphVertex vertex) { if (vertex == null || vertex.getStatus().isLessThanOrEqual(Status.NORMAL)) { return Collections.emptyList(); } // Gather the list of child vertices that impact the current vertex final List<GraphVertex> childVerticesWithImpact = calculateImpacting(graph, vertex) .stream() .map(e -> graph.getOpposite(vertex, e)) .sorted() .collect(Collectors.toList()); // Recurse final List<GraphVertex> causes = Lists.newArrayList(childVerticesWithImpact); for (GraphVertex childVertexWithImpact : childVerticesWithImpact) { causes.addAll(calculateRootCause(graph, childVertexWithImpact)); } return causes; }
@Override public Void visit(IpServiceVertex vertex) { graphVertex.set(graph.getVertexByIpServiceId(vertex.getIpServiceId())); return null; }
private void load() { resetContainer(); BusinessServiceGraph graph = businessServiceManager.getGraph(); for (GraphVertex topLevelBusinessService : graph.getVerticesByLevel(0)) { addVertex(graph, topLevelBusinessService, null); } }
@Override public Status getOperationalStatus(Edge edge) { m_rwLock.readLock().lock(); try { GraphVertex vertex = m_g.getVertexByEdgeId(edge.getId()); if (vertex != null) { return vertex.getStatus(); } return null; } finally { m_rwLock.readLock().unlock(); } }
@Override public Set<GraphEdge> calculateImpacting(BusinessService businessService) { m_rwLock.readLock().lock(); try { final GraphVertex vertex = m_g.getVertexByBusinessServiceId(businessService.getId()); return GraphAlgorithms.calculateImpacting(m_g, vertex); } finally { m_rwLock.readLock().unlock(); } }
private void createRowForVertex(BusinessServiceGraph graph, GraphVertex graphVertex, BusinessServiceRow parentRow) { final BusinessService businessService = graphVertex.getBusinessService(); if (businessService == null) { return; } final long rowId = rowIdCounter.incrementAndGet(); final Long parentBusinessServiceId = parentRow != null ? parentRow.getBusinessService().getId() : null; final BusinessServiceRow row = new BusinessServiceRow(rowId, businessService, parentBusinessServiceId); if (parentRow != null) { rowIdToParentRowIdMapping.put(rowId, parentRow.getRowId()); } addBean(row); // Recurse with all of the children graph.getOutEdges(graphVertex).stream() .map(e -> graph.getOpposite(graphVertex, e)) .filter(v -> v.getBusinessService() != null) .sorted((v1, v2) -> v1.getBusinessService().getName().compareTo(v2.getBusinessService().getName())) .forEach(v -> createRowForVertex(graph, v, row)); }
private void reduceUpdateAndPropagateVertex(BusinessServiceGraph graph, GraphVertex vertex) { if (vertex == null) { // Nothing to do here return; } // Calculate the weighed statuses from the child edges List<StatusWithIndex> statuses = weighEdges(graph.getOutEdges(vertex)); // Reduce Optional<StatusWithIndices> reducedStatus = vertex.getReductionFunction().reduce(statuses); Status newStatus; if (reducedStatus.isPresent()) { newStatus = reducedStatus.get().getStatus(); } else { newStatus = MIN_SEVERITY; } // Update and propagate updateAndPropagateVertex(graph, vertex, newStatus); }
for (String reductionKey : g.getReductionKeys()) { GraphVertex reductionKeyVertex = m_g.getVertexByReductionKey(reductionKey); if (reductionKeyVertex != null) { updateAndPropagateVertex(g, g.getVertexByReductionKey(reductionKey), reductionKeyVertex.getStatus()); } else { reductionsKeysToLookup.add(reductionKey); final Map<String, AlarmWrapper> lookup = m_alarmProvider.lookup(reductionsKeysToLookup); for (Entry<String, AlarmWrapper> eachEntry : lookup.entrySet()) { updateAndPropagateVertex(g, g.getVertexByReductionKey(eachEntry.getKey()), eachEntry.getValue().getStatus());
@Override public Void visit(ReductionKeyVertex vertex) { graphVertex.set(graph.getVertexByReductionKey(vertex.getReductionKey())); return null; }