System Architecture
The system has five logical components that communicate exclusively over Java RMI secured by mutual TLS (mTLS). No component accepts unencrypted connections.
Component Diagram
Component Responsibilities
| Component | Class | Port | Responsibility |
|---|---|---|---|
| AuthService | com.dfs.auth.AuthService | 1098 | User registration, login, session token validation, token revocation |
| ReplicaNode 0 | com.dfs.node.ReplicaNode | 1099 | File storage, TO-Multicast participation, Raft election |
| ReplicaNode 1 | com.dfs.node.ReplicaNode | 1100 | File storage, TO-Multicast participation, Raft election |
| ReplicaNode 2 | com.dfs.node.ReplicaNode | 1101 | File storage, TO-Multicast participation, Raft election |
| DFS Client | com.dfs.client.DFSClient + ClientShell | — | Interactive CLI for file operations |
Key Design Decisions
Why 3 Replicas?
Three is the minimal number for majority-based consensus (Raft requires > N/2 votes — with 3 nodes, that's 2 votes). This means the cluster can tolerate one node failure and still elect a leader and serve reads.
Why a Separate AuthService?
Authentication is a distinct concern from file storage. Separating it means:
- The auth service can be secured and scaled independently
- Session tokens are validated by a single source of truth
- Compromising a storage node doesn't give access to the password store
Why mTLS and Not Just TLS?
One-way TLS (where only the server has a certificate) leaves the door open for:
- Man-in-the-middle attacks: an attacker can impersonate a client
- Unauthorized connections: anyone who can reach the port can talk to the server
Mutual TLS requires both sides to present valid certificates signed by the shared Certificate Authority. This means only authorized clients and nodes can establish connections at all.
Why TO-Multicast for Writes?
Simple leader-based replication has a problem: if the leader crashes during a write, the write might be lost or duplicated. TO-Multicast ensures every node independently receives and acknowledges every write before it's committed. There's no single point of failure in the write path.
Next Steps
Continue to Data Flow to see exactly how a write operation travels through the system, step by step.