Skip to content

Commit c7aaf40

Browse files
authored
Merge pull request #76 from CS3219-AY2425S1/titus/update-readme
docs: update documentation
2 parents 368fa90 + 926427b commit c7aaf40

35 files changed

+613
-27
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,38 @@
99
- You can choose to develop individual microservices within separate folders within this repository **OR** use individual repositories (all public) for each microservice.
1010
- In the latter scenario, you should enable sub-modules on this GitHub classroom repository to manage the development/deployment **AND** add your mentor to the individual repositories as a collaborator.
1111
- The teaching team should be given access to the repositories as we may require viewing the history of the repository in case of any disputes or disagreements.
12+
13+
---
14+
15+
## Architecture Diagram
16+
17+
![Overall Architecture Diagram](./docs/architecture_diagram.png)
18+
19+
The overall architecture of PeerPrep follows a microservices architecture. The client acts as an orchestrator for the interaction between the different services.
20+
21+
## Screenshots
22+
23+
![Home Page](./docs/home_page.png)
24+
25+
![Collaboration Page](./docs/collab_page_1.png)
26+
27+
![Collaboration Page](./docs/collab_page_2.png)
28+
29+
![Question Page](./docs/question_page.png)
30+
31+
![Question Page](./docs/indiv_question_page.png)
32+
33+
![History Page](./docs/submission_history_page.png)
34+
35+
## More details
36+
37+
- [Frontend](./apps/frontend/README.md)
38+
- [User Service](./apps/user-service/README.md)
39+
- [Question Service](./apps/question-service/README.md)
40+
- [Matching Service](./apps/matching-service/README.md)
41+
- [Signalling Service](./apps/signalling-service/README.md)
42+
- [History Service](./apps/history-service/README.md)
43+
- [Execution Service](./apps/execution-service/README.md)
44+
- [CI/CD Guide](./docs/cicid.md)
45+
- [Docker Compose Guide](./apps/README.md)
46+
- [Set Up Guide](./docs/setup.md)

apps/README.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This project uses Docker Compose to manage multiple services such as a frontend, backend, and a database. The configuration is defined in the `docker-compose.yml` file, and environment variables can be stored in environment files for different environments (e.g., development, production).
44

5+
More details on how to set up Docker Compose can be found [here](../docs/setup.md)
6+
57
## Prerequisites
68

