/** * Factory method to build a node connectivity * @param endpoint node name * @param connectivity connectivity matrix * @return NodeConnectivity */ public static NodeConnectivity connectivity(String endpoint, ImmutableMap<String, ConnectionStatus> connectivity) { return NodeConnectivity.builder() .endpoint(endpoint) .type(NodeConnectivityType.CONNECTED) .connectivity(connectivity) .build(); }
private boolean isLocalNode(NodeConnectivity node) { return node.getEndpoint().equals(localNode); }
/** * Provide default metric. * @param layout current layout * @return default value */ private FailureDetectorMetrics getDefaultFailureDetectorMetric(Layout layout) { return FailureDetectorMetrics.builder() .localNode(getLocalEndpoint()) .layout(layout.getLayoutServers()) .unresponsiveNodes(layout.getUnresponsiveServers()) .epoch(layout.getEpoch()) .build(); }
@Test public void testDecisionMaker() { NodeConnectivity a = connectivity("a", ImmutableMap.of("a", OK, "b", OK, "c", OK)); NodeConnectivity b = connectivity("b", ImmutableMap.of("a", FAILED, "b", OK, "c", OK)); NodeConnectivity c = connectivity("c", ImmutableMap.of("a", OK, "b", FAILED, "c", OK)); ClusterGraph graph = cluster("a", a, b, c); Optional<NodeRank> decisionMaker = graph.toSymmetric().getDecisionMaker(); assertTrue(decisionMaker.isPresent()); assertEquals(decisionMaker.get(), new NodeRank("a", 2)); }
private NavigableSet<NodeRank> getNodeRanks() { NavigableSet<NodeRank> nodes = new TreeSet<>(); graph.keySet().forEach(node -> { int numConnected = graph.get(node).getConnected(); nodes.add(new NodeRank(node, numConnected)); }); return nodes; }
public static NodeState getUnavailableNodeState(String endpoint){ return new NodeState( NodeConnectivity.unavailable(endpoint), new HeartbeatTimestamp(Layout.INVALID_EPOCH, INVALID_HEARTBEAT_COUNTER), SequencerMetrics.UNKNOWN ); }
public NodeConnectivity(ByteBuf buf) { endpoint = ICorfuPayload.fromBuffer(buf, String.class); type = NodeConnectivityType.valueOf(ICorfuPayload.fromBuffer(buf, String.class)); Map<String, ConnectionStatus> connectivityMap = new HashMap<>(); ICorfuPayload .mapFromBuffer(buf, String.class, String.class) //transform map of strings to map of ConnectionStatus-es .forEach((node, status) -> connectivityMap.put(node, ConnectionStatus.valueOf(status))); connectivity = ImmutableMap.copyOf(connectivityMap); }
@Override public void doSerialize(ByteBuf buf) { ICorfuPayload.serialize(buf, endpoint); ICorfuPayload.serialize(buf, type.name()); Map<String, String> connectivityStrings = new HashMap<>(); connectivity.forEach((node, state) -> connectivityStrings.put(node, state.name())); ICorfuPayload.serialize(buf, connectivityStrings); }
/** * See if cluster is ready. If cluster contains at least one node with state NOT_READY the cluster is not ready and * cluster state can't be used to find failures. * @return cluster status */ public boolean isReady(){ if (nodes.isEmpty()){ return false; } //if at least one node is not ready then entire cluster is not ready to provide correct information for (NodeState nodeState : nodes.values()) { if (nodeState.getConnectivity().getType() == NodeConnectivityType.NOT_READY){ return false; } } return true; } }
/** * Transform ClusterGraph to Connectivity graph * * @return connectivity graph */ public ConnectivityGraph connectivityGraph() { return new ConnectivityGraph(new TreeSet<>(graph.values())); }
public static NodeState getNotReadyNodeState(String endpoint, long epoch, long counter){ return new NodeState( NodeConnectivity.notReady(endpoint), //Layout.INVALID_EPOCH, INVALID_HEARTBEAT_COUNTER - default values for heartbeat new HeartbeatTimestamp(epoch, counter), SequencerMetrics.UNKNOWN ); }
public FailureDetectorMetrics(ByteBuf buf) { localNode = ICorfuPayload.fromBuffer(buf, String.class); graph = ICorfuPayload.fromBuffer(buf, ConnectivityGraph.class); action = FailureDetectorAction.valueOf(ICorfuPayload.fromBuffer(buf, String.class)); failed = ICorfuPayload.fromBuffer(buf, NodeRank.class); healed = ICorfuPayload.fromBuffer(buf, NodeRank.class); layout = ICorfuPayload.listFromBuffer(buf, String.class); unresponsiveNodes = ICorfuPayload.listFromBuffer(buf, String.class); epoch = ICorfuPayload.fromBuffer(buf, Long.class); }
@Override public void doSerialize(ByteBuf buf) { ICorfuPayload.serialize(buf, localNode); ICorfuPayload.serialize(buf, graph); ICorfuPayload.serialize(buf, action.name()); ICorfuPayload.serialize(buf, failed == null ? NodeRank.EMPTY_NODE_RANK: failed); ICorfuPayload.serialize(buf, healed == null ? NodeRank.EMPTY_NODE_RANK: healed); ICorfuPayload.serialize(buf, layout); ICorfuPayload.serialize(buf, unresponsiveNodes); ICorfuPayload.serialize(buf, epoch); }
/** * Builds a new connectivity with unavailable state * @param endpoint node name * @return NodeConnectivity */ public static NodeConnectivity unavailable(String endpoint) { return NodeConnectivity.builder() .endpoint(endpoint) .type(NodeConnectivityType.UNAVAILABLE) .connectivity(ImmutableMap.of()) .build(); }
@Test public void testFailedNode() { NodeConnectivity a = connectivity("a", ImmutableMap.of("a", OK, "b", OK, "c", OK)); NodeConnectivity b = connectivity("b", ImmutableMap.of("a", FAILED, "b", OK, "c", OK)); NodeConnectivity c = connectivity("c", ImmutableMap.of("a", OK, "b", FAILED, "c", OK)); ClusterGraph graph = cluster("a", a, b, c); Optional<NodeRank> failedNode = graph.toSymmetric().findFailedNode(); assertTrue(failedNode.isPresent()); assertEquals(failedNode.get(), new NodeRank("b", 1)); }
private NodeState unavailableNodeState(String endpoint) { return new NodeState( unavailable(endpoint), new HeartbeatTimestamp(Layout.INVALID_EPOCH, 0), SequencerMetrics.UNKNOWN ); } }
/** * Builds a new connectivity with NOT_READY state * @param endpoint node name * @return NodeConnectivity */ public static NodeConnectivity notReady(String endpoint) { return NodeConnectivity.builder() .endpoint(endpoint) .type(NodeConnectivityType.NOT_READY) .connectivity(ImmutableMap.of()) .build(); }
private NodeState unavailable(String endpoint) { NodeConnectivity connectivity = NodeConnectivity.builder() .endpoint(endpoint) .type(NodeConnectivityType.UNAVAILABLE) .connectivity(ImmutableMap.of()) .build(); return new NodeState( connectivity, new HeartbeatTimestamp(Layout.INVALID_EPOCH, 0), SequencerMetrics.UNKNOWN ); } }
private NodeState nodeState(String endpoint, ConnectionStatus... connectionStates) { Map<String, ConnectionStatus> connectivity = new HashMap<>(); for (int i = 0; i < connectionStates.length; i++) { connectivity.put(NODE_NAMES.get(i), connectionStates[i]); } NodeConnectivity nodeConnectivity = NodeConnectivity.builder() .endpoint(endpoint) .type(NodeConnectivityType.CONNECTED) .connectivity(ImmutableMap.copyOf(connectivity)) .build(); return NodeState.builder() .sequencerMetrics(SequencerMetrics.READY) .heartbeat(new HeartbeatTimestamp(0, 0)) .connectivity(nodeConnectivity) .build(); }