public TopologyTestRunResource(StreamlineAuthorizer authorizer, StreamCatalogService catalogService, TopologyActionsService actionsService) { this.authorizer = authorizer; this.catalogService = catalogService; this.actionsService = actionsService; this.eventLogFileReader = new EventLogFileReader(); this.objectMapper = new ObjectMapper(); }
@Override public int hashCode() { int result = (int) (getTimestamp() ^ (getTimestamp() >>> 32)); result = 31 * result + (getComponentName() != null ? getComponentName().hashCode() : 0); result = 31 * result + (getStreamId() != null ? getStreamId().hashCode() : 0); result = 31 * result + (getTargetComponents() != null ? getTargetComponents().hashCode() : 0); result = 31 * result + (getEventId() != null ? getEventId().hashCode() : 0); result = 31 * result + (getRootIds() != null ? getRootIds().hashCode() : 0); result = 31 * result + (getParentIds() != null ? getParentIds().hashCode() : 0); result = 31 * result + (getFieldsAndValues() != null ? getFieldsAndValues().hashCode() : 0); return result; }
public List<EventInformation> loadEventLogFile(File eventLogFile) throws IOException { return loadEventLogFileAsStream(eventLogFile).collect(toList()); }
public GroupedCorrelationEvents(Map<String, EventInformation> correlatedEvents, String rootEventId) { this.allEvents = correlatedEvents; Map<String, ComponentGroupedEvents> unsortedComponentGroupedEvents = new HashMap<>(); correlatedEvents.values().forEach(event -> { String sourceComponentName = event.getComponentName(); Set<String> targetComponents = event.getTargetComponents(); ComponentGroupedEvents groupedEvents = unsortedComponentGroupedEvents.get(sourceComponentName); if (groupedEvents == null) { groupedEvents = new ComponentGroupedEvents(sourceComponentName); unsortedComponentGroupedEvents.put(sourceComponentName, groupedEvents); } groupedEvents.addOutputEventId(event.getEventId()); for (String component : targetComponents) { groupedEvents = unsortedComponentGroupedEvents.get(component); if (groupedEvents == null) { groupedEvents = new ComponentGroupedEvents(component); unsortedComponentGroupedEvents.put(component, groupedEvents); } groupedEvents.addInputEventId(event.getEventId()); } }); componentGroupedEvents = unsortedComponentGroupedEvents.entrySet() .stream() .collect(toMap(Map.Entry::getKey, entry -> new SortedComponentGroupedEvents(allEvents, entry.getValue(), rootEventId))); }
public EventInformation build(long timestamp, String componentName, String streamId, Set<String> targetComponents, StreamlineEvent event) { String sourceComponentName = EventCorrelationInjector.getSourceComponentName(event); if (!componentName.equals(sourceComponentName)) { throw new IllegalStateException("component name in event correlation is different from provided component name"); } return new EventInformation(timestamp, componentName, streamId, targetComponents, event.getId(), EventCorrelationInjector.getRootIds(event), EventCorrelationInjector.getParentIds(event), event); } }
public Map<String, EventInformationTreeNode> constructEventTreeAsMap(String rootEventId) { Stream<EventInformation> eventsAssociatedToRootEventStream = events.stream().filter(e -> { boolean isRootEvent = e.getEventId().equals(rootEventId); boolean containsRootEvent = e.getRootIds() != null && e.getRootIds().contains(rootEventId); return isRootEvent || containsRootEvent; }); Map<String, EventInformationTreeNode> nodes = eventsAssociatedToRootEventStream.collect( toMap(EventInformation::getEventId, EventInformationTreeNode::new)); nodes.forEach((eventId, node) -> { Set<String> parentIds = node.getEventInformation().getParentIds(); parentIds.forEach(parentId -> { EventInformationTreeNode parentNode = nodes.get(parentId); // parent will not be in nodes when parent is originated to another root event // if it's the case, just ignore it if (parentNode != null) { parentNode.addChild(node); } }); }); return nodes; }
private Response getEventsOfTestRunTopologyHistory(Long topologyId, Long historyId, String componentName, SecurityContext securityContext) throws IOException { SecurityUtil.checkRoleOrPermissions(authorizer, securityContext, Roles.ROLE_TOPOLOGY_USER, Topology.NAMESPACE, topologyId, READ); File eventLogFile = getEventLogFile(topologyId, historyId); Stream<EventInformation> eventsStream = eventLogFileReader.loadEventLogFileAsStream(eventLogFile); if (!StringUtils.isEmpty(componentName)) { eventsStream = eventsStream.filter(event -> { String eventComponentName = event.getComponentName(); return eventComponentName != null && eventComponentName.equals(componentName); }); } return WSUtils.respondEntities(eventsStream.collect(toList()), OK); }
@GET @Path("/topologies/{topologyId}/testhistories/{historyId}/events/correlated/{rootEventId}") public Response getGroupedCorrelatedEventsOfTestRunTopologyHistory(@Context UriInfo urlInfo, @PathParam("topologyId") Long topologyId, @PathParam("historyId") Long historyId, @PathParam("rootEventId") String rootEventId, @Context SecurityContext securityContext) throws Exception { SecurityUtil.checkRoleOrPermissions(authorizer, securityContext, Roles.ROLE_TOPOLOGY_USER, Topology.NAMESPACE, topologyId, READ); File eventLogFile = getEventLogFile(topologyId, historyId); List<EventInformation> events = eventLogFileReader.loadEventLogFile(eventLogFile); GroupedCorrelationEvents groupedEvents = new CorrelatedEventsGrouper(events).groupByComponent(rootEventId); if (!groupedEvents.getAllEvents().containsKey(rootEventId)) { throw BadRequestException.message("Can't find provided root event " + rootEventId + " from events."); } return WSUtils.respondEntity(groupedEvents, OK); }
@GET @Path("/topologies/{topologyId}/testhistories/{historyId}/events/tree/{rootEventId}") public Response getEventTreeOfTestRunTopologyHistory(@Context UriInfo urlInfo, @PathParam("topologyId") Long topologyId, @PathParam("historyId") Long historyId, @PathParam("rootEventId") String rootEventId, @Context SecurityContext securityContext) throws Exception { SecurityUtil.checkRoleOrPermissions(authorizer, securityContext, Roles.ROLE_TOPOLOGY_USER, Topology.NAMESPACE, topologyId, READ); File eventLogFile = getEventLogFile(topologyId, historyId); List<EventInformation> events = eventLogFileReader.loadEventLogFile(eventLogFile); EventInformationTreeNode rootEventNode = new EventInformationTreeBuilder(events).constructEventTree(rootEventId); if (rootEventNode == null) { throw BadRequestException.message("Can't find provided root event " + rootEventId + " from events."); } return WSUtils.respondEntity(rootEventNode, OK); }
private void findAndAddParentsIfNecessary(Map<String, EventInformation> allEventsMap, Map<String, EventInformation> relatedEventsMap, Map<String, EventInformation> eventsToAddMap, EventInformation event) { Set<String> parentIds = event.getParentIds(); for (String parentId : parentIds) { if (!relatedEventsMap.containsKey(parentId) && !eventsToAddMap.containsKey(parentId)) { // find and add parent to relatedEventsMap EventInformation parent = allEventsMap.get(parentId); if (parent == null) { throw new RuntimeException("Failed to find parent event: logged event information may be corrupted."); } eventsToAddMap.put(parent.getEventId(), parent); // newly found parent event may have parent event(s) as well... find them as well findAndAddParentsIfNecessary(allEventsMap, relatedEventsMap, eventsToAddMap, parent); } } }
private Map<String, EventInformation> buildRelatedEventsMap(String rootEventId) { Map<String, EventInformation> allEventsMap = events.stream() .collect(toMap(EventInformation::getEventId, e -> e)); Stream<EventInformation> eventsAssociatedToRootEventStream = events.stream().filter(e -> { boolean isRootEvent = e.getEventId().equals(rootEventId); boolean containsRootEvent = e.getRootIds() != null && e.getRootIds().contains(rootEventId); return isRootEvent || containsRootEvent; }); Map<String, EventInformation> relatedEventsMap = eventsAssociatedToRootEventStream.collect( toMap(EventInformation::getEventId, e -> e)); addNonExistingParents(allEventsMap, relatedEventsMap); return relatedEventsMap; }
@GET @Path("/topologies/{topologyId}/testhistories/{historyId}/events/root") public Response getRootEventsOfTestRunTopologyHistory(@Context UriInfo urlInfo, @PathParam("topologyId") Long topologyId, @PathParam("historyId") Long historyId, @Context SecurityContext securityContext) throws Exception { SecurityUtil.checkRoleOrPermissions(authorizer, securityContext, Roles.ROLE_TOPOLOGY_USER, Topology.NAMESPACE, topologyId, READ); File eventLogFile = getEventLogFile(topologyId, historyId); List<EventInformation> events = eventLogFileReader.loadEventLogFile(eventLogFile); List<com.hortonworks.registries.common.QueryParam> qps = com.hortonworks.registries.common.QueryParam.params( TopologySource.TOPOLOGYID, topologyId.toString(), TopologySource.VERSIONID, catalogService.getCurrentVersionId(topologyId).toString()); Set<String> sourceNames = catalogService.listTopologySources(qps).stream() .map(TopologyComponent::getName) .collect(Collectors.toSet()); return WSUtils.respondEntities(new CorrelatedEventsGrouper(events).groupByRelatedSourceEvents(sourceNames), OK); }
public synchronized void writeEvent(long timestamp, String componentName, String streamId, Set<String> targetComponents, StreamlineEvent event) { try (FileWriter fw = new FileWriter(eventLogFilePath, true)) { LOG.debug("writing event to file " + eventLogFilePath); EventInformationBuilder informationBuilder = new EventInformationBuilder(); EventInformation eventInfo = informationBuilder.build(timestamp, componentName, streamId, targetComponents, event); fw.write(objectMapper.writeValueAsString(eventInfo) + "\n"); fw.flush(); } catch (FileNotFoundException e) { LOG.error("Can't open file for write: " + eventLogFilePath); throw new RuntimeException(e); } catch (IOException e) { LOG.error("Fail to write event to output file " + eventLogFilePath + " : exception occurred.", e); throw new RuntimeException(e); } }
/** * Returns the group of correlated events per source where the group of related source events * produces the same downstream events * * @param sources the set of source component names * @return the group of correlated events per source */ public List<Set<String>> groupByRelatedSourceEvents(Set<String> sources) { Multimap<Set<String>, String> allEventsToSourceEvents = LinkedHashMultimap.create(); Stream<String> rootEventIds = events.stream().filter(e -> e != null && e.getRootIds().isEmpty()) .map(EventInformation::getEventId); rootEventIds.forEach(rootEventId -> { Map<String, EventInformation> allRelatedEvents = buildRelatedEventsMap(rootEventId); allEventsToSourceEvents.put(allRelatedEvents.keySet(), rootEventId); }); List<Set<String>> result = new ArrayList<>(); allEventsToSourceEvents.asMap().values().forEach(v -> result.add(new HashSet<>(v)) ); return result; }
private void rearrangeEventIds(Map<String, EventInformation> allEvents, String selectedEventId, List<String> eventIds) { if (eventIds.size() <= 1) { // no need to rearrange return; } List<String> movingIds = new LinkedList<>(); Iterator<String> iter = eventIds.iterator(); while (iter.hasNext()) { String eventId = iter.next(); EventInformation eventInformation = allEvents.get(eventId); if (eventInformation == null) { return; } if (eventId.equals(selectedEventId)) { iter.remove(); // place first among moving ids movingIds.add(0, eventId); } else if (eventInformation.getRootIds().contains(selectedEventId)) { // check if the event contains selected event in root ids // if then place them to just right side of selected event iter.remove(); movingIds.add(eventId); } } eventIds.addAll(0, movingIds); }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof EventInformation)) return false; EventInformation that = (EventInformation) o; if (getTimestamp() != that.getTimestamp()) return false; if (getComponentName() != null ? !getComponentName().equals(that.getComponentName()) : that.getComponentName() != null) return false; if (getStreamId() != null ? !getStreamId().equals(that.getStreamId()) : that.getStreamId() != null) return false; if (getTargetComponents() != null ? !getTargetComponents().equals(that.getTargetComponents()) : that.getTargetComponents() != null) return false; if (getEventId() != null ? !getEventId().equals(that.getEventId()) : that.getEventId() != null) return false; if (getRootIds() != null ? !getRootIds().equals(that.getRootIds()) : that.getRootIds() != null) return false; if (getParentIds() != null ? !getParentIds().equals(that.getParentIds()) : that.getParentIds() != null) return false; return getFieldsAndValues() != null ? getFieldsAndValues().equals(that.getFieldsAndValues()) : that.getFieldsAndValues() == null; }
@GET @Path("/topologies/{topologyId}/testhistories/{historyId}/events/tree/{rootEventId}/subtree/{subRootEventId}") public Response getEventSubTreeOfTestRunTopologyHistory(@Context UriInfo urlInfo, @PathParam("topologyId") Long topologyId, @PathParam("historyId") Long historyId, @PathParam("rootEventId") String rootEventId, @PathParam("subRootEventId") String subRootEventId, @Context SecurityContext securityContext) throws Exception { SecurityUtil.checkRoleOrPermissions(authorizer, securityContext, Roles.ROLE_TOPOLOGY_USER, Topology.NAMESPACE, topologyId, READ); File eventLogFile = getEventLogFile(topologyId, historyId); List<EventInformation> events = eventLogFileReader.loadEventLogFile(eventLogFile); EventInformationTreeNode subRootEventNode = new EventInformationTreeBuilder(events).constructEventTree(rootEventId, subRootEventId); if (subRootEventNode == null) { throw BadRequestException.message("Can't find provided root event " + rootEventId + " from events."); } return WSUtils.respondEntity(subRootEventNode, OK); }