From 6fb551d01225a218810c5e9e86d4c79e6b1abcfa Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 10 Sep 2020 18:21:27 +0200 Subject: [PATCH 1/3] upgrade spring-boot version --- pom.xml | 35 ++++--------------- .../repository/SimpleRepositoryTest.java | 20 ++++++----- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/pom.xml b/pom.xml index f0b042e..52312ab 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.5.RELEASE + 2.3.3.RELEASE @@ -23,11 +23,6 @@ - - org.springframework.boot - spring-boot-starter - - org.springframework.boot spring-boot-starter-web @@ -35,7 +30,7 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-starter-validation @@ -55,8 +50,8 @@ - junit - junit + org.junit.vintage + junit-vintage-engine @@ -101,25 +96,6 @@ 4.2.1 - - - org.junit.jupiter - junit-jupiter-api - test - - - - org.junit.jupiter - junit-jupiter-engine - test - - - - org.mockito - mockito-junit-jupiter - test - - de.flapdoodle.embed @@ -134,10 +110,12 @@ org.springframework.boot spring-boot-maven-plugin + org.apache.maven.plugins maven-surefire-plugin + com.mysema.maven apt-maven-plugin @@ -156,6 +134,7 @@ + com.google.cloud.tools diff --git a/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java b/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java index 206f3f8..e396d94 100644 --- a/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java +++ b/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java @@ -2,11 +2,11 @@ import com.example.simple.config.MongoDbCollectionsConfig; import com.example.simple.domain.Simple; -import com.mongodb.DBObject; +import com.mongodb.BasicDBList; import com.mongodb.client.model.IndexOptions; import com.mongodb.client.model.Indexes; -import com.mongodb.util.JSON; import org.apache.commons.io.FileUtils; +import org.bson.BsonArray; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -48,20 +48,22 @@ class SimpleRepositoryTest { * @throws IOException */ private void loadFileInMongodb(String path) throws IOException { + mongoOperations.dropCollection(mongoDbCollectionsConfig.getSimpleObjects()); + + mongoOperations.getCollection(mongoDbCollectionsConfig.getSimpleObjects()) + .createIndex(Indexes.ascending("simpleId"), new IndexOptions().unique(true)); + final var mongodbFile = FileUtils.readFileToString( new ClassPathResource(path).getFile(), Charset.defaultCharset() ); - final List dboList = (List) JSON.parse(mongodbFile); + BasicDBList dbList = new BasicDBList(); - mongoOperations.dropCollection(mongoDbCollectionsConfig.getSimpleObjects()); - - mongoOperations.getCollection(mongoDbCollectionsConfig.getSimpleObjects()) - .createIndex(Indexes.ascending("simpleId"), new IndexOptions().unique(true)); + dbList.addAll(BsonArray.parse(mongodbFile)); - for (DBObject dbo : dboList) - mongoOperations.save(dbo, mongoDbCollectionsConfig.getSimpleObjects()); + for (Object dbObject : dbList) + mongoOperations.save(dbObject, mongoDbCollectionsConfig.getSimpleObjects()); } @Test From adc7c52ccb0d71c82882399916e24e772b762651 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Tue, 22 Sep 2020 09:58:51 +0200 Subject: [PATCH 2/3] add d4rk3on spring-mvc dependency --- README.md | 19 ++-- pom.xml | 29 +++--- .../com/example/simple/SimpleApplication.java | 5 +- .../simple/config/GlobalExceptionHandler.java | 95 ------------------- .../example/simple/config/LoggerAspect.java | 85 ----------------- ...waggerConfig.java => SpringFoxConfig.java} | 17 ++-- .../com/example/simple/domain/Simple.java | 6 +- .../example/simple/service/SimpleService.java | 7 +- .../simple/service/SimpleServiceImpl.java | 50 +++------- .../example/simple/util/ExceptionEnum.java | 28 ------ .../simple/util/FunctionalException.java | 27 ------ .../example/simple/web/SimpleController.java | 8 +- .../web/response/GlobalExceptionResponse.java | 16 ---- src/main/resources/application-dev.yml | 6 ++ src/main/resources/application-docker.yml | 5 + src/main/resources/logback.xml | 48 ---------- .../config/GlobalExceptionHandlerTest.java | 89 ----------------- .../simple/config/LoggerAspectTest.java | 82 ---------------- .../repository/SimpleRepositoryTest.java | 39 ++++---- .../simple/service/SimpleServiceTest.java | 17 ++-- .../simple/web/SimpleControllerTest.java | 84 ++++++++++------ .../example/simple/web/TestController.java | 38 -------- src/test/resources/application.yml | 5 + 23 files changed, 157 insertions(+), 648 deletions(-) delete mode 100644 src/main/java/com/example/simple/config/GlobalExceptionHandler.java delete mode 100644 src/main/java/com/example/simple/config/LoggerAspect.java rename src/main/java/com/example/simple/config/{SwaggerConfig.java => SpringFoxConfig.java} (53%) delete mode 100644 src/main/java/com/example/simple/util/ExceptionEnum.java delete mode 100644 src/main/java/com/example/simple/util/FunctionalException.java delete mode 100644 src/main/java/com/example/simple/web/response/GlobalExceptionResponse.java delete mode 100644 src/main/resources/logback.xml delete mode 100644 src/test/java/com/example/simple/config/GlobalExceptionHandlerTest.java delete mode 100644 src/test/java/com/example/simple/config/LoggerAspectTest.java delete mode 100644 src/test/java/com/example/simple/web/TestController.java diff --git a/README.md b/README.md index 183e4ae..e194901 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -[![Coverage Status](https://coveralls.io/repos/github/D4rK3oN/spring-boot-2-simple-example/badge.svg?branch=master)](https://coveralls.io/github/D4rK3oN/spring-boot-2-simple-example?branch=master) +[![Coverage Status][coveralls-shield]][coveralls-url] +[![JitPack][jitpack-shield]][jitpack-url] [![Contributors][contributors-shield]][contributors-url] -[![Forks][forks-shield]][forks-url] -[![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![LinkedIn][linkedin-shield]][linkedin-url] @@ -27,6 +26,7 @@ * [Getting Started](#getting-started) * [Prerequisites](#prerequisites) * [Installation](#installation) +* [Swagger-UI](#swagger-ui) * [Roadmap](#roadmap) @@ -99,18 +99,23 @@ Program args: --spring.profiles.active=dev run config

+ +## Swagger-UI + +Swagger generated by springfox 3.0.0 : http://localhost:8080/swagger-ui/index.html#/ + ## Roadmap See the [open issues](https://github.com/D4rK3oN/spring-boot-2-simple-example/issues) for a list of proposed features (and known issues). +[coveralls-shield]: https://coveralls.io/repos/github/D4rK3oN/spring-boot-2-simple-example/badge.svg?branch=master +[coveralls-url]: https://coveralls.io/github/D4rK3oN/spring-boot-2-simple-example?branch=master +[jitpack-shield]: https://jitpack.io/v/D4rK3oN/lib-spring-boot-mvc.svg +[jitpack-url]: https://jitpack.io/#D4rK3oN/lib-spring-boot-mvc [contributors-shield]: https://img.shields.io/github/contributors/D4rK3oN/spring-boot-2-simple-example.svg?style=flat-square [contributors-url]: https://github.com/D4rK3oN/spring-boot-2-simple-example/graphs/contributors -[forks-shield]: https://img.shields.io/github/forks/D4rK3oN/spring-boot-2-simple-example.svg?style=flat-square -[forks-url]: https://github.com/D4rK3oN/spring-boot-2-simple-example/network/members -[stars-shield]: https://img.shields.io/github/stars/D4rK3oN/spring-boot-2-simple-example.svg?style=flat-square -[stars-url]: https://github.com/D4rK3oN/spring-boot-2-simple-example/stargazers [issues-shield]: https://img.shields.io/github/issues/D4rK3oN/spring-boot-2-simple-example.svg?style=flat-square [issues-url]: https://github.com/D4rK3oN/spring-boot-2-simple-example/issues [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555 diff --git a/pom.xml b/pom.xml index 52312ab..db02c72 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ org.springframework.boot spring-boot-starter-parent - 2.3.3.RELEASE + 2.4.1 com.example simple - 1.1.1 + 1.1.2-SNAPSHOT [Spring Boot] Simple Example Spring Boot 2: Simple example @@ -24,18 +24,14 @@ - org.springframework.boot - spring-boot-starter-web + com.github.d4rk3on + lib-spring-boot-mvc + 1.0.3 org.springframework.boot - spring-boot-starter-validation - - - - org.springframework.boot - spring-boot-starter-aop + spring-boot-starter-web @@ -65,35 +61,34 @@ io.springfox - springfox-swagger2 - 2.9.2 + springfox-boot-starter + 3.0.0 - io.springfox springfox-swagger-ui - 2.9.2 + 3.0.0 commons-io commons-io - 2.6 + 2.11.0 com.querydsl querydsl-apt - 4.2.1 + 5.0.0 com.querydsl querydsl-mongodb - 4.2.1 + 5.0.0 diff --git a/src/main/java/com/example/simple/SimpleApplication.java b/src/main/java/com/example/simple/SimpleApplication.java index e4db97c..49b9f77 100644 --- a/src/main/java/com/example/simple/SimpleApplication.java +++ b/src/main/java/com/example/simple/SimpleApplication.java @@ -2,12 +2,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @SpringBootApplication -@EnableMongoRepositories(basePackages = "com.example.simple.repository") +@ComponentScan(basePackages = {"com.github.d4rk3on", "com.example.simple"}) +@EnableMongoRepositories public class SimpleApplication { - public static void main(String[] args) { SpringApplication.run(SimpleApplication.class, args); } diff --git a/src/main/java/com/example/simple/config/GlobalExceptionHandler.java b/src/main/java/com/example/simple/config/GlobalExceptionHandler.java deleted file mode 100644 index caeb404..0000000 --- a/src/main/java/com/example/simple/config/GlobalExceptionHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.example.simple.config; - -import com.example.simple.util.ExceptionEnum; -import com.example.simple.util.FunctionalException; -import com.example.simple.web.response.GlobalExceptionResponse; -import lombok.extern.slf4j.Slf4j; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpStatus; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -import javax.servlet.http.HttpServletResponse; -import javax.validation.ConstraintViolationException; - -@Slf4j -@Order(Ordered.HIGHEST_PRECEDENCE) -@RestControllerAdvice -public class GlobalExceptionHandler { - - /** - * Handle default exceptions - * - * @param ex Exception - * @return GlobalExceptionResponse - */ - @ExceptionHandler(Exception.class) - @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public GlobalExceptionResponse exceptionHandler(Exception ex) { - log.error("Exception thrown [{}]", ex.getClass().getSimpleName(), ex); - - return GlobalExceptionResponse.builder() - .code(ExceptionEnum.INTERNAL_SERVER_ERROR.getHttpStatus().value()) - .message(ExceptionEnum.INTERNAL_SERVER_ERROR.getMessage()) - .detail(ex.getClass().getSimpleName() - .concat(" : ") - .concat(ex.getMessage())) - .build(); - } - - /** - * Constraint violation exceptions - * - * @param ex ConstraintViolationException - * @return GlobalExceptionResponse - */ - @ExceptionHandler(ConstraintViolationException.class) - @ResponseStatus(HttpStatus.BAD_REQUEST) - public GlobalExceptionResponse constraintExceptionHandler(Exception ex) { - log.error("Exception thrown [{}]", ex.getClass().getSimpleName(), ex); - - return GlobalExceptionResponse.builder() - .code(ExceptionEnum.INVALID_INPUT_PARAMETERS.getHttpStatus().value()) - .message(ExceptionEnum.INVALID_INPUT_PARAMETERS.getMessage()) - .detail(ex.getClass().getSimpleName() - .concat(" : ") - .concat(ex.getMessage())) - .build(); - } - - /** - * Request exceptions - * - * @param ex HttpMessageNotReadableException - * @return GlobalExceptionResponse - */ - @ExceptionHandler(HttpMessageNotReadableException.class) - @ResponseStatus(HttpStatus.BAD_REQUEST) - public GlobalExceptionResponse httpMessageNotReadableExceptionHandler(Exception ex) { - log.error("Exception thrown [{}]", ex.getClass().getSimpleName(), ex); - - return GlobalExceptionResponse.builder() - .code(ExceptionEnum.INVALID_REQUEST.getHttpStatus().value()) - .message(ExceptionEnum.INVALID_REQUEST.getMessage()) - .detail(ex.getClass().getSimpleName() - .concat(" : ") - .concat(ex.getMessage())) - .build(); - } - - @ExceptionHandler(FunctionalException.class) - public GlobalExceptionResponse functionalExceptionHandler(HttpServletResponse response, FunctionalException ex) { - log.error("FunctionalException thrown [{}]", ex.getExceptionEnum().getMessage(), ex); - - response.setStatus(ex.getExceptionEnum().getHttpStatus().value()); - - return GlobalExceptionResponse.builder() - .code(ex.getExceptionEnum().getHttpStatus().value()) - .message(ex.getExceptionEnum().getMessage()) - .detail(ex.getDetail()) - .build(); - } -} diff --git a/src/main/java/com/example/simple/config/LoggerAspect.java b/src/main/java/com/example/simple/config/LoggerAspect.java deleted file mode 100644 index 15a1085..0000000 --- a/src/main/java/com/example/simple/config/LoggerAspect.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.example.simple.config; - -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.List; - -@Slf4j -@Aspect -@Component -public class LoggerAspect { - private static final String CONTROLLER_MANAGER = "execution(* com.example.*.web.*Controller.*(..))"; - private static final String SERVICE_MANAGER = "execution(* com.example.*.service.*Service.*(..))"; - private static final String REPOSITORY_MANAGER = "execution(* com.example.*.repository.*Repository.*(..))"; - private static final String SPRING_DATA_REPOSITORY_MANAGER = "execution(* org.springframework.data.repository.*Repository.*(..))"; - - @Pointcut(CONTROLLER_MANAGER) - public void logControllerLayer() { - } - - @Pointcut(SERVICE_MANAGER) - public void logServiceLayer() { - } - - @Pointcut(REPOSITORY_MANAGER) - public void logRepositoryLayer() { - } - - @Pointcut(SPRING_DATA_REPOSITORY_MANAGER) - public void logSpringDataRepositoryLayer() { - } - - /** - * Logging all app layer. - * - * @param joinPoint - * @return - * @throws Throwable - */ - @Around("logControllerLayer() || logServiceLayer() || logRepositoryLayer()") - public Object printTraces(final ProceedingJoinPoint joinPoint) throws Throwable { - log.info("Invoked class [{}.{}] | Input Args -> {}", - joinPoint.getTarget().getClass().getSimpleName(), - joinPoint.getSignature().getName(), - CollectionUtils.arrayToList(joinPoint.getArgs()).isEmpty() ? "[EMPTY]" : joinPoint.getArgs()); - - final Object resultMethodExecution = joinPoint.proceed(); - - log.info("Invoked class [{}.{}] | Output Response -> {}", - joinPoint.getTarget().getClass().getSimpleName(), - joinPoint.getSignature().getName(), - resultMethodExecution); - - return resultMethodExecution; - } - - /** - * Logging Spring Data Repository layer. - * - * @param joinPoint - * @return - * @throws Throwable - */ - @Around("logSpringDataRepositoryLayer()") - public Object printSpringDataTraces(final ProceedingJoinPoint joinPoint) throws Throwable { - log.info("Invoked class [{}.{}] | Input Args -> {}", - joinPoint.getSignature().getDeclaringType().getSimpleName(), - joinPoint.getSignature().getName(), - List.of(joinPoint.getArgs()).isEmpty() ? "[EMPTY]" : joinPoint.getArgs()); - - final Object resultMethodExecution = joinPoint.proceed(); - - log.info("Invoked class [{}.{}] | Output Response -> {}", - joinPoint.getSignature().getDeclaringType().getSimpleName(), - joinPoint.getSignature().getName(), - resultMethodExecution); - - return resultMethodExecution; - } -} diff --git a/src/main/java/com/example/simple/config/SwaggerConfig.java b/src/main/java/com/example/simple/config/SpringFoxConfig.java similarity index 53% rename from src/main/java/com/example/simple/config/SwaggerConfig.java rename to src/main/java/com/example/simple/config/SpringFoxConfig.java index 4bbfffc..52c530d 100644 --- a/src/main/java/com/example/simple/config/SwaggerConfig.java +++ b/src/main/java/com/example/simple/config/SpringFoxConfig.java @@ -2,22 +2,27 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; +import org.springframework.web.bind.annotation.RestController; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration -@EnableSwagger2 -public class SwaggerConfig { +public class SpringFoxConfig { + +// @Bean +// public Docket api() { +// return new Docket(DocumentationType.SWAGGER_2) +// .select() +// .apis(RequestHandlerSelectors.basePackage("com.example.simple.web")) +// .build(); +// } @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) + .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) .build(); } } diff --git a/src/main/java/com/example/simple/domain/Simple.java b/src/main/java/com/example/simple/domain/Simple.java index 3f3bf58..88de7aa 100644 --- a/src/main/java/com/example/simple/domain/Simple.java +++ b/src/main/java/com/example/simple/domain/Simple.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.querydsl.core.annotations.QueryEntity; import lombok.Builder; import lombok.Data; import org.springframework.data.annotation.Id; @@ -13,7 +12,6 @@ @Data @Builder(toBuilder = true) -@QueryEntity @Document(collection = "#{@collections.getSimpleObjects()}") @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Simple { @@ -32,8 +30,6 @@ public class Simple { @JsonIgnore public boolean isEmpty() { - return (id == null || id.isEmpty()) - && (simpleId == null || simpleId.isEmpty()) - && (name == null || name.isEmpty()); + return (id == null || id.isEmpty()) && (simpleId == null || simpleId.isEmpty()) && (name == null || name.isEmpty()); } } diff --git a/src/main/java/com/example/simple/service/SimpleService.java b/src/main/java/com/example/simple/service/SimpleService.java index 7d7bf95..6afd95c 100644 --- a/src/main/java/com/example/simple/service/SimpleService.java +++ b/src/main/java/com/example/simple/service/SimpleService.java @@ -1,7 +1,6 @@ package com.example.simple.service; import com.example.simple.domain.Simple; -import com.example.simple.util.FunctionalException; import java.util.List; import java.util.Optional; @@ -10,9 +9,9 @@ public interface SimpleService { List findAllSimple(Optional name, Optional initialAge, Optional finalAge); - Simple findSimpleById(String simpleId) throws FunctionalException; + Simple findSimpleById(String simpleId); - void saveSimple(String simpleId, Simple simple) throws FunctionalException; + void saveSimple(String simpleId, Simple simple); - void deleteSimple(String simpleId) throws FunctionalException; + void deleteSimple(String simpleId); } diff --git a/src/main/java/com/example/simple/service/SimpleServiceImpl.java b/src/main/java/com/example/simple/service/SimpleServiceImpl.java index ef33b4f..8b53d92 100644 --- a/src/main/java/com/example/simple/service/SimpleServiceImpl.java +++ b/src/main/java/com/example/simple/service/SimpleServiceImpl.java @@ -2,9 +2,10 @@ import com.example.simple.domain.Simple; import com.example.simple.repository.SimpleRepository; -import com.example.simple.util.ExceptionEnum; -import com.example.simple.util.FunctionalException; +import com.github.d4rk3on.spring.mvc.util.ErrorEnum; +import com.github.d4rk3on.spring.mvc.util.exception.FunctionalException; import lombok.RequiredArgsConstructor; +import lombok.val; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -35,14 +36,6 @@ public List findAllSimple(Optional name, Optional initi return !CollectionUtils.isEmpty(simpleList) ? simpleList : List.of(); } - /** - * Evaluate the type of find we must launch based on the input parameters. - * - * @param name - * @param initialAge - * @param finalAge - * @return Type find we must execute. - */ private String evaluateFindRequest(Optional name, Optional initialAge, Optional finalAge) { if (name.isPresent() && (initialAge.isPresent() || finalAge.isPresent())) return FIND_BY_ALL_FILTERS; @@ -56,15 +49,6 @@ private String evaluateFindRequest(Optional name, Optional init return FIND_ALL; } - /** - * Execute the find method we must launch based on the requestType. - * - * @param requestType - * @param name - * @param initialAge - * @param finalAge - * @return Simple list. - */ private List executeFindRequest(String requestType, String name, Integer initialAge, Integer finalAge) { switch (requestType) { case FIND_ALL: @@ -76,49 +60,45 @@ private List executeFindRequest(String requestType, String name, Integer case FIND_BY_AGE: return simpleRepository.findAllByAgeBetween(initialAge, finalAge); default: - throw new FunctionalException("Error evaluating find request", ExceptionEnum.INTERNAL_SERVER_ERROR); + throw new FunctionalException("Error evaluating find request", ErrorEnum.INTERNAL_SERVER_ERROR); } } @Override - public Simple findSimpleById(String simpleId) throws FunctionalException { - final var simple = simpleRepository.findBySimpleId(simpleId).orElse(null); + public Simple findSimpleById(String simpleId) { + val simple = simpleRepository.findBySimpleId(simpleId).orElse(null); if (simple == null || simple.isEmpty()) throw new FunctionalException( - "Not valid findBySimpleId response", - ExceptionEnum.NO_DATA_FOUND, - "ID [".concat(simpleId).concat("] not exist")); + "Not valid findBySimpleId response", ErrorEnum.NO_DATA_FOUND, "ID [".concat(simpleId).concat("] not exist") + ); return simple; } @Override - public void saveSimple(String simpleId, Simple simple) throws FunctionalException { + public void saveSimple(String simpleId, Simple simple) { try { simpleRepository.save(simple.toBuilder().simpleId(simpleId).build()); } catch (DuplicateKeyException ex) { throw new FunctionalException( - ex.getMessage(), - ExceptionEnum.CONFLICT, - "Index : duplicate key [".concat(simpleId).concat("]") + ex.getMessage(), ErrorEnum.CONFLICT, "Index : duplicate key [".concat(simpleId).concat("]") ); } } @Override - public void deleteSimple(String simpleId) throws FunctionalException { + public void deleteSimple(String simpleId) { simpleRepository.delete(findSimpleToDeleteBySimpleId(simpleId)); } - private Simple findSimpleToDeleteBySimpleId(String simpleId) throws FunctionalException { - final var simple = simpleRepository.findBySimpleId(simpleId).orElse(null); + private Simple findSimpleToDeleteBySimpleId(String simpleId) { + val simple = simpleRepository.findBySimpleId(simpleId).orElse(null); if (simple == null || simple.isEmpty()) throw new FunctionalException( - "Resource to delete not found", - ExceptionEnum.NO_DATA_FOUND, - "ID [".concat(simpleId).concat("] not exist")); + "Resource to delete not found", ErrorEnum.NO_DATA_FOUND, "ID [".concat(simpleId).concat("] not exist") + ); return simple; } diff --git a/src/main/java/com/example/simple/util/ExceptionEnum.java b/src/main/java/com/example/simple/util/ExceptionEnum.java deleted file mode 100644 index 8ce4ad7..0000000 --- a/src/main/java/com/example/simple/util/ExceptionEnum.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.simple.util; - -import lombok.Getter; -import org.springframework.http.HttpStatus; - -public enum ExceptionEnum { - - CONFLICT(HttpStatus.CONFLICT, "The request could not be completed due to a conflict with the current state of the resource."), - FORBIDDEN(HttpStatus.FORBIDDEN, "Forbidden"), - INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Technical error in the system"), - INVALID_INPUT_PARAMETERS(HttpStatus.BAD_REQUEST, "Invalid input parameters"), - INVALID_REQUEST(HttpStatus.BAD_REQUEST, "Required request is missing"), - NO_AUTH_ACCESS(HttpStatus.UNAUTHORIZED, "Unauthorized"), - NO_AUTH_INFO(HttpStatus.NON_AUTHORITATIVE_INFORMATION, "Unauthorized"), - NO_CONTENT(HttpStatus.NO_CONTENT, "No content"), - NO_DATA_FOUND(HttpStatus.NOT_FOUND, "No data found"); - - @Getter - private HttpStatus httpStatus; - - @Getter - private String message; - - ExceptionEnum(final HttpStatus httpStatus, final String message) { - this.httpStatus = httpStatus; - this.message = message; - } -} diff --git a/src/main/java/com/example/simple/util/FunctionalException.java b/src/main/java/com/example/simple/util/FunctionalException.java deleted file mode 100644 index 2ffbf96..0000000 --- a/src/main/java/com/example/simple/util/FunctionalException.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.example.simple.util; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.ToString; - -@NoArgsConstructor -@ToString -public class FunctionalException extends RuntimeException { - - @Getter - private ExceptionEnum exceptionEnum; - - @Getter - private String detail; - - public FunctionalException(String message, ExceptionEnum exceptionEnum) { - super(message); - this.exceptionEnum = exceptionEnum; - } - - public FunctionalException(String message, ExceptionEnum exceptionEnum, String detail) { - super(message); - this.exceptionEnum = exceptionEnum; - this.detail = detail; - } -} diff --git a/src/main/java/com/example/simple/web/SimpleController.java b/src/main/java/com/example/simple/web/SimpleController.java index 9e62482..ad9de54 100644 --- a/src/main/java/com/example/simple/web/SimpleController.java +++ b/src/main/java/com/example/simple/web/SimpleController.java @@ -2,7 +2,6 @@ import com.example.simple.domain.Simple; import com.example.simple.service.SimpleService; -import com.example.simple.util.FunctionalException; import com.example.simple.web.response.SimpleResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -40,13 +39,12 @@ public SimpleResponse findAllSimple( } @GetMapping(path = "/{simpleId}") - public Simple findSimpleById(@PathVariable final String simpleId) throws FunctionalException { + public Simple findSimpleById(@PathVariable final String simpleId) { return simpleService.findSimpleById(simpleId); } @PutMapping(path = "/{simpleId}") - public ResponseEntity saveSimple(@PathVariable @NotEmpty final String simpleId, @RequestBody Simple simple) - throws FunctionalException { + public ResponseEntity saveSimple(@PathVariable @NotEmpty final String simpleId, @RequestBody Simple simple) { simpleService.saveSimple(simpleId, simple); return ResponseEntity.created( @@ -58,7 +56,7 @@ public ResponseEntity saveSimple(@PathVariable @NotEmpty final String simpleI } @DeleteMapping(path = "/{simpleId}") - public ResponseEntity deleteSimple(@PathVariable @NotEmpty final String simpleId) throws FunctionalException { + public ResponseEntity deleteSimple(@PathVariable @NotEmpty final String simpleId) { simpleService.deleteSimple(simpleId); return ResponseEntity.accepted().build(); diff --git a/src/main/java/com/example/simple/web/response/GlobalExceptionResponse.java b/src/main/java/com/example/simple/web/response/GlobalExceptionResponse.java deleted file mode 100644 index fce6394..0000000 --- a/src/main/java/com/example/simple/web/response/GlobalExceptionResponse.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.simple.web.response; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class GlobalExceptionResponse { - private int code; - private String message; - private String detail; -} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index c1a5cd2..e070d8a 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,7 +1,13 @@ server.port: 8080 +logging.level: + com.github.d4rk3on.spring.mvc: DEBUG + org.springframework: INFO + org.springframework.data: INFO + # MONGODB (MongoProperties) spring.data.mongodb: host: localhost port: 27017 database: example + diff --git a/src/main/resources/application-docker.yml b/src/main/resources/application-docker.yml index beaea72..4b5fc2a 100644 --- a/src/main/resources/application-docker.yml +++ b/src/main/resources/application-docker.yml @@ -1,5 +1,10 @@ server.port: 9080 +logging.level: + com.github.d4rk3on.spring.mvc: DEBUG + org.springframework: INFO + org.springframework.data: INFO + # MONGODB (MongoProperties) spring.data.mongodb: host: mongodb diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index ab93e2d..0000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - %green(%d{"yyyy-MM-dd HH:mm:ss,SSS"}) %highlight([%-5level]) %magenta([%thread]) %yellow([ %logger{36}:) %cyan(%line) %yellow(]) : %msg%n - - - - - - ${DEV_PATH}/resources/spring-boot-2-simple-example/logs/simple_example.log - - ${DEV_PATH}/resources/spring-boot-2-simple-example/logs/simple_example.%d{"yyyyMMdd"}.%i.log - - 5MB - - 40 - - - UTF-8 - - %d{"yyyy-MM-dd HH:mm:ss,SSS"} [%-5level] [%thread] [%logger{36}:%line] : %msg%n - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/java/com/example/simple/config/GlobalExceptionHandlerTest.java b/src/test/java/com/example/simple/config/GlobalExceptionHandlerTest.java deleted file mode 100644 index 44bbe65..0000000 --- a/src/test/java/com/example/simple/config/GlobalExceptionHandlerTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.example.simple.config; - -import com.example.simple.util.ExceptionEnum; -import com.example.simple.web.response.GlobalExceptionResponse; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class GlobalExceptionHandlerTest { - - private static final String PATH = "/test"; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Test - void testExceptionHandler() { - UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/exception")); - - final var response = testRestTemplate.getForEntity(builder.build().toUri(), GlobalExceptionResponse.class); - - assertAll( - () -> assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()), - () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.INTERNAL_SERVER_ERROR.getHttpStatus().value()) - .message(ExceptionEnum.INTERNAL_SERVER_ERROR.getMessage()) - .detail("Exception : Throw Exception") - .build(), response.getBody()) - ); - } - - @Test - void testConstraintViolationExceptionHandler() { - UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/constraintViolationException")); - - final var response = testRestTemplate.getForEntity(builder.build().toUri(), GlobalExceptionResponse.class); - - assertAll( - () -> assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()), - () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.INVALID_INPUT_PARAMETERS.getHttpStatus().value()) - .message(ExceptionEnum.INVALID_INPUT_PARAMETERS.getMessage()) - .detail("ConstraintViolationException : ") - .build(), response.getBody()) - ); - } - - @Test - void testHttpMessageNotReadableExceptionHandler() { - UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/httpMessageNotReadableException")); - - final var response = testRestTemplate.getForEntity(builder.build().toUri(), GlobalExceptionResponse.class); - - assertAll( - () -> assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()), - () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.INVALID_REQUEST.getHttpStatus().value()) - .message(ExceptionEnum.INVALID_REQUEST.getMessage()) - .detail("HttpMessageNotReadableException : Required request body is missing") - .build(), response.getBody()) - ); - } - - @Test - void testFunctionalExceptionHandler() { - UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/functionalException")); - - final var response = testRestTemplate.getForEntity(builder.build().toUri(), GlobalExceptionResponse.class); - - assertAll( - () -> assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()), - () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.INVALID_INPUT_PARAMETERS.getHttpStatus().value()) - .message(ExceptionEnum.INVALID_INPUT_PARAMETERS.getMessage()) - .detail("Testing functional exception") - .build(), response.getBody()) - ); - } -} \ No newline at end of file diff --git a/src/test/java/com/example/simple/config/LoggerAspectTest.java b/src/test/java/com/example/simple/config/LoggerAspectTest.java deleted file mode 100644 index 99fbb04..0000000 --- a/src/test/java/com/example/simple/config/LoggerAspectTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.example.simple.config; - -import lombok.AllArgsConstructor; -import lombok.ToString; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.reflect.MethodSignature; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.util.StringUtils; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class LoggerAspectTest { - - private static final String HEADER_TRACE = " : Invoked class [LoggerAspectTest$TestService$MockitoMock$"; - private static final String INPUT_TRACE = ".methodName] | Input Args -> [EMPTY]"; - private static final String OUTPUT_TRACE = ".methodName] | Output Response -> LoggerAspectTest.Response(id=00, name=Test)"; - - @Mock - private ProceedingJoinPoint joinPoint; - - @Mock - private MethodSignature signature; - - @Mock - private TestService testService; - - @InjectMocks - private LoggerAspect loggerAspect; - - @Test - void testPrintTraces() throws Throwable { - when(joinPoint.getTarget()).thenReturn(testService); - when(joinPoint.getSignature()).thenReturn(signature); - when(joinPoint.getSignature().getName()).thenReturn("methodName"); - when(joinPoint.getArgs()).thenReturn(new String[0]); - when(joinPoint.proceed()).thenReturn(new Response("00", "Test")); - - // Create a stream to hold the output - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - - PrintStream oldPrintStream = System.out; - - // Tell Java to use your special stream - System.setOut(new PrintStream(byteArrayOutputStream)); - - loggerAspect.printTraces(joinPoint); - - final var trace = byteArrayOutputStream.toString(); - - // Restore old output - System.setOut(oldPrintStream); - - // Print byteArrayOutputStream message in the console - System.out.println(trace); - - assertAll( - () -> assertEquals(2, StringUtils.countOccurrencesOf(trace, HEADER_TRACE)), - () -> assertTrue(trace.contains(INPUT_TRACE)), - () -> assertTrue(trace.contains(OUTPUT_TRACE)) - ); - } - - private interface TestService { - } - - @AllArgsConstructor - @ToString - private class Response { - private String id; - private String name; - } -} \ No newline at end of file diff --git a/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java b/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java index e396d94..8ac60d6 100644 --- a/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java +++ b/src/test/java/com/example/simple/repository/SimpleRepositoryTest.java @@ -5,6 +5,7 @@ import com.mongodb.BasicDBList; import com.mongodb.client.model.IndexOptions; import com.mongodb.client.model.Indexes; +import lombok.val; import org.apache.commons.io.FileUtils; import org.bson.BsonArray; import org.junit.jupiter.api.Test; @@ -41,19 +42,13 @@ class SimpleRepositoryTest { @Autowired private SimpleRepository simpleRepository; - /** - * Load the JSON file in the embed Mongodb. - * - * @param path - * @throws IOException - */ private void loadFileInMongodb(String path) throws IOException { mongoOperations.dropCollection(mongoDbCollectionsConfig.getSimpleObjects()); mongoOperations.getCollection(mongoDbCollectionsConfig.getSimpleObjects()) .createIndex(Indexes.ascending("simpleId"), new IndexOptions().unique(true)); - final var mongodbFile = FileUtils.readFileToString( + val mongodbFile = FileUtils.readFileToString( new ClassPathResource(path).getFile(), Charset.defaultCharset() ); @@ -70,7 +65,7 @@ private void loadFileInMongodb(String path) throws IOException { void findAllWhenExistData() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAll(); + val response = simpleRepository.findAll(); assertAll( () -> assertFalse(response.isEmpty()), @@ -83,7 +78,7 @@ void findAllWhenExistData() throws IOException { void findAllWhenNoExistData() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.empty.json"); - final var response = simpleRepository.findAll(); + val response = simpleRepository.findAll(); assertAll( () -> assertTrue(response != null && response.isEmpty()), @@ -95,7 +90,7 @@ void findAllWhenNoExistData() throws IOException { void findAllWhenNoExistCollection() { mongoOperations.dropCollection(mongoDbCollectionsConfig.getSimpleObjects()); - final var response = simpleRepository.findAll(); + val response = simpleRepository.findAll(); assertAll( () -> assertTrue(response != null && response.isEmpty()), @@ -107,7 +102,7 @@ void findAllWhenNoExistCollection() { void findBySimpleIdWhenExistData() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findBySimpleId("00"); + val response = simpleRepository.findBySimpleId("00"); assertAll( () -> assertTrue(response.isPresent()), @@ -123,7 +118,7 @@ void findBySimpleIdWhenExistData() throws IOException { void findBySimpleIdWhenNoDataFound() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findBySimpleId("unknown"); + val response = simpleRepository.findBySimpleId("unknown"); assertAll( () -> assertFalse(response.isPresent()), @@ -135,7 +130,7 @@ void findBySimpleIdWhenNoDataFound() throws IOException { void findByNameWhenExistData() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAllByNameIgnoreCaseLike("domi"); + val response = simpleRepository.findAllByNameIgnoreCaseLike("domi"); assertAll( () -> assertFalse(response.isEmpty()), @@ -151,7 +146,7 @@ void findByNameWhenExistData() throws IOException { void findByNameWhenNoDataFound() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAllByNameIgnoreCaseLike("unknown"); + val response = simpleRepository.findAllByNameIgnoreCaseLike("unknown"); assertAll( () -> assertTrue(response.isEmpty()), @@ -163,7 +158,7 @@ void findByNameWhenNoDataFound() throws IOException { void findBetweenAgesWhenExistData() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAllByAgeBetween(20, 28); + val response = simpleRepository.findAllByAgeBetween(20, 28); assertAll( () -> assertFalse(response.isEmpty()), @@ -180,7 +175,7 @@ void findBetweenAgesWhenExistData() throws IOException { void findBetweenAgesWhenNoDataFound() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAllByAgeBetween(20, 25); + val response = simpleRepository.findAllByAgeBetween(20, 25); assertAll( () -> assertTrue(response.isEmpty()), @@ -192,7 +187,7 @@ void findBetweenAgesWhenNoDataFound() throws IOException { void findByNameAndBetweenAgesWhenExistData() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAllByCustomFilters("dead", 28, 35); + val response = simpleRepository.findAllByCustomFilters("dead", 28, 35); assertAll( () -> assertFalse(response.isEmpty()), @@ -209,7 +204,7 @@ void findByNameAndBetweenAgesWhenExistData() throws IOException { void findByNameAndBetweenAgesWhenNoDataFound() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var response = simpleRepository.findAllByCustomFilters("Domi", 20, 30); + val response = simpleRepository.findAllByCustomFilters("Domi", 20, 30); assertAll( () -> assertTrue(response.isEmpty()), @@ -223,7 +218,7 @@ void saveWhenOk() throws IOException { simpleRepository.save(Simple.builder().simpleId("01").name("Testing").build()); - final var response = simpleRepository.findAll(); + val response = simpleRepository.findAll(); assertAll( () -> assertFalse(response.isEmpty()), @@ -244,7 +239,7 @@ void saveWhenIdAlreadyExist() throws IOException { void deleteWhenOk() throws IOException { loadFileInMongodb("mongodb/examples.simpleObjects.data.json"); - final var exampleToDelete = simpleRepository.findBySimpleId("00"); + val exampleToDelete = simpleRepository.findBySimpleId("00"); assertAll( () -> assertTrue(exampleToDelete.isPresent()), @@ -259,7 +254,7 @@ void deleteWhenOk() throws IOException { simpleRepository.delete(exampleToDelete.get()); - final var findDeleted = simpleRepository.findBySimpleId("00"); + val findDeleted = simpleRepository.findBySimpleId("00"); assertAll( () -> assertFalse(findDeleted.isPresent()), @@ -273,7 +268,7 @@ void deleteWhenElementNotExist() throws IOException { simpleRepository.delete(Simple.builder().id("unknown").id("000").name("Testing").build()); - final var findDeleted = simpleRepository.findBySimpleId("000"); + val findDeleted = simpleRepository.findBySimpleId("000"); assertAll( () -> assertFalse(findDeleted.isPresent()), diff --git a/src/test/java/com/example/simple/service/SimpleServiceTest.java b/src/test/java/com/example/simple/service/SimpleServiceTest.java index b6be0d6..a1ebad6 100644 --- a/src/test/java/com/example/simple/service/SimpleServiceTest.java +++ b/src/test/java/com/example/simple/service/SimpleServiceTest.java @@ -2,7 +2,8 @@ import com.example.simple.domain.Simple; import com.example.simple.repository.SimpleRepository; -import com.example.simple.util.FunctionalException; +import com.github.d4rk3on.spring.mvc.util.exception.FunctionalException; +import lombok.val; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -37,7 +38,7 @@ class SimpleServiceTest { void findAllSimpleWhenOk() { when(simpleRepository.findAll()).thenReturn(SIMPLE_LIST_OK); - final var response = simpleService.findAllSimple(Optional.empty(), Optional.empty(), Optional.empty()); + val response = simpleService.findAllSimple(Optional.empty(), Optional.empty(), Optional.empty()); assertAll( () -> assertTrue(response != null && !response.isEmpty()), @@ -50,7 +51,7 @@ void findAllSimpleWhenOk() { void findAllSimpleWhenNoDataFound() { when(simpleRepository.findAll()).thenReturn(List.of()); - final var emptyResponse = simpleService.findAllSimple(Optional.empty(), Optional.empty(), Optional.empty()); + val emptyResponse = simpleService.findAllSimple(Optional.empty(), Optional.empty(), Optional.empty()); assertAll( () -> assertTrue(emptyResponse != null && emptyResponse.isEmpty()), @@ -59,7 +60,7 @@ void findAllSimpleWhenNoDataFound() { when(simpleRepository.findAll()).thenReturn(null); - final var nullResponse = simpleService.findAllSimple(Optional.empty(), Optional.empty(), Optional.empty()); + val nullResponse = simpleService.findAllSimple(Optional.empty(), Optional.empty(), Optional.empty()); assertAll( () -> assertTrue(nullResponse != null && nullResponse.isEmpty()), @@ -72,7 +73,7 @@ void findAllSimpleByNameWhenOk() { when(simpleRepository.findAllByNameIgnoreCaseLike(SIMPLE_LIST_OK.get(0).getName())) .thenReturn(List.of(SIMPLE_LIST_OK.get(0))); - final var response = simpleService.findAllSimple( + val response = simpleService.findAllSimple( Optional.of(SIMPLE_LIST_OK.get(0).getName()), Optional.empty(), Optional.empty()); @@ -89,7 +90,7 @@ void findAllSimpleBetweenAgesWhenOk() { when(simpleRepository.findAllByAgeBetween(20, 30)) .thenReturn(List.of(SIMPLE_LIST_OK.get(4))); - final var response = simpleService.findAllSimple( + val response = simpleService.findAllSimple( Optional.empty(), Optional.of(20), Optional.of(30)); @@ -106,7 +107,7 @@ void findAllSimpleByNameAndBetweenAgesWhenOk() { when(simpleRepository.findAllByCustomFilters("pool", 20, 30)) .thenReturn(List.of(SIMPLE_LIST_OK.get(4))); - final var response = simpleService.findAllSimple( + val response = simpleService.findAllSimple( Optional.of("pool"), Optional.of(20), Optional.of(30)); @@ -127,7 +128,7 @@ void findSimpleByIdWhenExistData() { .name("Domino") .build())); - final var response = simpleService.findSimpleById("01"); + val response = simpleService.findSimpleById("01"); assertAll( () -> assertNotNull(response), diff --git a/src/test/java/com/example/simple/web/SimpleControllerTest.java b/src/test/java/com/example/simple/web/SimpleControllerTest.java index d16cb03..47daef6 100644 --- a/src/test/java/com/example/simple/web/SimpleControllerTest.java +++ b/src/test/java/com/example/simple/web/SimpleControllerTest.java @@ -2,10 +2,12 @@ import com.example.simple.domain.Simple; import com.example.simple.service.SimpleService; -import com.example.simple.util.ExceptionEnum; -import com.example.simple.util.FunctionalException; -import com.example.simple.web.response.GlobalExceptionResponse; import com.example.simple.web.response.SimpleResponse; +import com.github.d4rk3on.spring.mvc.model.Error; +import com.github.d4rk3on.spring.mvc.model.response.GlobalExceptionResponse; +import com.github.d4rk3on.spring.mvc.util.ErrorEnum; +import com.github.d4rk3on.spring.mvc.util.exception.FunctionalException; +import lombok.val; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -47,7 +49,7 @@ void findAllSimpleWhenOk() { UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH); - var response = testRestTemplate.getForEntity(builder.build().toUri(), SimpleResponse.class); + val response = testRestTemplate.getForEntity(builder.build().toUri(), SimpleResponse.class); assertAll( () -> assertEquals(HttpStatus.OK, response.getStatusCode()), @@ -70,7 +72,7 @@ void findAllSimpleWhenNoDataFound() { UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH); - final var response = testRestTemplate.getForEntity(builder.build().toUri(), SimpleResponse.class); + val response = testRestTemplate.getForEntity(builder.build().toUri(), SimpleResponse.class); assertAll( () -> assertEquals(HttpStatus.OK, response.getStatusCode()), @@ -91,7 +93,7 @@ void findSimpleByIdWhenOk() { UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/01")); - var response = testRestTemplate.getForEntity(builder.build().toUri(), Simple.class); + val response = testRestTemplate.getForEntity(builder.build().toUri(), Simple.class); assertAll( () -> assertEquals(HttpStatus.OK, response.getStatusCode()), @@ -105,21 +107,29 @@ void findSimpleByIdWhenNoDataFound() { when(simpleService.findSimpleById("00")) .thenThrow(new FunctionalException( "Not valid findBySimpleId response", - ExceptionEnum.NO_DATA_FOUND, + ErrorEnum.NO_DATA_FOUND, "ID [00] not exist")); UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/00")); - final var response = testRestTemplate.getForEntity(builder.build().toUri(), GlobalExceptionResponse.class); + val response = testRestTemplate.getForEntity(builder.build().toUri(), GlobalExceptionResponse.class); assertAll( () -> assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()), () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.NO_DATA_FOUND.getHttpStatus().value()) - .message(ExceptionEnum.NO_DATA_FOUND.getMessage()) - .detail("ID [00] not exist") - .build(), response.getBody()) + () -> assertEquals( + GlobalExceptionResponse.builder() + .errors( + Collections.singletonList( + Error.builder() + .httpStatus(ErrorEnum.NO_DATA_FOUND.getHttpStatus()) + .cause(ErrorEnum.NO_DATA_FOUND.getMessage()) + .message("Not valid findBySimpleId response >>> ID [00] not exist") + .build() + ) + ) + .build(), + response.getBody()) ); } @@ -137,7 +147,7 @@ void saveSimpleWhenOk() { } ); - final var response = testRestTemplate + val response = testRestTemplate .exchange(builder.build().toUri(), HttpMethod.PUT, request, ResponseEntity.class); assertAll( @@ -156,7 +166,7 @@ void saveSimpleWhenIdAlreadyExist() { doThrow( new FunctionalException( "Testing duplicate key exception in saveSimple method", - ExceptionEnum.CONFLICT, + ErrorEnum.CONFLICT, "Index : duplicate key [01]") ).when(simpleService).saveSimple(eq("01"), any(Simple.class)); @@ -170,17 +180,25 @@ void saveSimpleWhenIdAlreadyExist() { } ); - final var response = testRestTemplate + val response = testRestTemplate .exchange(builder.build().toUri(), HttpMethod.PUT, request, GlobalExceptionResponse.class); assertAll( () -> assertEquals(HttpStatus.CONFLICT, response.getStatusCode()), () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.CONFLICT.getHttpStatus().value()) - .message(ExceptionEnum.CONFLICT.getMessage()) - .detail("Index : duplicate key [01]") - .build(), response.getBody()) + () -> assertEquals( + GlobalExceptionResponse.builder() + .errors( + Collections.singletonList( + Error.builder() + .httpStatus(ErrorEnum.CONFLICT.getHttpStatus()) + .cause(ErrorEnum.CONFLICT.getMessage()) + .message("Testing duplicate key exception in saveSimple method >>> Index : duplicate key [01]") + .build() + ) + ) + .build(), + response.getBody()) ); } @@ -190,7 +208,7 @@ void deleteSimpleWhenOk() { UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/01")); - final var response = testRestTemplate + val response = testRestTemplate .exchange(builder.build().toUri(), HttpMethod.DELETE, HttpEntity.EMPTY, ResponseEntity.class); assertAll( @@ -204,23 +222,31 @@ void deleteSimpleWhenIdNotExist() { doThrow( new FunctionalException( "Resource to delete not found", - ExceptionEnum.NO_DATA_FOUND, + ErrorEnum.NO_DATA_FOUND, "ID [01] not exist") ).when(simpleService).deleteSimple(eq("01")); UriComponentsBuilder builder = UriComponentsBuilder.fromPath(PATH.concat("/01")); - final var response = testRestTemplate + val response = testRestTemplate .exchange(builder.build().toUri(), HttpMethod.DELETE, HttpEntity.EMPTY, GlobalExceptionResponse.class); assertAll( () -> assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()), () -> assertNotNull(response.getBody()), - () -> assertEquals(GlobalExceptionResponse.builder() - .code(ExceptionEnum.NO_DATA_FOUND.getHttpStatus().value()) - .message(ExceptionEnum.NO_DATA_FOUND.getMessage()) - .detail("ID [01] not exist") - .build(), response.getBody()) + () -> assertEquals( + GlobalExceptionResponse.builder() + .errors( + Collections.singletonList( + Error.builder() + .httpStatus(ErrorEnum.NO_DATA_FOUND.getHttpStatus()) + .cause(ErrorEnum.NO_DATA_FOUND.getMessage()) + .message("Resource to delete not found >>> ID [01] not exist") + .build() + ) + ) + .build(), + response.getBody()) ); } } \ No newline at end of file diff --git a/src/test/java/com/example/simple/web/TestController.java b/src/test/java/com/example/simple/web/TestController.java deleted file mode 100644 index d7b3df4..0000000 --- a/src/test/java/com/example/simple/web/TestController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example.simple.web; - -import com.example.simple.util.FunctionalException; -import com.example.simple.util.ExceptionEnum; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.validation.ConstraintViolationException; -import java.util.Collections; - -@RestController -@RequestMapping("/test") -public class TestController { - - @RequestMapping(value = "/exception", method = RequestMethod.GET) - public String testException() throws Exception { - throw new Exception("Throw Exception"); - } - - @RequestMapping(value = "/constraintViolationException", method = RequestMethod.GET) - public String testConstraintViolationException() throws ConstraintViolationException { - throw new ConstraintViolationException(Collections.EMPTY_SET); - } - - @RequestMapping(value = "/httpMessageNotReadableException", method = RequestMethod.GET) - public String httpMessageNotReadableException() throws HttpMessageNotReadableException { - throw new HttpMessageNotReadableException("Required request body is missing"); - } - - @RequestMapping(value = "/functionalException", method = RequestMethod.GET) - public String testFunctionalException() throws FunctionalException { - throw new FunctionalException("Throw FunctionalException", - ExceptionEnum.INVALID_INPUT_PARAMETERS, - "Testing functional exception"); - } -} diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 4d511c3..4d255f8 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -1,2 +1,7 @@ # MONGODB (MongoProperties) spring.data.mongodb.collections.simpleObjects: simpleObjects + +logging.level: + com.github.d4rk3on.spring.mvc: DEBUG + org.springframework: DEBUG + org.springframework.data: DEBUG \ No newline at end of file From 142e451e6fc0d3a417bcb3605a85179d9b162a8a Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Sun, 31 Jul 2022 13:58:51 +0200 Subject: [PATCH 3/3] new release 1.2.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index db02c72..3fca296 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ com.example simple - 1.1.2-SNAPSHOT + 1.2.0 [Spring Boot] Simple Example Spring Boot 2: Simple example