Implementation for social media network system using Java, Quarkus, Kafka and Hazelcast (for caching). I tried to write code in best practice software development and implement the architecture to achieve project security and resilience.
- Mysql (DB)
- Kafka (help in processing users feed in the background)
- Hazelcast for cache user feeds and Post caching too(I will add Redis and you can switching between them from the config).
- Keycloak project security (Authentication and Authorization)
- Java (Quarkus, JPA, ...)
Goal: Load user feed and add new feed too fast
** Note: I'm not using every service as a cache node instead I imagined there is a hazelcast cluster contains a separated nodes (pods) for caching.
You need to have MYSQL database installed on your machine and add two empty schemas (social_media, keycloak), docker desktop, docker compose and minikube
** Be sure you have Docker Desktop started:
cd social-media-quarkus-kubernetes
docker compose up
# Start minikube cluster
minikube start
# User minikube docker environment
eval $(minikube docker-env)
cd ${project-root-folder}
# Build project jars and docker images
mvn clean install -Dquarkus.container-image.build=true
docker run -d -p 5000:5000 --name registry registry:2.7
minikube start --cpus 4 --memory 4096 --insecure-registry localhost:5000
cd services/feed
docker build -f src/main/docker/Dockerfile.jvm -t social/feed:1.0 .
docker tag social/feed:1.0 localhost:5000/social/feed:1.0
docker push localhost:5000/social/feed
kubectl apply -f target/kubernetes/kubernetes.yml
Add Certificates for Ingress-Nginx
cd kubernetes/certificate
kubectl create secret tls ingress-tls --key certificate.key --cert cert.pem
Apply secrets, config-maps and ingress configurations
kubectl apply -f kubernetes/config
Deploy Feed and User Service
cd services/feed
kubectl apply -f target/kubernetes/kubernetes.yml
cd services/user
kubectl apply -f target/kubernetes/kubernetes.yml
Run minikube tunnel to access the ingress controller
minikube tunnel
Update your /etc/hosts file and add the following line:
127.0.0.1 social.app
curl https://social.app/feed/{{endpoint path}}
curl https://social.app/user/{{endpoint path}}
** To test on k8s please replace http://localhost:8010/ to https://social.app/{service}/
1- Register two users
first one
curl -X POST --location "http://localhost:8010/register" \
-H "Content-Type: application/json" \
-d "{\"username\": \"mostafa\", \"password\": \"123\", \"firstname\": \"Mostafa\", \"lastname\": \"Albana\", \"email\": \"[email protected]\"}"
second user
curl -X POST --location "http://localhost:8010/register" \
-H "Content-Type: application/json" \
-d "{\"username\": \"mostafa2\", \"password\": \"123\", \"firstname\": \"Mostafa2\", \"lastname\": \"Albana2\", \"email\": \"[email protected]\"}"
2- Login (Get the OAuth token from Keycloak) (Token 1)
curl --insecure -X POST http://localhost:8080/realms/social/protocol/openid-connect/token \
--user backend-service:Wbw4dVq74XTlzjfXTIKizFEVodPOPmY4 \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'username=mostafa&password=123&grant_type=password'
3- Send friend request
curl -X POST --location "http://localhost:8010/friend/send/{to}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token1}"
4- Then login with the other user (Token2)
curl --insecure -X POST http://localhost:8080/realms/social/protocol/openid-connect/token \
--user backend-service:Wbw4dVq74XTlzjfXTIKizFEVodPOPmY4 \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'username=mostafa2&password=123&grant_type=password'
5- Confirm friend request
curl -X PUT --location "http://localhost:8010/friend/confirm/{friend-request-id}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token2}"
6- Add New Post for user1 (mostafa)
curl -X POST --location "http://localhost:8020/post" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token1}" \
-d "{\"postBody\": \"My first post\"}"
7- Get the feed of user2 (mostafa2)
curl -X GET --location "http://localhost:8020/get" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token2}"