Skip to content

Commit

Permalink
chore: code style reformat
Browse files Browse the repository at this point in the history
reformat the code style of all projects
  • Loading branch information
micaellobo committed Feb 28, 2024
1 parent dcdcbeb commit fa00149
Show file tree
Hide file tree
Showing 115 changed files with 1,832 additions and 1,301 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,31 @@ Spring Boot microservice-based application to manage orders, products, inventory
Use pre-built Docker images for a fast and straightforward way to run the application:

1. Clone the repository or download the
[docker-compose.yaml](https://github.com/micaellobo/e-commerce-store/raw/master/deployment/docker-compose.yaml)
[docker-compose.yaml](https://github.com/micaellobo/e-commerce-store/raw/master/deployment/docker-compose.yaml)
2. Run the following command:

docker-compose up -d

### Local Development with Docker

Build new Docker images and package the application into a JAR file from your local codebase, although it may be a bit slower.
Build new Docker images and package the application into a JAR file from your local codebase, although it may be a bit
slower.

1. Clone the repository.
2. Run the following command:

docker-compose -f docker-compose-dev.yaml up -d --build

For smoother local development, it's recommended to have `Java 17` or higher and `Maven` installed. You can also configure the essential databases using [docker-compose-dbs.yaml](https://github.com/micaellobo/e-commerce-store/raw/master/deployment/docker-compose-dbs.yaml). \
For smoother local development, it's recommended to have `Java 17` or higher and `Maven` installed. You can also
configure the essential databases
using [docker-compose-dbs.yaml](https://github.com/micaellobo/e-commerce-store/raw/master/deployment/docker-compose-dbs.yaml). \
Run each service individually with `mvn spring-boot:run`.

### Exploring and Interacting with API

- **Swagger:** http://localhost:8080/swagger
- **Postman Collection:** [postman_collection.json](https://github.com/micaellobo/e-commerce-store/raw/master/documentation/postman_collection.json)
- **Postman Collection:
** [postman_collection.json](https://github.com/micaellobo/e-commerce-store/raw/master/documentation/postman_collection.json)

# Next Steps and Improvements

Expand All @@ -49,7 +53,8 @@ are a few ideas:
- **Testing:** Implement integration tests using `testContainers` to closely resemble the production environment.
- **Security:** Transitioning from `JWT` to `OAuth` 2.0 with `Keycloak` for more robust authentication and authorization
mechanisms.
- **CI/CD:** Set up pipelines to automate testing and deployment processes with `Jenkins`. Currently using `GitHub Actions` to build and push microservices Docker images to `Docker Hub`.
- **CI/CD:** Set up pipelines to automate testing and deployment processes with `Jenkins`. Currently
using `GitHub Actions` to build and push microservices Docker images to `Docker Hub`.
- **Container Orchestration:** Explore container orchestration platforms like `Kubernetes`.
- **Event-Driven:** Explore asynchronous communication with `Kafka`/ `RabbitMQ`.
- **Distributed Tracing:** Explore distributed tracing tools like `Zipkin`.
Expand Down
2 changes: 1 addition & 1 deletion api-gateway/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.Buildable;
import org.springframework.cloud.gateway.route.builder.PredicateSpec;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;

Expand All @@ -30,54 +26,88 @@ public static void main(String[] args) {
public RouteLocator myRoutes(
final RouteLocatorBuilder builder,
final AuthenticationPrefilter authFilter,
final SwaggerFilter swaggerFilter) {
final SwaggerFilter swaggerFilter
) {
return builder.routes()
.route("auth-service",
r -> r.path("/api/v1/auth/login")
.uri("lb://auth-service"))
.route("user-service-with-auth",
r -> r.path("/api/v1/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://user-service"))
.route("user-service-no-auth",
r -> r.path("/api/v1/users/**")
.uri("lb://user-service"))
.route("inventory-service-with-auth",
r -> r.path("/api/v1/products/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://inventory-service"))
.route("inventory-service-no-auth",
r -> r.path("/api/v1/products/**")
.uri("lb://inventory-service"))
.route("reviews-service-with-auth",
r -> r.path("/api/v1/reviews/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://reviews-service"))
.route("reviews-service-no-auth",
r -> r.path("/api/v1/reviews/**")
.uri("lb://reviews-service"))
.route("orders-service-with-auth",
r -> r.path("/api/v1/orders/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://order-service"))
.route("orders-service-no-auth",
r -> r.path("/api/v1/orders/**")
.uri("lb://order-service"))
.route("user-service-api-docs", r -> r.path("/user-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://user-service"))
.route("inventory-service-api-docs", r -> r.path("/inventory-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://inventory-service"))
.route("order-service-api-docs", r -> r.path("/order-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://order-service"))
.route("reviews-service-api-docs", r -> r.path("/reviews-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://reviews-service"))
.route("auth-service-api-docs", r -> r.path("/auth-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://auth-service"))
.build();
.route(
"auth-service",
r -> r.path("/api/v1/auth/login")
.uri("lb://auth-service")
)
.route(
"user-service-with-auth",
r -> r.path("/api/v1/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://user-service")
)
.route(
"user-service-no-auth",
r -> r.path("/api/v1/users/**")
.uri("lb://user-service")
)
.route(
"inventory-service-with-auth",
r -> r.path("/api/v1/products/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://inventory-service")
)
.route(
"inventory-service-no-auth",
r -> r.path("/api/v1/products/**")
.uri("lb://inventory-service")
)
.route(
"reviews-service-with-auth",
r -> r.path("/api/v1/reviews/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://reviews-service")
)
.route(
"reviews-service-no-auth",
r -> r.path("/api/v1/reviews/**")
.uri("lb://reviews-service")
)
.route(
"orders-service-with-auth",
r -> r.path("/api/v1/orders/users/me/**")
.filters(f -> f.filter(authFilter))
.uri("lb://order-service")
)
.route(
"orders-service-no-auth",
r -> r.path("/api/v1/orders/**")
.uri("lb://order-service")
)
.route(
"user-service-api-docs",
r -> r.path("/user-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://user-service")
)
.route(
"inventory-service-api-docs",
r -> r.path("/inventory-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://inventory-service")
)
.route(
"order-service-api-docs",
r -> r.path("/order-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://order-service")
)
.route(
"reviews-service-api-docs",
r -> r.path("/reviews-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://reviews-service")
)
.route(
"auth-service-api-docs",
r -> r.path("/auth-service/api-docs")
.filters(f -> f.filter(swaggerFilter.apply(new SwaggerFilter.Config())))
.uri("lb://auth-service")
)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.http.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
Expand All @@ -22,7 +22,8 @@
@Component
@Slf4j
@RequiredArgsConstructor
public class AuthenticationPrefilter implements GatewayFilter {
public class AuthenticationPrefilter
implements GatewayFilter {

private final WebClient.Builder webClientBuilder;

Expand All @@ -31,9 +32,11 @@ public class AuthenticationPrefilter implements GatewayFilter {

private Function<ResponseEntity<Void>, Mono<? extends Void>> getResponseEntityMonoFunction(
final ServerWebExchange exchange,
final GatewayFilterChain chain) {
final GatewayFilterChain chain
) {
return response -> {
if (!response.getStatusCode().is2xxSuccessful()) {
if (!response.getStatusCode()
.is2xxSuccessful()) {
return this.onError(exchange, response.getStatusCode());
}

Expand All @@ -48,26 +51,34 @@ private Function<ResponseEntity<Void>, Mono<? extends Void>> getResponseEntityMo
}

var modifiedRequest = exchange.getRequest()
.mutate()
.header("userId", userId)
.header("username", username)
.build();

return chain.filter(exchange.mutate().request(modifiedRequest).build());
.mutate()
.header("userId", userId)
.header("username", username)
.build();

return chain.filter(exchange.mutate()
.request(modifiedRequest)
.build());
};
}

private Mono<Void> onError(final ServerWebExchange exchange, final HttpStatusCode statusCode) {
private Mono<Void> onError(
final ServerWebExchange exchange,
final HttpStatusCode statusCode
) {
var response = exchange.getResponse();
response.setStatusCode(statusCode);
return response.setComplete();
}

@Override
public Mono<Void> filter(final ServerWebExchange exchange, final GatewayFilterChain chain) {
public Mono<Void> filter(
final ServerWebExchange exchange,
final GatewayFilterChain chain
) {

var headers = exchange.getRequest()
.getHeaders();
.getHeaders();

var bearerToken = headers.getFirst(HttpHeaders.AUTHORIZATION);
var correlationID = headers.getFirst(CORRELATION_ID);
Expand All @@ -78,17 +89,17 @@ public Mono<Void> filter(final ServerWebExchange exchange, final GatewayFilterCh
}
try {
return this.webClientBuilder.build()
.post()
.uri(this.authServiceUrl + "/validate")
.header(HttpHeaders.AUTHORIZATION, bearerToken)
.header(CORRELATION_ID, correlationID)
.retrieve()
.toBodilessEntity()
.flatMap(this.getResponseEntityMonoFunction(exchange, chain))
.onErrorResume(WebClientResponseException.class, e -> {
log.error(e.getMessage());
return this.onError(exchange, e.getStatusCode());
});
.post()
.uri(this.authServiceUrl + "/validate")
.header(HttpHeaders.AUTHORIZATION, bearerToken)
.header(CORRELATION_ID, correlationID)
.retrieve()
.toBodilessEntity()
.flatMap(this.getResponseEntityMonoFunction(exchange, chain))
.onErrorResume(WebClientResponseException.class, e -> {
log.error(e.getMessage());
return this.onError(exchange, e.getStatusCode());
});
} catch (Exception e) {
log.error(e.getMessage());
return this.onError(exchange, HttpStatus.INTERNAL_SERVER_ERROR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@

@Component
@Slf4j
public class CorrelationIdFilter implements GlobalFilter, Ordered {
public class CorrelationIdFilter
implements GlobalFilter, Ordered {

public static final String CORRELATION_ID = "correlationId";

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
public Mono<Void> filter(
ServerWebExchange exchange,
GatewayFilterChain chain
) {
var correlationId = this.generateOrRetrieveCorrelationId();
var request = exchange.getRequest()
.mutate()
.header(CORRELATION_ID, correlationId)
.build();
.mutate()
.header(CORRELATION_ID, correlationId)
.build();

log.info("{} - {} - {} - {} - {}", request.getMethod(), request.getPath(), correlationId, null, null);

Expand All @@ -35,7 +39,8 @@ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
}

private String generateOrRetrieveCorrelationId() {
return UUID.randomUUID().toString();
return UUID.randomUUID()
.toString();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import org.springframework.stereotype.Component;

@Component
public class SwaggerFilter extends RewritePathGatewayFilterFactory {
public class SwaggerFilter
extends RewritePathGatewayFilterFactory {
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
Expand All @@ -16,7 +17,12 @@ public GatewayFilter apply(Config config) {
.path("/api-docs")
.build();

return chain.filter(exchange.mutate().request(modifiedRequest).build());
var build = exchange
.mutate()
.request(modifiedRequest)
.build();

return chain.filter(build);
};
}
}
2 changes: 1 addition & 1 deletion auth-service/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
Expand Down
Loading

0 comments on commit fa00149

Please sign in to comment.