Skip to content

Microservices development for managing your list of preferred mythical beasts. This multimodule Maven project is built with Reactive Programming, Hexagonal Arch, CQRS, Event Sourcing, and Kafka for synchronizing databases. RSocket for communication between microservices and Redis to store relevant information from other components.

License

Notifications You must be signed in to change notification settings

Ivan-Montes/nano-bestiary

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nano-bestiary

Microservices development for managing your list of preferred mythical beasts. This multimodule Maven project is built with Reactive Programming, Hexagonal Arch, CQRS, Event Sourcing, and Kafka for synchronizing databases. RSocket for communication between microservices and Redis to store relevant information from other components.

Components

 
graph BT

subgraph KafkaUI
 Kafka-UI
end  

subgraph Kafka
  Kafka-Server
end 
  
subgraph oauth2-server
  oauth2server{{JWT Authorization Server}}
end

subgraph ms-area
   A{{Area}}
end 

subgraph ms-area-db["Databases for ms-area"]
  direction RL
   A1[(Sql Read Db)]
   A2[(NoSql Write Db)]
   A3[(Redis Backup Db)]
end

subgraph ms-creature
   C{{Creature}}
end 

subgraph ms-creature-db["Databases for ms-creature"]
  direction RL
   C1[(Sql Read Db)]
   C2[(NoSql Write Db)]
   C3[(Redis Backup Db)]
end

ms-area-db <--> ms-area
ms-creature-db <--> ms-creature    

A1 <-. Synchro .-> A2
C1 <-. Synchro .-> C2

ms-area <-->|Publish-Subscriber| Kafka
ms-creature <-->|Publish-Subscriber| Kafka 

ms-area <-.->| | oauth2-server
ms-creature <-.->| | oauth2-server 

KafkaUI <--> |  | Kafka
  
classDef canvas_basic fill:#82C0CC,stroke:#333;
classDef ms_basic fill:#FFB703,stroke:#333;
classDef db_basic fill:#FD9E02,stroke:#333;
classDef redis_basic fill:#FB8500,stroke:#333

class ms-area-db,ms-creature-db canvas_basic
class A,C,Kafka-UI,oauth2server,Kafka-Server ms_basic
class A1,A2,C1,C2, db_basic
class A3,C3 redis_basic

class ms-area,ms-creature,oauth2-server,Kafka,KafkaUI canvas_basic
 
Loading

Table of contents

Installation

  1. First of all clone or download the project.

  2. Inside the main folder, you could find two docker-compose yaml files.

  3. From there use the command line to start the project in dev or production mode

    **Developer mode**  
    docker-compose -f docker-compose-dev.yml up -d

    **Production mode**
    docker-compose -f docker-compose-prod.yml up -d

The dev environment is ready for using with your IDE. The microservice attempts to communicate with Kafka using the local host. In production, it uses the archive Dockerfile to build an image of the project, so you wont need the IDE.

  1. You could stop the project and free resources with any of these orders
    **Developer mode**
    docker-compose -f docker-compose-dev.yml down --rmi local -v
      
    **Production mode**
    docker-compose -f docker-compose-prod.yml down --rmi local -v  

Usage

First of all, please visit the centralized REST API documentation on the Api-Gateway server. You can change the selection on the upper dropdown menu.

http://localhost:8080/swagger-ui.html

In this context, unexpected behavior may occur due to the different network settings when using Swagger requests directly from Api-Gateway centralized Swagger-UI. To prevent some of these issues, CORS and CSRF have been disabled in Spring Security settings. Alternatively if you want use the Swagger-UI dashboard for REST operations, it is recommended to call the microservice directly:

http://localhost:${port}/swagger-ui.html.

API Rest Endpoints have dynamic ports but Api Gateway responds on 8080 port, so you could use a program like SoapUI or curl and call them with the following nomenclature http://${hostname}:8080/api/v1/${entity}. For instance:

    ** Get a List of Area entities **
    curl -v http://localhost:8080/api/v1/areas

    ** Get a Creature according to an Id **
    curl -v http://localhost:8080/api/v1/creatures/22000000-0000-0000-0000-000000000003
    
    ** Create Area **
    curl -v -H "Content-Type: application/json" -d '{"areaName":"Delfos"}' http://localhost:8080/api/v1/areas
    
    ** Update Creature **
    curl -v -X "PUT" -H "Content-Type: application/json" -d '{"creatureName":"Harpy", "creatureDescription":"half-human and half-bird", "areaId":"11000000-0000-0000-0000-000000000001"}' http://localhost:8080/api/v1/creatures/22000000-0000-0000-0000-000000000008
    
    ** Delete a Creature according to an Id **
    curl -v -X "DELETE" http://localhost:8080/api/v1/creatures/22000000-0000-0000-0000-000000000005
    

The initial data load is performed by the kafka-data-init microservice. It uses Kafka to publish events, which the other microservices then use to update their databases.

Kafka-UI allow you to check your Kafka server using a practical dashboard, so visit the following url:

http://localhost:8081

A good way for checking the JWT generation and validation flow, is reading this and following these steps:

  • First you should register an user using the method POST and the URL http://localhost:9000/register. Here is an example of the info you need to send:
{
  "name":"Marco",	
  "lastname":"Polo",	
  "email":"[email protected]",
  "password":"passpasspass"
}
  • Next, since form-based login authorization is active, we need to use a browser. Navigate to http://localhost:9000/login and use the credentials you have just created. Ignore any NoResourceFoundException error.
  • Then we will request the authorization code with the same browser. The authorization server will respond with a code, which the client can exchange for tokens over a secure channel.
http://localhost:9000/oauth2/authorize
?client_id=client
&redirect_uri=http://localhost:9000/callback
&scope=openid
&response_type=code
&response_mode=query
&state=k13gsri3gw
&nonce=njumydikqj
  • We use the POST method to request our JWT token sending the authorization code and the rest of parameters

 

  • Now we can use the retrieved JWT token to reach the unique protected URL in the rest of microservices at http://{host}:{port}/actuator/metrics

This project has my own profile of SoapUI with the endpoints configured. Everything is in the file Proy-nano-bestiary-soapui-project.xml at the root folder.

If you want to test the project in a Kubernetes environment, you can use the contents of k8s-manifest folder. The manifests are configured for development profile, so you need your IDE to deploy the microservice infrastructure. You can run all manifest files with:

kubectl -apply ./k8s-manifest

Features

▶️ Unit testing for business logic classes using Test Containers for Repositories

▶️ Hexagonal Architecture and CQRS with independent databases

▶️ Redis DB for each microservice works as caches to store ID references for other REST APIs

▶️ Event Sourcing for persisting as an ordered sequence of events

▶️ Use of RSocket for request communication between microservices

Maintainers

Just me, Iván 😅

License

GPLv3 license


Java Maven Spring GitHub Eclipse SonarQube Docker Kafka GPLv3 license

About

Microservices development for managing your list of preferred mythical beasts. This multimodule Maven project is built with Reactive Programming, Hexagonal Arch, CQRS, Event Sourcing, and Kafka for synchronizing databases. RSocket for communication between microservices and Redis to store relevant information from other components.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Contributors 3

  •  
  •  
  •