Skip to content

Commit 48cab0e

Browse files
committed
readme update
1 parent 5bb8e4e commit 48cab0e

11 files changed

Lines changed: 172 additions & 92 deletions

File tree

Daily Journal.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,4 +376,18 @@ Another crash cause since the kafka version of 2.8 was too old, need to use more
376376

377377
Still debugging issues with deployment to localstack. Trying to use awslocal instead of aws since the latter works better for localstack
378378

379-
Okay now it is working not sure why. The endpoint has been created. Testing it right now.
379+
Okay now it is working not sure why. The endpoint has been created. Testing it right now.
380+
381+
### 20th May 2026 -
382+
383+
Still debugging. Mistakenly used the wrong number of broker nodes compared to the number of availability zone. The number should be such that they are multiples of each other.
384+
385+
Another issue encountered was the adding spaces when combining id with string. In one case the taskDefinition takes the .addContainer method and adds the imageName to the " Container" with a space included. That space should not exist. Another error - the environment variable that pointed to the auth service container did not have the preceding "http://".
386+
387+
### 21st May 2026 -
388+
389+
That fix did not work either. ChatGPT suggested changing the url yml file in the api-gateway from host.docker.internal to the container names instead. Since the latter poses issues due to NAT
390+
391+
### 22nd May 2026 -
392+
393+
lots of debugging required now

