Skip to content

mostafacs/social-media-quarkus-microservices-kubernetes

Repository files navigation

Social Media Platform

About Project

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.

Technology Stack

  • 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, ...)

Project Architecture

Goal: Load user feed and add new feed too fast

Add Post

Add post architecture

Load user feed

Loading user feed architecture

** 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.

Run App Locally on k8s

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

using minikube docker environment

# 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

or using local registry

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

Now you can access the app using:

curl https://social.app/feed/{{endpoint path}}
curl https://social.app/user/{{endpoint path}}

Test the App Without k8s

** 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}"