Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.fortitudetec.elucidation.server.service;
/*-
* #%L
* Elucidation Server
* %%
* Copyright (C) 2018 - 2020 Fortitude Technologies, LLC
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
*/
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Objects.isNull;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
import com.fortitudetec.elucidation.common.definition.CommunicationDefinition;
import com.fortitudetec.elucidation.common.model.ConnectionEvent;
import com.fortitudetec.elucidation.common.model.Direction;
import com.fortitudetec.elucidation.common.model.RelationshipDetails;
import com.fortitudetec.elucidation.server.core.ConnectionSummary;
import com.fortitudetec.elucidation.server.core.DependencyRelationshipDetails;
import com.fortitudetec.elucidation.server.core.ServiceConnections;
import com.fortitudetec.elucidation.server.core.ServiceDependencies;
import com.fortitudetec.elucidation.server.core.ServiceDetails;
import com.fortitudetec.elucidation.server.core.ServiceDependencyDetails;
import com.fortitudetec.elucidation.server.db.ConnectionEventDao;
import com.google.common.collect.ImmutableList;
import org.apache.commons.collections4.map.HashedMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
public class RelationshipService {
private final ConnectionEventDao dao;
private final Map communicationDefinitions;
public RelationshipService(ConnectionEventDao dao, Map communicationDefinitions) {
this.dao = dao;
this.communicationDefinitions = communicationDefinitions;
}
public void createEvent(ConnectionEvent event) {
dao.createOrUpdate(event);
}
public List listEventsSince(long sinceInMillis) {
return dao.findEventsSince(sinceInMillis);
}
public List listEventsForService(String serviceName) {
return dao.findEventsByServiceName(serviceName);
}
public List currentServiceNames() {
return dao.findAllServiceNames();
}
public List currentServiceDetails() {
var serviceNames = currentServiceNames();
return serviceNames.stream()
.map(this::buildDetails)
.collect(toList());
}
private ServiceDetails buildDetails(String serviceName) {
var events = dao.findEventsByServiceName(serviceName);
var eventsByDirectionCounts = events.stream().collect(groupingBy(ConnectionEvent::getEventDirection));
var eventsByCommunicationType = events.stream().collect(groupingBy(ConnectionEvent::getCommunicationType));
var eventsByCommunicationTypeCounts = eventsByCommunicationType.entrySet().stream()
.collect(toMap(
Map.Entry::getKey,
entry-> entry.getValue().size()
));
return ServiceDetails.builder()
.serviceName(serviceName)
.inboundEvents(eventsByDirectionCounts.getOrDefault(Direction.INBOUND, newArrayList()).size())
.outboundEvents(eventsByDirectionCounts.getOrDefault(Direction.OUTBOUND, newArrayList()).size())
.communicationTypes(eventsByCommunicationTypeCounts)
.build();
}
public List buildAllDependencies() {
return dao.findAllServiceNames().stream()
.distinct()
.map(this::findDependencies)
.collect(toList());
}
public List buildAllDependenciesWithDetails() {
var servicesWithDependencies = buildAllDependencies();
return servicesWithDependencies.stream()
.map(this::expandDetails)
.collect(toList());
}
private ServiceDependencyDetails expandDetails(ServiceDependencies service) {
var serviceName = service.getServiceName();
var depsWithDetails = service.getDependencies().stream()
.map(dep -> detailsForDependency(serviceName, dep))
.collect(toList());
return ServiceDependencyDetails.builder()
.serviceName(serviceName)
.dependencies(depsWithDetails)
.build();
}
private DependencyRelationshipDetails detailsForDependency(String fromService, String toService) {
return DependencyRelationshipDetails.builder()
.serviceName(toService)
.details(findRelationshipDetails(fromService, toService))
.build();
}
private ServiceDependencies findDependencies(String serviceName) {
List dependentEvents = dao.findEventsByServiceName(serviceName).stream()
.filter(this::isDependentEvent)
.collect(toList());
return ServiceDependencies.builder()
.serviceName(serviceName)
.dependencies(populateOppositeConnections(dependentEvents))
.build();
}
private boolean isDependentEvent(ConnectionEvent event) {
var communicationType = event.getCommunicationType();
var communicationDefinition = communicationDefinitions.get(communicationType);
return communicationDefinition.isDependentEvent(event);
}
public ServiceConnections buildRelationships(String serviceName) {
List events = dao.findEventsByServiceName(serviceName);
Map> eventsByDirection = events.stream()
.collect(groupingBy(ConnectionEvent::getEventDirection));
Set inboundConnections = populateOppositeConnections(eventsByDirection.get(Direction.INBOUND));
Set outboundConnections = populateOppositeConnections(eventsByDirection.get(Direction.OUTBOUND));
Map inboundSummaries = inboundConnections.stream()
.map(connectedServiceName -> ConnectionSummary.builder()
.serviceName(connectedServiceName)
.hasInbound(true)
.build())
.collect(toMap(ConnectionSummary::getServiceName, Function.identity()));
Map outboundSummaries = outboundConnections.stream()
.map(connectedServiceName -> ConnectionSummary.builder()
.serviceName(connectedServiceName)
.hasOutbound(true)
.build())
.collect(toMap(ConnectionSummary::getServiceName, Function.identity()));
Map summaries = new HashedMap<>(inboundSummaries);
outboundSummaries.forEach(
(key, value) -> summaries.merge(key, value,
(v1, v2) -> ConnectionSummary.builder().serviceName(v1.getServiceName()).hasOutbound(true).hasInbound(true).build()));
return ServiceConnections.builder()
.serviceName(serviceName)
.children(newHashSet(summaries.values()))
.build();
}
public List findRelationshipDetails(String fromService, String toService) {
List events = dao.findEventsByServiceName(fromService);
return events.stream()
.map(this::findAssociatedEventsOrUnknown)
.flatMap(List::stream)
.filter(event -> event.getServiceName().equalsIgnoreCase(toService))
.map(event -> RelationshipDetails.builder()
.communicationType(event.getCommunicationType())
.connectionIdentifier(event.getConnectionIdentifier())
.eventDirection(event.getEventDirection().opposite())
.lastObserved(event.getObservedAt())
.build())
.collect(toList());
}
private Set populateOppositeConnections(List events) {
if (isNull(events)) {
return newHashSet();
}
return events.stream()
.map(this::findAssociatedEventsOrUnknown)
.flatMap(List::stream)
.map(ConnectionEvent::getServiceName)
.collect(toSet());
}
private List findAssociatedEventsOrUnknown(ConnectionEvent event) {
List associatedEvents = dao.findAssociatedEvents(
event.getEventDirection().opposite(),
event.getConnectionIdentifier(),
event.getCommunicationType());
return associatedEventsOrUnknown(event, associatedEvents);
}
private static List associatedEventsOrUnknown(ConnectionEvent event,
List associatedEvents) {
if (associatedEvents.isEmpty()) {
ConnectionEvent syntheticEvent = syntheticConnectionEvent(event);
return ImmutableList.of(syntheticEvent);
}
return associatedEvents;
}
private static ConnectionEvent syntheticConnectionEvent(ConnectionEvent event) {
return ConnectionEvent.builder()
.serviceName(ConnectionEvent.UNKNOWN_SERVICE)
.eventDirection(event.getEventDirection().opposite())
.communicationType(event.getCommunicationType())
.connectionIdentifier(event.getConnectionIdentifier())
.observedAt(event.getObservedAt())
.build();
}
public List findAllEventsByConnectionIdentifier(String connectionIdentifier) {
return dao.findEventsByConnectionIdentifier(connectionIdentifier);
}
}