README.md

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,67 @@
1-
Following this [tutorial](https://www.youtube.com/watch?v=tseqdcFfTUY&list=PLwnoReiC-egEJ-cpIExHV73LZm1yiRN2O&index=3) to deepen my understanding on SpringBoot.
1+
# Patient Management System
2+
3+
A tool for administrators to manage the patients stored in their Database. SpringBoot is used for the backend, Kafka for real-time messaging and consumption between services, gRPC is used for real-time communication between services, AWS for cloud deployment, and Docker for containerization. This project was done to deepen my understanding of SpringBoot and served as an introduction to microservices architecture.
4+
5+
## Technologies
6+
7+
- SpringBoot
8+
- Docker
9+
- Kafka
10+
- gRPC
11+
- AWS
12+
- REST Assured
13+
14+
## Features
15+
16+
The administrator can log in and modify the patient database in three ways: add, update, and delete patients. Each time a new patient is added, the billing service creates a billing account for that patient and Kafka sends a patient created event to the analytics service to observe changes in the system. All services were containerized using Docker and tested on the internal network to simulate a microservices architecture. Lastly, the api gateway service ensures that only the admin with a valid JWT can access sensitive operations of other services.
17+
18+
## The Process
19+
20+
I followed this [tutorial](https://www.youtube.com/watch?v=tseqdcFfTUY&list=PLwnoReiC-egEJ-cpIExHV73LZm1yiRN2O&index=3) to deepen my understanding on SpringBoot.
21+
22+
I commented almost each part of the code since this was all new to me until I got an understanding of the repeated patterns used in SpringBoot. I also made a daily journal entry to document what I learnt and how I squashed bugs that arose due to the tutorial being more than a year old.
23+
24+
## What I Learned
25+
26+
The most important lessons were the foundational lessons. Here is the list below -
27+
28+
- When a client interacts with a database in SpringBoot, they should do so using Data Transfer Objects, or DTOs. A developer hide away the details of the internal objects in the database and can pick and choose which fields can be exposed to the client.
29+
30+
- To create methods that interact with a database, create a service folder and create a Java file that appends the name and "Service" together. An example of this is the PatientService.java file.
31+
32+
- Dependency injection works by creating a constructor for a class where the arguments constitute the dependencies required by that class to function. An example of this is the PatientService that requires PatientRepository, the BillingServiceGrpcClient, and the KafkaProducer as its dependencies.
33+
34+
- For testing different services together, create a Dockerfile with the necessary environment variables and arguments and put them all on the same network such as "internal". This allows you to simulate the services communication with each other in a microservices architecture pattern.
35+
36+
- For services that have a database a repository class file can be created and extended using JPA repository. This gives you basic CRUD functionality out of the box. You can create your own queries using the English language instead of sql statements.
37+
38+
- The model folder stores the properties of the entity that you want to model.
39+
40+
- gRPC, created by Google is preferred for communication between internal services due to it higher speed.
41+
42+
- Despite the tutorial being just one year old, a lot of the bug squashing came down to changes being made to core technologies. An example of this is having to a different image of Kafka, namely Apache Kafka. Another example is the fact that the author uses SpringBoot version and I am using SpringBoot version 4, causing compatibility issues when trying to configure the api gateway service
43+
44+
## Future Work (Improvements)
45+
46+
Below are some of the features that could be implemented to further enhance the experience of the hospital administrator -
247

3-
## Extra Features (TO DO)
448
- [ ] Allow a user with admin to add or remove patient from database
549
- [ ] Add Integration test for the above function
650
- [ ] Flow Diagrams to display how services interact with each other
7-
- [ ] Add events such as update, delete patient for analytics-service to track via kafka
51+
- [ ] Add events such as update, delete patient for analytics-service to track via kafka
52+
53+
## Running the Project
54+
55+
- **Prerequisites:** Java 21+
56+
57+
- **Run with Docker (example for `patient-service`):**
58+
- `docker build -t patient-service ./patient-service`
59+
- `docker run -p 8080:8080 patient-service` (check the service's `application.yml`/`application.properties` for the actual port)
60+
61+
- **Integration tests:** `cd integration-tests && ./mvnw test` (or `mvnw.cmd test` on Windows)
62+
63+
- **Notes:** Many services require environment variables (DB, Kafka, gRPC endpoints). Check each service's `src/main/resources` for required settings before running.
64+
65+
## Video Demo
66+
67+
This will be uploaded soon once I complete the frontend.

api-gateway/src/main/resources/application-prod.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ spring:
1010
## Rest client -> http://localhost:5004/auth/login
1111
## api gateway -> http://auth-service:4005/login
1212
- id: auth-service-route
13-
uri: http://auth-service:4005 #
13+
uri: http://host.docker.internal:4005 #
1414
predicates:
1515
# sends request to auth-service if the url has auth in it
1616
- Path=/auth/**
@@ -23,7 +23,7 @@ spring:
2323
## patient service (Spring Boot app) -> /patients -> Patients Array
2424
- id: patient-service-route
2525
# where the request ends up
26-
uri: http://patient-service:5000
26+
uri: http://host.docker.internal:5000
2727
# determine what request is sent to patient-service
2828
predicates:
2929
- Path=/api/patients/**
@@ -36,7 +36,7 @@ spring:
3636
## api gateway -> http://patient-service:5000/v3/api-docs
3737
- id: api-docs-patient-route
3838
# where the request ends up
39-
uri: http://patient-service:5000
39+
uri: http://host.docker.internal:5000
4040
# determine what request is sent to patient-service
4141
predicates:
4242
- Path=/api-docs/patients
@@ -51,7 +51,7 @@ spring:
5151
## api gateway -> http://auth-service:4005/v3/api-docs
5252
- id: api-docs-auth-route
5353
# where the request ends up
54-
uri: http://auth-service:4005
54+
uri: http://host.docker.internal:4005
5555
# determine what request is sent to patient-service
5656
predicates:
5757
- Path=/api-docs/auth

api-requests/auth-service/send-login-request.http

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
# }
99

1010
# send login in request via frontend
11-
12-
POST http://lb-b7d24f40.elb.localhost.localstack.cloud:5004/auth/login
11+
POST http://lb-2e602308.elb.localhost.localstack.cloud:5004/auth/login
1312
Content-Type: application/json
1413

1514
{

infrastructure/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ build/
3232

3333
### VS Code ###
3434
.vscode/
35+
36+
### Cloud Formation Template ###
37+
cdk.out/

infrastructure/cdk.out/localstack.template.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@
468468
"Ref": "AuthServiceDbSubnetGroup12237DD0"
469469
},
470470
"Engine": "postgres",
471-
"EngineVersion": "17.2",
471+
"EngineVersion": "17",
472472
"MasterUserPassword": {
473473
"Fn::Join": [
474474
"",
@@ -572,7 +572,7 @@
572572
"Ref": "PatientServiceDbSubnetGroup1312FFB6"
573573
},
574574
"Engine": "postgres",
575-
"EngineVersion": "17.2",
575+
"EngineVersion": "17",
576576
"MasterUserPassword": {
577577
"Fn::Join": [
578578
"",
@@ -660,7 +660,7 @@
660660
},
661661
"ClusterName": "kafka-cluster-for-patients",
662662
"KafkaVersion": "4.1.x.kraft",
663-
"NumberOfBrokerNodes": 1
663+
"NumberOfBrokerNodes": 2
664664
}
665665
},
666666
"patientManagementClusterBA279E99": {
@@ -704,7 +704,7 @@
704704
},
705705
{
706706
"Name": "JWT_SECRET",
707-
"Value": "${jwt.secret}"
707+
"Value": "1efa4b99150d4203128275ec4711bc8d97139469fe8caf5ed4f9a968e8c4b3ce"
708708
},
709709
{
710710
"Name": "SPRING_DATASOURCE_URL",
@@ -777,7 +777,7 @@
777777
}
778778
}
779779
},
780-
"Name": "auth-service Container",
780+
"Name": "auth-serviceContainer",
781781
"PortMappings": [
782782
{
783783
"ContainerPort": 4005,
@@ -983,7 +983,7 @@
983983
}
984984
}
985985
},
986-
"Name": "billing-service Container",
986+
"Name": "billing-serviceContainer",
987987
"PortMappings": [
988988
{
989989
"ContainerPort": 5001,
@@ -1182,7 +1182,7 @@
11821182
}
11831183
}
11841184
},
1185-
"Name": "analytics-service Container",
1185+
"Name": "analytics-serviceContainer",
11861186
"PortMappings": [
11871187
{
11881188
"ContainerPort": 5002,
@@ -1442,7 +1442,7 @@
14421442
}
14431443
}
14441444
},
1445-
"Name": "patient-service Container",
1445+
"Name": "patient-serviceContainer",
14461446
"PortMappings": [
14471447
{
14481448
"ContainerPort": 5002,
@@ -1635,7 +1635,7 @@
16351635
"Environment": [
16361636
{
16371637
"Name": "AUTH_SERVICE_URL",
1638-
"Value": "host.docker.internal:4005"
1638+
"Value": "http://host.docker.internal:4005"
16391639
},
16401640
{
16411641
"Name": "SPRING_PROFILES_ACTIVE",

0 commit comments

Comments
 (0)