com.chutneytesting.agent.domain.explore.ExploreAgentsService Maven / Gradle / Ivy
The newest version!
/*
* SPDX-FileCopyrightText: 2017-2024 Enedis
*
* SPDX-License-Identifier: Apache-2.0
*
*/
package com.chutneytesting.agent.domain.explore;
import static com.chutneytesting.agent.domain.explore.ImmutableExploreResult.Links.of;
import com.chutneytesting.agent.domain.AgentClient;
import com.chutneytesting.agent.domain.TargetId;
import com.chutneytesting.agent.domain.configure.ConfigurationState;
import com.chutneytesting.agent.domain.configure.Explorations;
import com.chutneytesting.agent.domain.configure.LocalServerIdentifier;
import com.chutneytesting.agent.domain.configure.NetworkConfiguration;
import com.chutneytesting.agent.domain.explore.ExploreResult.Links;
import com.chutneytesting.agent.domain.explore.ImmutableExploreResult.Link;
import com.chutneytesting.agent.domain.network.NetworkDescription;
import com.chutneytesting.engine.domain.delegation.ConnectionChecker;
import com.chutneytesting.engine.domain.delegation.NamedHostAndPort;
import com.chutneytesting.environment.api.target.dto.TargetDto;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Service to explore agents from the current one, given a {@link NetworkConfiguration}.
* Exploration performs two things :
*
* - propagate a {@link NetworkConfiguration} recursively to all reachable agents
* - aggregate discovered agentLinks between agents
*
*/
public class ExploreAgentsService {
private static final Logger LOGGER = LoggerFactory.getLogger(ExploreAgentsService.class);
private final Explorations explorations;
private final AgentClient agentClient;
private final ConnectionChecker connectionChecker;
private final LocalServerIdentifier localServerIdentifier;
public ExploreAgentsService(Explorations explorations,
AgentClient agentClient,
ConnectionChecker connectionChecker,
LocalServerIdentifier localServerIdentifier) {
this.explorations = explorations;
this.agentClient = agentClient;
this.connectionChecker = connectionChecker;
this.localServerIdentifier = localServerIdentifier;
}
/**
* Propagate given {@link NetworkConfiguration} recursively to all reachable agents.
*
* @return agentLinks & targetLinks discovered during propagation of the given {@link NetworkConfiguration} among agents
*/
public ExploreResult explore(NetworkConfiguration networkConfiguration) {
if (explorations.changeStateToIfPossible(networkConfiguration, ConfigurationState.EXPLORING)) {
return exploreAndMerge(networkConfiguration);
} else {
LOGGER.debug("Received already applied configure");
return ExploreResult.EMPTY;
}
}
/**
* Propagate final {@link NetworkDescription} recursively to all reachable agents.
*/
public void wrapUp(NetworkDescription networkDescription) {
if (explorations.changeStateToIfPossible(networkDescription.configuration(), ConfigurationState.WRAPING_UP)) {
dispatch(networkDescription);
explorations.changeStateToIfPossible(networkDescription.configuration(), ConfigurationState.FINISHED);
} else {
LOGGER.debug("Received already applied description");
}
}
private ExploreResult exploreAndMerge(NetworkConfiguration networkConfiguration) {
String localName = localServerIdentifier.getLocalName(networkConfiguration);
Set exploreResults = exploreToRemoteAgentsAndTargets(localName, networkConfiguration);
Links agentLinks = aggregateLinks(exploreResults, ExploreResult::agentLinks);
Links targetLinks = aggregateLinks(exploreResults, ExploreResult::targetLinks);
return ImmutableExploreResult.of(agentLinks, targetLinks);
}
private ExploreResult detectAvailableTargets(String localName, NetworkConfiguration networkConfiguration) {
Set> targetLinks = networkConfiguration.environmentConfiguration().stream()
.flatMap(e -> e.targets.stream()
.map(t -> Pair.of(e.name, t))
.filter(p -> {
try {
NamedHostAndPort namedHostAndPort = namedHostAndPortFromTarget(p.getRight());
return connectionChecker.canConnectTo(namedHostAndPort);
} catch (UndefinedPortException ex) {
LOGGER.warn(ex.getMessage());
return false;
}
})
.map(p -> TargetId.of(p.getRight().name, p.getLeft()))
.map(targetIdentifier -> Link.of(AgentId.of(localName), targetIdentifier))
).collect(Collectors.toSet());
return ImmutableExploreResult.of(Links.empty(), ImmutableExploreResult.Links.of(targetLinks));
}
private Set exploreToRemoteAgentsAndTargets(String localName, NetworkConfiguration networkConfiguration) {
Set remoteExplorationResults = networkConfiguration.agentNetworkConfiguration().stream()
.filter(agentInfo -> !localName.equals(agentInfo.name()))
.map(agentInfo -> agentClient.explore(localName, agentInfo, networkConfiguration))
.collect(Collectors.toSet());
ExploreResult localTargetsExplorationResult = detectAvailableTargets(localName, networkConfiguration);
return ImmutableSet.builder().addAll(remoteExplorationResults).add(localTargetsExplorationResult).build();
}
private Links aggregateLinks(Set exploreResults, Function> linksExtractor) {
return of(exploreResults.stream()
.map(linksExtractor)
.flatMap(Links::stream)
.collect(Collectors.toSet()));
}
private void dispatch(NetworkDescription networkDescription) {
String localName = localServerIdentifier.getLocalName(networkDescription.configuration());
networkDescription.configuration().agentNetworkConfiguration().stream()
.filter(agentInfo -> !localName.equals(agentInfo.name()))
.forEach(agentInfo -> agentClient.wrapUp(agentInfo, networkDescription));
}
private NamedHostAndPort namedHostAndPortFromTarget(TargetDto target) {
UrlSlicer urlSlicer = new UrlSlicer(target.url);
return new NamedHostAndPort(target.name, urlSlicer.host, urlSlicer.port);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy