de.mklinger.qetcher.client.impl.lookup.NodesHolder Maven / Gradle / Ivy
package de.mklinger.qetcher.client.impl.lookup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.mklinger.qetcher.client.model.v1.AvailableNode;
import de.mklinger.qetcher.client.model.v1.NodeLifecycle;
/**
* @author Marc Klinger - mklinger[at]mklinger[dot]de
*/
public class NodesHolder {
private static final Logger LOG = LoggerFactory.getLogger(NodesHolder.class);
private final AtomicReference> fullyFunctionalNodes;
private final AtomicReference> otherNodes;
public NodesHolder() {
this.fullyFunctionalNodes = new AtomicReference<>(Collections.emptyList());
this.otherNodes = new AtomicReference<>(Collections.emptyList());
}
public void setNodes(final List availableNodes) {
this.fullyFunctionalNodes.set(availableNodes.stream()
.filter(this::isFullyFunctionalNode)
.collect(Collectors.toList()));
this.otherNodes.set(availableNodes.stream()
.filter(this::isOtherNode)
.collect(Collectors.toList()));
}
private boolean isFullyFunctionalNode(final AvailableNode node) {
return node.getNodeLifecycle() == NodeLifecycle.FULLY_FUNCTIONAL;
}
private boolean isOtherNode(final AvailableNode node) {
return !isFullyFunctionalNode(node);
}
public List getNodes() {
final List currentFullyFunctionalNodes = fullyFunctionalNodes.get();
final List currentOtherNodes = otherNodes.get();
final List availableNodes = new ArrayList<>(currentFullyFunctionalNodes.size() + currentOtherNodes.size());
availableNodes.addAll(currentFullyFunctionalNodes);
availableNodes.addAll(currentOtherNodes);
return availableNodes;
}
public Optional getRandomNode() {
final List currentFullyFunctionalNodes = fullyFunctionalNodes.get();
final List currentOtherNodes = otherNodes.get();
Optional node = getRandomNode(currentFullyFunctionalNodes);
if (!node.isPresent()) {
node = getRandomNode(currentOtherNodes);
}
if (LOG.isDebugEnabled() && node.isPresent()) {
LOG.debug("Choosing node {} at {} ({})",
node.get().getNodeName(),
node.get().getAddress().toUriString(),
node.get().getNodeLifecycle());
}
return node;
}
private Optional getRandomNode(final List nodes) {
if (nodes.isEmpty()) {
return Optional.empty();
}
final int randomIdx = ThreadLocalRandom.current()
.nextInt(nodes.size());
return Optional.of(nodes.get(randomIdx));
}
}