Newer
Older
cactus / src / main / java / com / cube / cluster / ClusterNode.java
@agalyaramadoss agalyaramadoss on 16 Feb 3 KB version update with 21
package com.cube.cluster;

import java.time.Instant;
import java.util.Objects;

/**
 * Represents a node in the Cube database cluster.
 */
public class ClusterNode {
    
    private final String nodeId;
    private final String host;
    private final int port;
    private final String datacenter;
    private final String rack;
    
    private volatile NodeState state;
    private volatile Instant lastHeartbeat;
    private volatile long version; // For gossip protocol
    
    public enum NodeState {
        ALIVE,      // Node is responding
        SUSPECTED,  // Node may be down
        DEAD,       // Node is confirmed down
        LEAVING,    // Node is leaving cluster
        JOINING     // Node is joining cluster
    }
    
    public ClusterNode(String nodeId, String host, int port) {
        this(nodeId, host, port, "dc1", "rack1");
    }
    
    public ClusterNode(String nodeId, String host, int port, String datacenter, String rack) {
        this.nodeId = nodeId;
        this.host = host;
        this.port = port;
        this.datacenter = datacenter;
        this.rack = rack;
        this.state = NodeState.ALIVE;
        this.lastHeartbeat = Instant.now();
        this.version = 0;
    }
    
    public String getNodeId() {
        return nodeId;
    }
    
    public String getHost() {
        return host;
    }
    
    public int getPort() {
        return port;
    }
    
    public String getDatacenter() {
        return datacenter;
    }
    
    public String getRack() {
        return rack;
    }
    
    public NodeState getState() {
        return state;
    }
    
    public void setState(NodeState state) {
        this.state = state;
    }
    
    public Instant getLastHeartbeat() {
        return lastHeartbeat;
    }
    
    public void updateHeartbeat() {
        this.lastHeartbeat = Instant.now();
        this.state = NodeState.ALIVE;
    }
    
    public long getVersion() {
        return version;
    }
    
    public void incrementVersion() {
        this.version++;
    }
    
    /**
     * Get the endpoint address (host:port)
     */
    public String getEndpoint() {
        return host + ":" + port;
    }
    
    /**
     * Check if node is alive
     */
    public boolean isAlive() {
        return state == NodeState.ALIVE;
    }
    
    /**
     * Check if node is in same datacenter
     */
    public boolean isInSameDatacenter(ClusterNode other) {
        return this.datacenter.equals(other.datacenter);
    }
    
    /**
     * Check if node is in same rack
     */
    public boolean isInSameRack(ClusterNode other) {
        return this.rack.equals(other.rack);
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ClusterNode that = (ClusterNode) o;
        return Objects.equals(nodeId, that.nodeId);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(nodeId);
    }
    
    @Override
    public String toString() {
        return "ClusterNode{" +
               "nodeId='" + nodeId + '\'' +
               ", endpoint=" + getEndpoint() +
               ", state=" + state +
               ", dc=" + datacenter +
               ", rack=" + rack +
               '}';
    }
}