@@ -64,11 +64,31 @@ Concrete subclasses add command-specific fields, all set via constructor. Reques
### `CommandHandler<T extends Request>`
<img src="../../../images/docs/networking/commands/command_handler.png" alt="Class diagram of the CommandHandler" />
The `CommandHandler` is a single-method interface responsible for executing a typed request.
The `CommandHandler` is an abstract base class responsible for executing a typed request.
The handler contains the domain logic: reading from registries and managers, modifying state, and dispatching a response via the `ResponseDispatcher`.
Handlers receive their dependencies (the `ResponseDispatcher`, registries and managers etc.) through constructor injection.
This keeps them fully testable without the network layer.
Handlers receive their dependencies (the `ResponseDispatcher`, registries and managers etc.) through constructor injection.
They can also register reusable pre-execution checks via `addCheck(...)`. These checks are stored on the handler and are evaluated before `execute(...)` runs.
When a piece of trivial validation is shared by multiple handlers, it should be extracted into a dedicated `HandlerCheck` instead of being duplicated in each handler.
### `HandlerCheck`
<img src="../../../images/docs/networking/commands/handler_check.png" alt="Class diagram of HandlerCheck and CommandHandlerExecutor" />
The `HandlerCheck` is a functional interface for reusable pre-execution validation.
Its `check(...)` method receives the incoming `Request` and returns an empty `Optional` if the request may continue.
If the check fails, it returns an `ErrorResponse` wrapped in the `Optional`, which will be dispatched to the client instead of calling the handler.
This is the right place for small shared checks such as "is the user logged in?" or other simple preconditions that multiple handlers need.
### `CommandHandlerExecutor`
<img src="../../../images/docs/networking/commands/handler_check_executor.png" alt="Class diagram of HandlerCheck and CommandHandlerExecutor" />
The `CommandHandlerExecutor` runs all checks registered on a handler before invoking `execute(...)`.
If any `HandlerCheck` returns a response, the executor dispatches it immediately and aborts execution.
Otherwise, the handler is executed normally.
This keeps precondition handling separate from the actual domain logic inside the handler.
### `CommandRouter`
<img src="../../../images/docs/networking/commands/command_router.png" alt="Class diagram of the CommandRouter" />
This document describes the protocol for client-server communication in our application. It defines the structure of requests and responses, the supported commands along with their request parameters, response formats, and possible errors.
# Table of Contents
- [Protocol Document](#protocol-document)
- [Table of Contents](#table-of-contents)
- [General structure of requests](#general-structure-of-requests)
<!-- Please see the comments for copy ‚ n' paste ready examples -->
# General structure of requests
As mentioned before, our protocol is based on POP3.
Each command is represented as a single line of text, starting with the command name followed by parameters. The server responds with a status line indicating success or failure, followed by the body.
Requests can have parameters that provide additional information for the command. Parameters are key-value pairs separated by an equal sign (`=`).
Responses are collections of key-value pairs, containing either a value or another collection, allowing for nested structures.
Each collection is ended with the `END` keyword.
# Preconditions
The serverside pipeline to process incoming requests consists of multiple stages.
Each of these stages can yield an error response if the request does not meet the requirements of that stage.
## Parsing
One of these stages is the parsing. It is responsible for parsing the raw request into a structured format that can be easily processed by the command handlers. It validates the syntax of the request as well.
| `PARSING_ERROR` | The body of the request contains syntax errors (see message field of response for more details) |
## Command dispatching
After the request has been successfully parsed, the next stage is to dispatch the `PrimitiveRequest` to the appropriate `CommandParser`. This is done by the `CommandDispatcherDispatcher`, which uses the command name to determine which parser to use.
| `UNKNOWN_COMMAND` | The command is unknown to this server. No parser has been defined |
## Command parsing
Once the `PrimitiveRequest` has been dispatched to the appropriate `CommandParser`, the parser is responsible for parsing the parameters of the request and creating a `Request` that can be executed by the responsible `CommandHandler`.
| `USER_NOT_LOGGED_IN` | The user is not logged in |
# Commands
Commands are the core of our protocol, representing the various actions that clients can request from the server. Each command has a unique name and may require specific parameters in addition to pre-execution checks.
The server processes these commands and responds accordingly.
<!--
## Name of the command
Description of the command, what it does, and when it should be used.
### Required pre-execution checks
- [`Check1`](#check1)
### Request Parameters
| Parameter Name | Type | Optional | Description |
The `PING` command is a simple command that can be used to check if the server is responsive.
### Required pre-execution checks
None.
### Request Parameters
No parameters.
### Success Response
No response fields.
### Example Request
```
PING
```
### Example Response
```
+OK
END
```
## CHECK_USERNAME command
The `CHECK_USERNAME` command is used to check if a username is already taken by another user. Additional users can still log in with the same username, but their name will be substituted with a suffix.
### Required pre-execution checks
None.
### Request Parameters
| Parameter Name | Type | Optional | Description |
The `LOGIN` command is used to log in a user with a specified username. If the username is already taken by another user, the server will append a suffix to the username to make it unique.
### Required pre-execution checks
None.
### Request Parameters
| Parameter Name | Type | Optional | Description |
| `NO_USER_ASSOCIATED` | The session has no user associated, logging out is not possible. |
### Example Request
```
LOGOUT
```
### Example Response
```
+OK
END
```
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.