diff --git a/documents/docs/networking/commands/protocol-document.md b/documents/docs/networking/commands/protocol-document.md index a546a97..b08cf7f 100644 --- a/documents/docs/networking/commands/protocol-document.md +++ b/documents/docs/networking/commands/protocol-document.md @@ -43,6 +43,13 @@ This document describes the protocol for client-server communication in our appl - [Error Response](#error-response-5) - [Example Request](#example-request-3) - [Example Response](#example-response-3) + - [LIST\_USERS command](#list_users-command) + - [Required pre-execution checks](#required-pre-execution-checks-4) + - [Request Parameters](#request-parameters-4) + - [Success Response](#success-response-4) + - [Error Response](#error-response-6) + - [Example Request](#example-request-4) + - [Example Response](#example-response-4) @@ -287,3 +294,51 @@ LOGOUT +OK END ``` + +## LIST_USERS command +The `LIST_USERS` command is used to retrieve a list of all currently logged-in users. + +### Required pre-execution checks +None. + +### Request Parameters +No parameters. + +### Success Response +| Field | Type | Description | +| :------ | :----------------- | :--------------------------------------- | +| `USERS` | `Collection` | Collection of all users currently online | + +| Fields of `User` | Type | Description | +| :--------------- | :---------------------------------------------------------------------- | :-------------------------------------------------------------------- | +| `USERNAME` | `String` | Username of the newly created user, can differ from the requested one | +| `ID` | [`UUID`](https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html) | The ID of the created user | + + +### Error Response +None. + +### Example Request +``` +LIST_USERS +``` + +### Example Response +``` ++OK + USERS + USER + USERNAME=Lars_001 + ID=56765d0f-8cd3-4eec-91b2-7e36265c1a5d + END + USER + USERNAME=Lars_002 + ID=b7bbd9b3-0d49-4c92-8306-b1c8506d2ff0 + END + USER + USERNAME=Lars + ID=982bc78e-547f-495a-a821-433a3603f92c + END + END +END +``` \ No newline at end of file diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index a635785..e20ed3e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -9,6 +9,9 @@ import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_message_count.Get import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageHandler; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageParser; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.get_next_message.GetNextMessageRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users.ListUsersHandler; +import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users.ListUsersParser; +import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users.ListUsersRequest; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginHandler; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginParser; import ch.unibas.dmi.dbis.cs108.casono.server.app.commands.login.LoginRequest; @@ -115,6 +118,7 @@ public class ServerApp { parserDispatcher.register("LOGOUT", new LogoutParser()); commandRouter.register( LogoutRequest.class, new LogoutHandler(responseDispatcher, userRegistry)); + parserDispatcher.register("SEND_MESSAGE", new SendMessageParser()); commandRouter.register( SendMessageRequest.class, new SendMessageHandler(responseDispatcher, userRegistry)); @@ -128,5 +132,9 @@ public class ServerApp { commandRouter.register( GetNextMessageRequest.class, new GetNextMessageHandler(responseDispatcher, userRegistry)); + + parserDispatcher.register("LIST_USERS", new ListUsersParser()); + commandRouter.register( + ListUsersRequest.class, new ListUsersHandler(responseDispatcher, userRegistry)); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersHandler.java new file mode 100644 index 0000000..2ad7fe2 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersHandler.java @@ -0,0 +1,40 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users; + +import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.User; +import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandHandler; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher.ResponseDispatcher; +import java.util.Collection; + +/** + * Handles {@link ListUsersRequest}s by retrieving all users from the {@link UserRegistry} and + * dispatching a {@link ListUsersResponse} containing the list of users. + */ +public class ListUsersHandler extends CommandHandler { + private final UserRegistry userRegistry; + + /** + * Creates a new handler for listing all users + * + * @param responseDispatcher the dispatcher used to send the response + * @param userRegistry the registry used to look up existing users + */ + public ListUsersHandler(ResponseDispatcher responseDispatcher, UserRegistry userRegistry) { + super(responseDispatcher); + this.userRegistry = userRegistry; + } + + /** + * Executes the list users request + * + *

All users are retrieved from the {@link UserRegistry} and returned in a {@link + * ListUsersResponse}. + * + * @param request the request to execute + */ + @Override + public void execute(ListUsersRequest request) { + Collection users = userRegistry.getAllUsers(); + responseDispatcher.dispatch(new ListUsersResponse(request.getContext(), users)); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersParser.java new file mode 100644 index 0000000..f55149e --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersParser.java @@ -0,0 +1,18 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; + +/** Parses a primitive request into a {@link ListUsersRequest}. */ +public class ListUsersParser implements CommandParser { + /** + * Parses a primitive request into a ListUsersRequest. + * + * @param primitiveRequest the request to parse + * @return the created {@link ListUsersRequest} + */ + @Override + public ListUsersRequest parse(PrimitiveRequest primitiveRequest) { + return new ListUsersRequest(primitiveRequest.context()); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersRequest.java new file mode 100644 index 0000000..9ed8fdd --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersRequest.java @@ -0,0 +1,17 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; + +/** Request implementation used to retrieve all existing users from the server. */ +public class ListUsersRequest extends Request { + /** + * Constructs a new ListUsersRequest with the given context + * + * @param context the {@link RequestContext} containing information for responding to the + * request + */ + public ListUsersRequest(RequestContext context) { + super(context); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersResponse.java new file mode 100644 index 0000000..4e48aaf --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/app/commands/list_users/ListUsersResponse.java @@ -0,0 +1,35 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.app.commands.list_users; + +import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.User; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.SuccessResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody; +import java.util.Collection; + +/** Response containing a list of all active users on the server */ +public class ListUsersResponse extends SuccessResponse { + /** + * Creates a new ListUsersResponse containing the given list of users + * + * @param context the {@link RequestContext} associated with the request + * @param users the collection of users currently active on the server + */ + public ListUsersResponse(RequestContext context, Collection users) { + super( + context, + ResponseBody.builder() + .block( + "USERS", + users_block -> { + for (User user : users) { + users_block.block( + "USER", + user_block -> { + user_block.param("USERNAME", user.getName()); + user_block.param("ID", user.getId().value()); + }); + } + }) + .build()); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java index f0f8b97..4e82e3a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java @@ -52,5 +52,5 @@ public abstract class CommandHandler { * * @param request the request to execute, of type T */ - public void execute(T request) {} + public abstract void execute(T request); }