sequenceDiagram
participant Client
participant AuthService
participant CustomerService
participant ProductService
participant OrderService
participant PaymentService
participant Kafka
Client->>AuthService: POST /auth
AuthService-->>Client: JWT
Client->>CustomerService: POST /customers
CustomerService-->>Client: Customer Created
Client->>ProductService: POST /products
ProductService-->>Client: Product Created
Client->>OrderService: POST /orders
OrderService-->>Client: Order Created
OrderService->>Kafka: OrderEvent Published
Kafka-->>PaymentService: OrderEvent Consumed
Note right of PaymentService: Payment Created
Client->>PaymentService: PUT /payments/order/{orderId}/status/{status}
PaymentService-->>Client: Payment Status Updated
PaymentService->>Kafka: PaymentEvent Published
Kafka-->>OrderService: PaymentEvent Consumed
Note right of OrderService: Status Updated
- Screaming Architecture
- Clean Architecture
- Event-Driven Architecture
- Clean Code
- Domain-Driven Design
- SOLID Principles
- Separation of Concerns
- Common Closure Principle
- Common Reuse Principle
- Test Pyramid
- Ambassador Pattern
- Circuit Breaker Pattern
- Mediator Pattern
- Outbox Pattern
- Result Pattern
- Retry Pattern
- Strategy Pattern
- Java
- Spring Boot
- Kong
- Keycloak
- OAuth2
- JWT
- Kafka
- MongoDB
- Debezium
- Redis
- Elastic
- Swagger
- Testcontainers
- Docker
- Kubernetes
docker compose up --detach --build --remove-orphans
Install Into Local Maven Repository: mvn clean install
-
Kong:
http://localhost:8002
-
Keycloak:
http://localhost:8005
-
Username:
admin
-
Password:
password
-
Role:
Manage Realms
>microservices
>Clients
>authservice
>Service Accounts Roles
>Assign Role
>manage-users
-
-
Kafka:
http://localhost:9000
-
Mongo:
http://localhost:27018
-
Redis:
http://localhost:6380
-
Logs:
http://localhost:5601/app/management/data/index_management/data_streams
-
APM:
http://localhost:5601/app/apm/services
Localhost: http://localhost:8010
Docker: http://localhost:9010
Kong: http://localhost:8000/authservice
Method | Endpoint | Description |
---|---|---|
/auth | Get | |
/auth | Auth | |
/users | Save | |
/users/{id} | Delete |
Localhost: http://localhost:8015
Docker: http://localhost:9015
Kong: http://localhost:8000/configurationservice
Localhost: http://localhost:8020
Docker: http://localhost:9020
Kong: http://localhost:8000/customerservice
Method | Endpoint | Description |
---|---|---|
/customers | List | |
/customers | Create | |
/customers/{id} | Get | |
/customers/{id} | Update | |
/customers/{id} | Delete |
Localhost: http://localhost:8025
Docker: http://localhost:9025
Kong: http://localhost:8000/productservice
Method | Endpoint | Description |
---|---|---|
/products | List | |
/products | Create | |
/products/{id} | Get | |
/products/{id} | Update | |
/products/{id} | Delete |
Localhost: http://localhost:8030
Docker: http://localhost:9030
Kong: http://localhost:8000/orderservice
Method | Endpoint | Description |
---|---|---|
/orders | List | |
/orders | Create | |
/orders/{id} | Get |
Localhost: http://localhost:8035
Docker: http://localhost:9035
Kong: http://localhost:8000/paymentservice
Method | Endpoint | Description |
---|---|---|
/payments | List | |
/payments/{id} | Get | |
/payments/order/{orderId} | Get By Order Id | |
/payments/order/{orderId}/status/{status} | Update Status |
@Service
public class ProductService {
@Cacheable(value = "products")
public List<Product> get() {
return repository.findAll();
}
@Cacheable(value = "products", key = "#id")
public Optional<Product> get(final UUID id) {
return repository.findById(id);
}
@CachePut(value = "products", key = "#product.id")
public Product save(final Product product) {
return repository.save(product);
}
@CacheEvict(value = "products", key = "#id")
public void delete(final UUID id) {
repository.deleteById(id);
}
@CacheEvict(value = "products", allEntries = true)
public void delete() {
repository.deleteAll();
}
}
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>X.X.X</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-mongo</artifactId>
<version>X.X.X</version>
</dependency>
@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "5m")
public class ShedLockConfiguration {
private final MongoClient mongoClient;
public ShedLockConfiguration(final MongoClient mongoClient) {
this.mongoClient = mongoClient;
}
@Bean
public MongoLockProvider lockProvider() {
return new MongoLockProvider(mongoClient, "database");
}
}
@Component
public class Scheduler {
@Scheduled(fixedDelay = 5000)
@SchedulerLock(name = "SchedulerJob", lockAtMostFor = "1m")
public void job() {
System.out.println("Executing!");
}
}