79
Before you begin, ensure you have the following installed on your machine:
@@ -30,11 +32,25 @@ In the `./apps` directory:
3032
├── user-service
3133
│ ├── Dockerfile # Dockerfile for user-service
3234
│ └── ... (other user-service files)
33-
35+
├── execution-service
36+
│ ├── Dockerfile # Dockerfile for execution-service
37+
│ └── ... (other execution-service files)
38+
├── signalling-service
39+
│ ├── Dockerfile # Dockerfile for signalling-service
40+
│ └── ... (other signalling-service files)
41+
├── history-service
42+
│ ├── Dockerfile # Dockerfile for history-service
43+
│ └── ... (other history-service files)
3444
```
3545

3646
## Docker Compose Setup
3747

48+
Ensure that you are currently using **Docker Compose v2** in your local Docker Desktop.
49+
- Launch your local Docker Desktop application
50+
- Click on settings button at the top right hand corner (beside the name)
51+
- Under the General tab, scroll down until you see a checkbox that says Use Docker Compose V2, ensure that the box is checked then apply and restart (refer to the image below)
52+
![Docker Compose V2](https://github.com/user-attachments/assets/3b8d47c2-c488-4fc1-804d-418ffebbdd9c)
53+
3854
By using multiple Dockerfiles in Docker Compose, we can manage complex multi-container applications where each service has its own environment and build process.
3955

4056
1. Build and Start the Application
@@ -54,11 +70,15 @@ This will:
5470

5571
Once running, you can access:
5672

57-
- The **frontend** at http://localhost:3000
58-
- The **user service** at http://localhost:3001
59-
- The **question service** at http://localhost:8080 (REST) and http://localhost:50051 (gRPC)
60-
- The **matching service** at http://localhost:8081
61-
- The **redis service** at http://localhost:6379
73+
- The [**frontend**](./frontend/README.md) at http://localhost:3000
74+
- The [**user-service**](./user-service/README.md) at http://localhost:3001
75+
- The [**question-service**](./question-service/README.md) at http://localhost:8080 (REST) and http://localhost:50051 (gRPC)
76+
- The [**matching-service**](./matching-service/README.md) at http://localhost:8081
77+
- The [**history-service**](./history-service/README.md) at http://localhost:8082
78+
- The [**execution-service**](./execution-service/README.md) at http://localhost:8083
79+
- The [**signalling-service**](./signalling-service/README.md) at http://localhost:4444
80+
- The **redis** at http://localhost:6379
81+
- The **rabbitmq** at http://localhost:5672
6282

6383
3. Stopping Services
6484

@@ -76,6 +96,11 @@ This command will stop and remove the containers, networks, and volumes created
7696

7797
- **Port Conflicts**: If you encounter port conflicts, ensure the host ports specified in docker-compose.yml (e.g., 3000:3000) are not in use by other applications.
7898
- **Environment Variables Not Loaded**: Ensure the `.env` files are in the correct directories as found in the `docker-compose.yml` file.
99+
- **Command execution failed**: When you try running test cases or submitting the code in the collaborative environment, if you encounter the following error message:
100+
```bash
101+
Command execution failed: Unable to find image 'apps-python-sandbox:latest' locally docker: Error response from daemon: pull access denied for apps-python-sandbox, repository does not exist or may require 'docker login': denied: requested access to the resource is denied. See 'docker run --help'. : exit status 125
102+
```
103+
Ensure that you have **Docker Compose V2** enabled for your Docker Desktop application. Please refer to the Docker Compose setup guide above to enable it locally.
79104

80105
### Known Issues
81106

apps/execution-service/README.md

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,59 @@
11
# Execution Service
22

3+
The Execution Service provides backend functionality for running and validating code executions or submissions within a coding platform. It enables users to execute code against test cases and receive feedback on the correctness of their solutions.
4+
5+
The Execution Service incorporates a code execution mechanism designed to run user-submitted solutions within an isolated, sandboxed environment. This approach enhances security by preventing arbitrary code from interacting with the host system directly and allows for performance monitoring
6+
7+
### Technology Stack
8+
9+
- Golang (Go): Statically typed, compiled language with low latency. Fast and efficient processing is ideal for high-read, high-write environments like in Execution Service, when many users run tests or submit tests.
10+
- Rest Server: chi router was utilized which supports CORS, logging and timeout via middlewares. It is stateless, which reduces coupling and enhances scalability and reliability, simplicity and flexibility. For example, clients may make requests to different server instances when scaled.
11+
- Firebase Firestore: NoSQL Document database that is designed for automatic horizontal scaling and schema-less design that allows for flexibility as number of tests increases or more users run tests.
12+
- Docker: used to containerize the Execution Service to simplify deployment. Additionally used to provide a sandboxed execution environment for user-submitted code, ensuring security by limiting code access to the host system and managing dependencies independently.
13+
14+
### Execution Process
15+
16+
For execution of user code (running of test cases without submission), only visible (public) and custom test cases are executed.
17+
18+
![Diagram of code execution process](../../docs/exeuction_process.png)
19+
20+
### Submission Process
21+
22+
For submission of user code, both visible (public) and hidden testcases are executed, before calling the history-service API to submit the submission data, code and test results.
23+
24+
![Diagram of code submission process](../../docs/submission_process.png)
25+
26+
### Design Decisions
27+
28+
1. **Docker Containerisation**
29+
a. Upon receiving a code execution request, the service dynamically creates a Docker container with a controlled environment tailored to Python
30+
b. The Docker container is set up with only the minimal permissions and resources needed to execute the code, restricting the execution environment to reduce risk
31+
c. This containerized environment is automatically destroyed after execution, ensuring no residual data or state remains between executions
32+
33+
2. **Security and Isolation**
34+
a. Containers provide isolation from the host system, limiting any interaction between user code and the underlying infrastructure
35+
b. Only essential files and libraries required for code execution are included, reducing potential attack surfaces within each container. The sandboxed, container-based execution system provides a secure and efficient way to run user code submissions.
36+
37+
The sandboxed, container-based execution system provides a secure and efficient way to run user code submissions.
38+
39+
### Communication between Execution and History Service
40+
41+
The communication between the Execution service and the History service is implemented through a RabbitMQ Message Queue. RabbitMQ is ideal for message queues in microservices due to its reliability, flexible routing, and scalability. It ensures messages aren’t lost through durable queues and supports complex routing to handle diverse messaging needs.
42+
43+
Asynchronous communication was chosen as a user’s submission history did not need to be updated immediately. Instead of waiting for a response, the Execution Service can put the message in a queue and continue processing other requests.
44+
45+
![RabbitMQ Message Queue](./../../docs/rabbit_mq_queue.png)
46+
47+
A message queue allows services to communicate without depending on each other's availability. The Execution Service can send a message to the queue, and the History Service can process it when it’s ready. This decoupling promotes loose coupling and reduces dependencies between services, which helps maintain a robust and adaptable system.
48+
49+
---
50+
51+
## Setup
52+
53+
### Prerequisites
54+
55+
Ensure you have Go installed on your machine.
56+
357
### Installation
458

559
1. Install dependencies:
@@ -61,10 +115,10 @@ The server will be available at http://localhost:8083.
61115

62116
## API Endpoints
63117

64-
- `POST /tests/populate`
65-
- `GET /tests/{questionDocRefId}/`
66-
- `POST /tests/{questionDocRefId}/execute`
67-
- `POST /tests/{questionDocRefId}/submit`
118+
- `POST: /tests/populate`: Deletes and repopulates all tests in Firebase
119+
- `GET: /{questionDocRefId}`: Reads the public testcases for the question, identified by the question reference ID
120+
- `POST: /{questionDocRefId}/execute`: Executes the public testcases for the question, identified by the question reference ID
121+
- `POST: /{questionDocRefId}/submit`: Executes the public and hidden testcases for the question, identified by the question reference ID, and submits the code submission to History Service
68122

69123
## Managing Firebase
70124

apps/frontend/README.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
1-
This is the frontend for the question service.
1+
# Frontend
22

3-
## Tech Stack
3+
![Home page](../../docs/home_page.png)
44

5-
- Next.js
6-
- TypeScript
7-
- Ant Design
8-
- SCSS
5+
### Tech Stack
6+
7+
- React: React is one of the most popular UI libraries that allows the creation of reusable UI functional components. Its community ecosystem also offers React hooks that simplify the implementation of some of our frontend components, such as websockets.
8+
- Next.js: A React framework for building single-page applications. It comes with several useful features such as automatic page routing based on filesystem.
9+
- Ant Design: An enterprise-level design system that comes with several extensible UI components and solutions out-of-the-box, which allows us to quickly create nice-looking components that can be adjusted according to our requirements.
10+
- Typescript: A language extension of Javascript that allows us to perform static type-checking, to ensure that issues with incorrectly used types are caught and resolved as early as possible, improving code maintainability.
11+
12+
### Authorization-based Route Protection with Next.js Middleware
13+
14+
Middleware is a Next.js feature that allows the webpage server to intercept page requests and perform checks before serving the webpage. We used this feature to protect page access from unauthenticated users. This was done by checking the request’s JWT token (passed as a cookie) against the user service and redirecting users without authorized access to a public route (namely, the login page).
15+
16+
### User Flow and Communication between Microservices
17+
18+
Clients interact with the microservices through dedicated endpoints, with each microservice managing its own database for independent reading and writing.
19+
20+
Having individual databases per microservice improves data security, scalability, fault isolation, flexibility in database choice, and development efficiency. This approach allows each microservice to operate independently, optimizing stability, performance, and adaptability in the system.
21+
22+
![Diagram for user flow and communication between microservices](../../docs/userflow.png)
23+
24+
---
925

1026
## Getting Started
1127

apps/history-service/README.md

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
1-
# Question Service
1+
# History Service
2+
3+
The History Service is designed to store and retrieve a user’s code submission history. Users can view their past submission records of a collaboration session, with details such as the submitted date, the question attempted on, and the matched username. The information on the submission is stored within the history service’s database, and the data is accessed through querying the history-service from the frontend. It uses Google Firestore as a cloud-based NoSQL database for efficient and scalable data storage and retrieval. It is developed with a RESTful API structure, allowing flexibility for client applications to interact with the service.
4+
5+
### Technology Stack
6+
7+
- Golang (Go): Statically typed, compiled language with low latency. Fast and efficient processing is ideal for high-read, high-write environments like in history service.
8+
- Firebase Firestore: NoSQL Document database that is designed for automatic horizontal scaling and schema-less design that allows for flexibility as application grows and new features are added.
9+
- REST Server: chi router was utilized which supports CORS, logging and timeout via middlewares. It is stateless, which reduces coupling and enhances scalability and reliability, simplicity and flexibility. For example, clients may make requests to different server instances when scaled.
10+
- Docker: used to containerize the History Service to simplify deployment.
11+
12+
### Design Decisions
13+
14+
The submission history is organized with the most recent submission displayed first, making it easy for users to review their past submissions. Pagination is implemented to help users find specific records efficiently and reduce the amount of data transferred when loading the page.
15+
16+
![Screenshot of the submission history page with pagination](../../docs/submission_history_page.png)
17+
18+
On the question page, users can view their past submissions for that question, allowing them to see their submitted code alongside the question details for better context.
19+
20+
![Screenshot of a question’s submission history](../../docs/indiv_question_page.png)
21+
22+
Each submission record is created through the execution service via an asynchronous call, ensuring smooth and efficient processing (more details provided in the next section).
23+
24+
---
225

326
## Overview
427

@@ -90,10 +113,10 @@ The server will be available at http://localhost:8082.
90113

91114
## API Endpoints
92115

93-
- `POST /histories`
94-
- `GET /histories/{docRefId}`
95-
- `PUT /histories/{docRefId}`
96-
- `DELETE /histories/{docRefId}`
116+
- `POST: /histories`: Create a history record of the code submission
117+
- `GET: /histories/{historyDocRefId}`: Reads the history record of the code submission, identified by the history reference ID
118+
- `GET: /histories/user/{username}`: Returns a paginated list of history records by a user, identified by the username
119+
- `GET: /histories/user/{username}/question/{questionDocRefId}`: Returns a paginated list of history records by a user, for a question, identified by the username and question reference ID
97120

98121
```bash
99122
go run main.go

0 commit comments

Comments
 (0)