This is a Spring boot v3.0 repository which attempts to solve Problem 3 as defined in the Pesapal Careers portal.
- Clone this repository
- Ensure you have Java 17 installed on your machine.
- Start your preferred Java supporting IDE e.g. Intellij.
- Open this project with the IDE and allow it to load and prepare the project to build with Gradle.
- Finally run the Gradle bootRun command.
- You can use Postman or cURL to test the end points.
Build a TCP server that can accept and hold a maximum of N clients (where N is configurable). These clients are assigned ranks based on first-come-first-serve, i.e whoever connects first receives the next available high rank. Ranks are from 0–N, 0 being the highest rank.
Clients can send to the server commands that the server distributes among the clients. Only a client with a lower rank can execute a command of a higher rank client. Higher rank clients cannot execute commands by lower rank clients, so these commands are rejected. The command execution can be as simple as the client printing to console that command has been executed.
If a client disconnects the server should re-adjust the ranks and promote any client that needs to be promoted not to leave any gaps in the ranks.
The following describes how i tackled the above problem. Let's start with the Endpoints then code, where i will show you how each of the endpoint functions was built.
The following are the resources available from the base url:
-
Providing a client to the server
For the server to accept the client, provide the client's name with the request /solution/register as a POST request and add json body similar to the one shown below.
curl --location --request POST 'http://localhost:8080/pesa-pal/problem3/api/v1/solution/register' \ --header 'Content-Type: application/json' \ --data-raw '{ "client": "mandela" }'
On success you will get a response with CREATED http status to mean that it was a success otherwise you will get an exception with reason.
However when you try to add an already existing client you will receive a Bad Request error as shown below.
-
List clients on the server
To fetch list of active clients use /solution/clients as a GET request and with a json body as shown below.
curl --location --request GET 'http://localhost:8080/pesa-pal/problem3/api/v1/solution/clients'
On success you will get a response with OK http status and json array body with the to mean that it was a success otherwise you will get an exception with reason.
-
Ping Server
The client is required to ping the server after every 60 seconds with /solution/online as a POST request and with a json body as shown below.
curl --location --request POST 'http://localhost:8080/pesa-pal/problem3/api/v1/solution/online' \ --header 'Content-Type: application/json' \ --data-raw '{"client": "mandela"}'
On success you will get a response with HTTP Status 200 to mean that it was a success otherwise you will get an exception with reason.
However when the target client doesn't exist you will receive a Not Found error as shown below.
-
Execute commands
The client is required to provide a command using /solution/cmd as a POST request and with a json body as shown below.
curl --location --request POST 'http://localhost:8080/pesa-pal/problem3/api/v1/solution/cmd' \ --header 'Content-Type: application/json' \ --data-raw '{ "client": "perez", "cmd": "Hello world" }'
On success you will get a response with HTTP Status 200 to mean that it was a success otherwise you will get an exception with reason.
The following are some of the exceptions that can be thrown:
Project directory structure:
To effectively solve the larger part of the problem, I choose to use the Queue<?> datatype becuse of its elastic ability on the items it holds. Therefore items in the Queue automatically adjusts to the FIFO order.
The following are code snipnnets for important functions in the application:
-
Service Function Class
-
Service Class
-
Scheduler Class
-
Controller Class