Skip to content

Commit

Permalink
feat: update code to use webflux (#95)
Browse files Browse the repository at this point in the history
Co-authored-by: Paulo Gomes da Cruz Junior <paulo.cruz@encora.com>
  • Loading branch information
brunoMarchiEncora and Paulo Gomes da Cruz Junior committed Jan 31, 2023
1 parent e88da07 commit b29c915
Show file tree
Hide file tree
Showing 8 changed files with 426 additions and 221 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ca.bc.gov.api.oracle.legacy.configuration;

import static org.springframework.web.reactive.function.server.RequestPredicates.path;
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;

import ca.bc.gov.api.oracle.legacy.routes.BaseRouter;
import io.swagger.v3.oas.models.tags.Tag;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

@Configuration
@Slf4j
public class RouteConfiguration {

@Bean
public RouterFunction<ServerResponse> routes(List<BaseRouter> routes) {
return
routes
.stream()
.map(route -> nest(
path(String.format("/api%s", route.basePath())),
route.routerRoute())
)
.reduce(RouterFunction::and)
.orElseThrow();
}

@Bean
public OpenApiCustomizer tagCustomizer(List<BaseRouter> routes) {
return openAPI -> routes.forEach(route ->
openAPI
.addTagsItem(
new Tag()
.name(route.routeTagName())
.description(route.routeTagDescription())));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ca.bc.gov.api.oracle.legacy.handlers;

import ca.bc.gov.api.oracle.legacy.dto.ClientPublicViewDto;
import ca.bc.gov.api.oracle.legacy.service.ClientService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
@RequiredArgsConstructor
public class ClientHandler {

private final ClientService clientService;

public Mono<ServerResponse> findByClientNumber(ServerRequest serverRequest) {
String clientNumber = serverRequest.pathVariable("clientNumber");
return clientService
.findByClientNumber(clientNumber)
.flatMap(response -> ServerResponse.ok()
.body(Mono.just(response), ClientPublicViewDto.class));
}

public Mono<ServerResponse> findAllNonIndividuals(ServerRequest serverRequest) {
int page = Integer.parseInt(serverRequest.queryParam("page").orElse("0"));
int size = Integer.parseInt(serverRequest.queryParam("size").orElse("10"));
String sortedColumnName = serverRequest.queryParam("sortedColumnName").orElse("clientName");

return
clientService.findAllNonIndividualClients(page, size, sortedColumnName)
.flatMap(response -> ServerResponse.ok()
.body(Mono.just(response), List.class));
}

public Mono<ServerResponse> findByNames(ServerRequest serverRequest) {
String clientName = serverRequest.queryParam("clientName").orElse("");
String clientFirstName = serverRequest.queryParam("clientFirstName").orElse("");
String clientMiddleName = serverRequest.queryParam("clientMiddleName").orElse("");
List<String> clientTypeCodes = serverRequest.queryParams().get("clientTypeCodes");
int page = Integer.parseInt(serverRequest.queryParam("page").orElse("0"));
int size = Integer.parseInt(serverRequest.queryParam("size").orElse("10"));

return clientService.searchByNames(clientName, clientFirstName, clientMiddleName,
clientTypeCodes, page, size)
.flatMap(response -> ServerResponse.ok()
.body(Mono.just(response), List.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package ca.bc.gov.api.oracle.legacy.handlers;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Mono;

@RestControllerAdvice
@ControllerAdvice
@Slf4j
@Component
@Order(-2)
public class GlobalErrorHandler extends AbstractErrorWebExceptionHandler {

public GlobalErrorHandler(
ErrorAttributes errorAttributes,
WebProperties webProperties,
ApplicationContext applicationContext,
ServerCodecConfigurer configurer) {
super(errorAttributes, webProperties.getResources(), applicationContext);
this.setMessageWriters(configurer.getWriters());
}

@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(
RequestPredicates.all(), request -> renderErrorResponse(request, errorAttributes));
}

private Mono<ServerResponse> renderErrorResponse(
ServerRequest request, ErrorAttributes errorAttributes) {

Throwable exception = errorAttributes.getError(request).fillInStackTrace();
String errorMessage = exception.getMessage();
HttpStatusCode errorStatus = HttpStatus.INTERNAL_SERVER_ERROR;

log.error(
"An error was generated during request for {} {}",
request.method(),
request.requestPath(),
exception);

if (exception instanceof ResponseStatusException responseStatusException) {
errorMessage = responseStatusException.getReason();
errorStatus = responseStatusException.getStatusCode();
}

errorMessage =
BooleanUtils.toString(StringUtils.isBlank(errorMessage), StringUtils.EMPTY, errorMessage);

log.error("{} - {}", errorStatus, errorMessage);

return ServerResponse.status(errorStatus)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(errorMessage));
}
}
15 changes: 15 additions & 0 deletions src/main/java/ca/bc/gov/api/oracle/legacy/routes/BaseRouter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ca.bc.gov.api.oracle.legacy.routes;

import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

public interface BaseRouter {
String basePath();

RouterFunction<ServerResponse> routerRoute();

String routeTagName();

String routeTagDescription();

}
Loading

0 comments on commit b29c915

Please sign in to comment.