From 1116e83012f917d012026504ee4cf23859aa3d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Moitti=C3=A9?= Date: Wed, 20 Nov 2024 16:26:02 +0100 Subject: [PATCH] wip --- build.gradle | 6 +- .../letomodelizerapi/config/Constants.java | 4 + .../letomodelizerapi/config/JerseyConfig.java | 61 ---- .../controller/AIConfigurationController.java | 104 +++--- .../controller/AIController.java | 158 ++++----- .../controller/AISecretController.java | 96 +++--- .../controller/CsrfController.java | 23 +- .../controller/CurrentUserController.java | 133 ++++---- .../controller/DefaultController.java | 32 +- .../controller/GroupController.java | 245 ++++++-------- .../controller/HomeController.java | 48 +-- .../controller/LibraryController.java | 250 +++++++------- .../controller/PermissionController.java | 40 +-- .../controller/RoleController.java | 320 ++++++++---------- .../controller/ScopeController.java | 239 ++++++------- .../controller/UserController.java | 194 +++++------ .../handler/ApiExceptionHandler.java | 37 -- .../ConstraintViolationExceptionHandler.java | 80 ----- ...ataIntegrityViolationExceptionHandler.java | 49 --- .../handler/GlobalExceptionHandler.java | 179 ++++++++++ .../IllegalArgumentExceptionHandler.java | 39 --- .../controller/model/QueryFilter.java | 81 +++-- .../persistence/model/AIConfiguration.java | 10 +- .../persistence/model/AIConversation.java | 10 +- .../persistence/model/AIMessage.java | 6 +- .../persistence/model/AISecret.java | 6 +- .../persistence/model/AbstractEntity.java | 7 +- .../persistence/model/AccessControl.java | 8 +- .../model/AccessControlPermission.java | 8 +- .../model/AccessControlPermissionView.java | 16 +- .../persistence/model/AccessControlTree.java | 8 +- .../model/AccessControlTreeView.java | 18 +- .../persistence/model/Library.java | 16 +- .../persistence/model/LibraryTemplate.java | 16 +- .../persistence/model/Permission.java | 10 +- .../persistence/model/User.java | 12 +- .../persistence/model/UserAccessControl.java | 8 +- .../model/UserAccessControlView.java | 20 +- .../persistence/model/UserCsrfToken.java | 6 +- .../model/UserLibraryTemplateView.java | 20 +- .../persistence/model/UserLibraryView.java | 20 +- .../persistence/model/UserPermission.java | 14 +- .../repository/UserRepository.java | 2 + .../AccessControlTypePredicateFilter.java | 33 ++ .../CustomSpringQueryFilterSpecification.java | 33 ++ .../specification/PredicateOperator.java | 73 ---- .../specification/SpecificationHelper.java | 103 ------ .../filter/BooleanPredicateFilter.java | 30 -- .../filter/DatePredicateFilter.java | 162 --------- .../filter/EnumPredicateFilter.java | 29 -- .../specification/filter/FilterType.java | 56 --- .../filter/IPredicateFilter.java | 32 -- .../filter/NumberPredicateFilter.java | 87 ----- .../specification/filter/PredicateFilter.java | 266 --------------- .../filter/TextPredicateFilter.java | 46 --- .../filter/TokenPredicateFilter.java | 18 - .../filter/UUIDPredicateFilter.java | 32 -- .../specification/filter/package-info.java | 4 - .../specification/package-info.java | 2 +- .../service/AIConfigurationService.java | 7 +- .../service/AIConfigurationServiceImpl.java | 19 +- .../service/AISecretService.java | 9 +- .../service/AISecretServiceImpl.java | 29 +- .../letomodelizerapi/service/AIService.java | 22 +- .../service/AIServiceImpl.java | 71 ++-- .../AccessControlPermissionService.java | 9 +- .../AccessControlPermissionServiceImpl.java | 19 +- .../service/AccessControlService.java | 51 +-- .../service/AccessControlServiceImpl.java | 112 +++--- .../service/LibraryService.java | 27 +- .../service/LibraryServiceImpl.java | 41 +-- .../service/PermissionService.java | 9 +- .../service/PermissionServiceImpl.java | 17 +- .../service/UserPermissionService.java | 10 +- .../service/UserPermissionServiceImpl.java | 52 ++- .../letomodelizerapi/service/UserService.java | 9 +- .../service/UserServiceImpl.java | 17 +- .../config/JerseyConfigTest.java | 25 -- .../AIConfigurationControllerTest.java | 41 +-- .../controller/AIControllerTest.java | 67 ++-- .../controller/AISecretControllerTest.java | 35 +- .../controller/CsrfControllerTest.java | 5 +- .../controller/CurrentUserControllerTest.java | 44 +-- .../controller/DefaultControllerTest.java | 8 - .../controller/GroupControllerTest.java | 85 ++--- .../controller/HomeControllerTest.java | 21 +- .../controller/LibraryControllerTest.java | 92 +++-- .../controller/PermissionControllerTest.java | 11 +- .../controller/RoleControllerTest.java | 115 ++++--- .../controller/ScopeControllerTest.java | 79 +++-- .../controller/UserControllerTest.java | 69 ++-- .../handler/ApiExceptionHandlerTest.java | 29 -- ...nstraintViolationExceptionHandlerTest.java | 78 ----- ...ntegrityViolationExceptionHandlerTest.java | 45 --- .../handler/GlobalExceptionHandlerTest.java | 129 +++++++ .../IllegalArgumentExceptionHandlerTest.java | 25 -- .../controller/model/QueryFilterTest.java | 138 +++++--- .../cucumber/StepDefinitions.java | 112 +++--- .../letomodelizerapi/helper/MockHelper.java | 13 +- .../specification/PredicateOperatorTest.java | 45 --- .../SpecificationHelperTest.java | 79 ----- .../filter/BooleanPredicateFilterTest.java | 70 ---- .../filter/DatePredicateFilterTest.java | 196 ----------- .../filter/EnumPredicateFilterTest.java | 70 ---- .../filter/NumberPredicateFilterTest.java | 135 -------- .../filter/PredicateFilterTest.java | 116 ------- .../filter/TextPredicateFilterTest.java | 106 ------ .../filter/TokenPredicateFilterTest.java | 51 --- .../filter/UUIDPredicateFilterTest.java | 57 ---- .../AIConfigurationServiceImplTest.java | 3 +- .../service/AISecretServiceImplTest.java | 3 +- .../service/AIServiceImplTest.java | 10 +- ...ccessControlPermissionServiceImplTest.java | 4 +- .../service/AccessControlServiceImplTest.java | 12 +- .../service/LibraryServiceImplTest.java | 10 +- .../service/PermissionServiceImplTest.java | 4 +- .../UserPermissionServiceImplTest.java | 4 +- .../service/UserServiceImplTest.java | 4 +- 118 files changed, 2228 insertions(+), 4212 deletions(-) delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/config/JerseyConfig.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandler.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandler.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandler.java create mode 100644 src/main/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandler.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandler.java create mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/AccessControlTypePredicateFilter.java create mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/CustomSpringQueryFilterSpecification.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperator.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelper.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/FilterType.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/IPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilter.java delete mode 100644 src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/package-info.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/config/JerseyConfigTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandlerTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandlerTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandlerTest.java create mode 100644 src/test/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandlerTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandlerTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperatorTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelperTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilterTest.java delete mode 100644 src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilterTest.java diff --git a/build.gradle b/build.gradle index 7ef9ec20..2c670da8 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id 'com.adarshr.test-logger' version '4.0.0' id 'jacoco' id 'idea' - id "info.solidsoft.pitest" version "1.15.0" + id 'info.solidsoft.pitest' version '1.15.0' } idea { @@ -40,17 +40,17 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-jersey' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.session:spring-session-jdbc:3.3.3' implementation 'org.flywaydb:flyway-core:10.20.1' - implementation "org.flywaydb:flyway-database-postgresql:10.20.1" + implementation 'org.flywaydb:flyway-database-postgresql:10.20.1' implementation 'commons-lang:commons-lang:2.6' implementation 'commons-beanutils:commons-beanutils:1.9.4' implementation 'com.github.erosb:json-sKema:0.18.0' implementation 'com.hubspot.jinjava:jinjava:2.7.3' + implementation 'io.github.zorin95670:spring-query-filter:1.1.3' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.postgresql:postgresql:42.7.4' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/java/com/ditrit/letomodelizerapi/config/Constants.java b/src/main/java/com/ditrit/letomodelizerapi/config/Constants.java index 75d694af..251d6d8f 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/config/Constants.java +++ b/src/main/java/com/ditrit/letomodelizerapi/config/Constants.java @@ -4,6 +4,10 @@ * All constants value. */ public final class Constants { + /** + * Minimum resource size. + */ + public static final int MINIMUM_RESOURCE_SIZE = 1; /** * Maximum resource size. */ diff --git a/src/main/java/com/ditrit/letomodelizerapi/config/JerseyConfig.java b/src/main/java/com/ditrit/letomodelizerapi/config/JerseyConfig.java deleted file mode 100644 index 79922e9c..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/config/JerseyConfig.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.ditrit.letomodelizerapi.config; - -import com.ditrit.letomodelizerapi.controller.AIConfigurationController; -import com.ditrit.letomodelizerapi.controller.AIController; -import com.ditrit.letomodelizerapi.controller.AISecretController; -import com.ditrit.letomodelizerapi.controller.CsrfController; -import com.ditrit.letomodelizerapi.controller.CurrentUserController; -import com.ditrit.letomodelizerapi.controller.GroupController; -import com.ditrit.letomodelizerapi.controller.HomeController; -import com.ditrit.letomodelizerapi.controller.LibraryController; -import com.ditrit.letomodelizerapi.controller.PermissionController; -import com.ditrit.letomodelizerapi.controller.RoleController; -import com.ditrit.letomodelizerapi.controller.ScopeController; -import com.ditrit.letomodelizerapi.controller.UserController; -import com.ditrit.letomodelizerapi.controller.handler.ApiExceptionHandler; -import com.ditrit.letomodelizerapi.controller.handler.ConstraintViolationExceptionHandler; -import com.ditrit.letomodelizerapi.controller.handler.DataIntegrityViolationExceptionHandler; -import com.ditrit.letomodelizerapi.controller.handler.IllegalArgumentExceptionHandler; -import org.apache.commons.lang.StringUtils; -import org.glassfish.jersey.server.ResourceConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; - -/** - * Jersey configuration. - */ -@Configuration -public class JerseyConfig extends ResourceConfig { - - /** - * Default constructor to initialize registered endpoints and filters. - * @param aiHost the host value for ai request, injected from application properties. - */ - @Autowired - public JerseyConfig(@Value("${ai.host}") final String aiHost) { - // Filter - // Controller - register(UserController.class); - register(CurrentUserController.class); - register(RoleController.class); - register(GroupController.class); - register(ScopeController.class); - register(LibraryController.class); - register(HomeController.class); - register(CsrfController.class); - register(PermissionController.class); - register(AISecretController.class); - register(AIConfigurationController.class); - - if (StringUtils.isNotBlank(aiHost)) { - register(AIController.class); - } - - // Exception handler - register(ApiExceptionHandler.class); - register(ConstraintViolationExceptionHandler.class); - register(DataIntegrityViolationExceptionHandler.class); - register(IllegalArgumentExceptionHandler.class); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/AIConfigurationController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/AIConfigurationController.java index f8f2a7f2..4b448059 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/AIConfigurationController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/AIConfigurationController.java @@ -17,26 +17,23 @@ import jakarta.servlet.http.HttpSession; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -49,9 +46,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/ai/configurations") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/ai/configurations") @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class AIConfigurationController implements DefaultController { @@ -87,28 +83,27 @@ public class AIConfigurationController implements DefaultController { * based on the provided query parameters and pagination settings. * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. - * @param uriInfo UriInfo context to extract query parameters for filtering results. + * @param filters All query parameters for filtering results. * @param queryFilter bean parameter encapsulating filtering and pagination criteria. * @return a Response object containing the requested page of AIConfigurationDTO objects representing the * configurations. The status of the response can vary based on the outcome of the request. */ - @GET - public Response getAllConfigurations(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> getAllConfigurations( + final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_CONFIGURATION, ActionPermission.ACCESS); - Map filters = new HashMap<>(this.getFilters(uriInfo)); - log.info("[{}] Received GET request to get configurations with the following filters: {}", user.getLogin(), filters); - var resources = aiConfigurationService.findAll(filters, queryFilter.getPagination()) + var resources = aiConfigurationService.findAll(filters, queryFilter) .map(new BeanMapper<>(AIConfigurationDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -119,10 +114,9 @@ public Response getAllConfigurations(final @Context HttpServletRequest request, * @return a Response object containing theAIConfigurationDTO object representing the configuration. * The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}") - public Response getConfigurationById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}") + public ResponseEntity getConfigurationById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_CONFIGURATION, ActionPermission.ACCESS); @@ -131,9 +125,7 @@ public Response getConfigurationById(final @Context HttpServletRequest request, var aiConfiguration = aiConfigurationService.findById(id); - return Response.status(HttpStatus.OK.value()) - .entity(new BeanMapper<>(AIConfigurationDTO.class).apply(aiConfiguration)) - .build(); + return ResponseEntity.ok(new BeanMapper<>(AIConfigurationDTO.class).apply(aiConfiguration)); } /** @@ -149,9 +141,10 @@ public Response getConfigurationById(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the configuration creation. A successful operation returns * a status of CREATED. */ - @POST - public Response createConfiguration(final @Context HttpServletRequest request, - final @Valid AIConfigurationRecord aiConfigurationRecord) { + @PostMapping + public ResponseEntity createConfiguration( + final HttpServletRequest request, + final @Valid AIConfigurationRecord aiConfigurationRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, null, EntityPermission.AI_CONFIGURATION, ActionPermission.CREATE); @@ -164,9 +157,8 @@ public Response createConfiguration(final @Context HttpServletRequest request, aiService.sendConfiguration(configuration); - return Response.status(HttpStatus.CREATED.value()) - .entity(new BeanMapper<>(AIConfigurationDTO.class).apply(aiConfiguration)) - .build(); + return ResponseEntity.status(HttpStatus.CREATED.value()) + .body(new BeanMapper<>(AIConfigurationDTO.class).apply(aiConfiguration)); } /** @@ -182,9 +174,10 @@ public Response createConfiguration(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of configurations update. A successful operation returns * a status of OK. */ - @PUT - public Response updateConfiguration(final @Context HttpServletRequest request, - final @Valid List aiConfigurationRecords) { + @PutMapping + public ResponseEntity> updateConfiguration( + final HttpServletRequest request, + final @Valid List aiConfigurationRecords) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_CONFIGURATION, ActionPermission.UPDATE); @@ -212,9 +205,7 @@ public Response updateConfiguration(final @Context HttpServletRequest request, aiService.sendConfiguration(configuration); - return Response.status(HttpStatus.OK.value()) - .entity(configurations) - .build(); + return ResponseEntity.ok(configurations); } /** @@ -231,11 +222,11 @@ public Response updateConfiguration(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the configuration update. A successful operation returns * a status of OK. */ - @PUT - @Path("/{id}") - public Response updateConfiguration(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AIConfigurationRecord aiConfigurationRecord) { + @PutMapping("/{id}") + public ResponseEntity updateConfiguration( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AIConfigurationRecord aiConfigurationRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_CONFIGURATION, ActionPermission.UPDATE); @@ -247,9 +238,7 @@ public Response updateConfiguration(final @Context HttpServletRequest request, aiService.sendConfiguration(configuration); - return Response.status(HttpStatus.OK.value()) - .entity(new BeanMapper<>(AIConfigurationDTO.class).apply(aiConfiguration)) - .build(); + return ResponseEntity.ok(new BeanMapper<>(AIConfigurationDTO.class).apply(aiConfiguration)); } /** @@ -264,10 +253,9 @@ public Response updateConfiguration(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the deletion operation. A successful operation * returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}") - public Response deleteConfiguration(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/{id}") + public ResponseEntity deleteConfiguration(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_CONFIGURATION, ActionPermission.DELETE); @@ -283,6 +271,6 @@ public Response deleteConfiguration(final @Context HttpServletRequest request, aiConfigurationService.delete(id); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/AIController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/AIController.java index f3c42794..2f29b565 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/AIController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/AIController.java @@ -22,37 +22,35 @@ import jakarta.servlet.http.HttpSession; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.HttpHeaders; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.io.IOException; +import java.util.List; import java.util.Map; import java.util.UUID; /** * Controller to manage ai endpoint. */ -@Path("/ai") -@Produces(MediaType.APPLICATION_JSON) -@Controller @Slf4j +@RestController +@RequestMapping("/ai") +@ConditionalOnProperty(name = "ai.host", havingValue = "", matchIfMissing = false) @AllArgsConstructor(onConstructor = @__(@Autowired)) public class AIController implements DefaultController { @@ -90,10 +88,9 @@ public class AIController implements DefaultController { * @param aiCreateFileRecord the request details for the AI, validated to ensure it meets the expected format. * @return a Response object containing the AI's response in JSON format, with a status of CREATED (201). */ - @POST - @Path("/generate") - public Response generateFiles(final @Context HttpServletRequest request, - final @Valid AICreateFileRecord aiCreateFileRecord) { + @PostMapping("/generate") + public ResponseEntity generateFiles(final HttpServletRequest request, + final @Valid AICreateFileRecord aiCreateFileRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -102,10 +99,7 @@ public Response generateFiles(final @Context HttpServletRequest request, String json = aiService.createFile(aiCreateFileRecord); - return Response.status(HttpStatus.CREATED.value()) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) - .entity(json) - .build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(json); } /** @@ -117,10 +111,9 @@ public Response generateFiles(final @Context HttpServletRequest request, * @return a Response object containing the created AI conversation DTO with a status of CREATED (201). * @throws JsonProcessingException if there is an error processing the request data. */ - @POST - @Path("/conversations") - public Response createConversations(final @Context HttpServletRequest request, - final @Valid AIConversationRecord aiConversationRecord) + @PostMapping("/conversations") + public ResponseEntity createConversations(final HttpServletRequest request, + final @Valid AIConversationRecord aiConversationRecord) throws JsonProcessingException { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -131,35 +124,34 @@ public Response createConversations(final @Context HttpServletRequest request, AIConversationDTO dto = new BeanMapper<>(AIConversationDTO.class) .apply(aiService.createConversation(user, aiConversationRecord)); - return Response.status(HttpStatus.CREATED.value()).entity(dto).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(dto); } /** * Handles a GET request to retrieve all AI conversations with optional filtering and pagination. * This endpoint allows administrators to view all AI conversations. * - * @param request the HttpServletRequest used to access the user's session. - * @param uriInfo UriInfo object to retrieve query parameters. + * @param request the HttpServletRequest used to access the user's session. + * @param filters All query parameters for filtering results. * @param queryFilter the filter criteria and pagination information. * @return a Response object containing a paginated list of AIConversationDTOs. */ - @GET - @Path("/conversations") - public Response findAllConversations(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/conversations") + public ResponseEntity> findAllConversations( + final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get AI conversations with the following filters: {}", user.getLogin(), filters); - Page resources = aiService.findAllConversations(filters, queryFilter.getPagination()) + Page resources = aiService.findAllConversations(filters, queryFilter) .map(new BeanMapper<>(AIConversationDTO.class)); - return Response.status(getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -170,10 +162,9 @@ public Response findAllConversations(final @Context HttpServletRequest request, * @param id the ID of the AI conversation to retrieve. * @return a Response object containing the AIConversationDTO with a status of OK (200). */ - @GET - @Path("/conversations/{id}") - public Response getConversationById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/conversations/{id}") + public ResponseEntity getConversationById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -182,7 +173,7 @@ public Response getConversationById(final @Context HttpServletRequest request, AIConversationDTO dto = new BeanMapper<>(AIConversationDTO.class) .apply(aiService.getConversationById(user, id)); - return Response.status(HttpStatus.OK.value()).entity(dto).build(); + return ResponseEntity.ok(dto); } /** @@ -195,11 +186,11 @@ public Response getConversationById(final @Context HttpServletRequest request, * @return a Response object containing the updated AIConversationDTO with a status of OK (200). * @throws JsonProcessingException if there is an error processing the request data. */ - @PUT - @Path("/conversations/{id}") - public Response updateConversationById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AIConversationRecord aiConversationRecord) + @PutMapping("/conversations/{id}") + public ResponseEntity updateConversationById( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AIConversationRecord aiConversationRecord) throws JsonProcessingException { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -210,7 +201,7 @@ public Response updateConversationById(final @Context HttpServletRequest request AIConversationDTO dto = new BeanMapper<>(AIConversationDTO.class) .apply(aiService.updateConversationById(user, id, aiConversationRecord)); - return Response.status(HttpStatus.OK.value()).entity(dto).build(); + return ResponseEntity.ok(dto); } /** @@ -221,10 +212,9 @@ public Response updateConversationById(final @Context HttpServletRequest request * @param id the ID of the AI conversation to delete. * @return a Response object with a status of NO CONTENT (204) upon successful deletion. */ - @DELETE - @Path("/conversations/{id}") - public Response deleteConversationById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/conversations/{id}") + public ResponseEntity deleteConversationById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -236,7 +226,7 @@ public Response deleteConversationById(final @Context HttpServletRequest request aiService.deleteConversationById(user, id); } - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -249,11 +239,11 @@ public Response deleteConversationById(final @Context HttpServletRequest request * @return a Response object containing the AI's reply in plain text with a status of CREATED (201). * @throws JsonProcessingException if there is an error processing the request data. */ - @POST - @Path("/conversations/{id}/messages") - public Response createConversationMessage(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AIMessageRecord aiMessage) throws IOException { + @PostMapping("/conversations/{id}/messages") + public ResponseEntity createConversationMessage(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AIMessageRecord aiMessage) + throws IOException { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -262,7 +252,7 @@ public Response createConversationMessage(final @Context HttpServletRequest requ AIMessageDTO aiMessageDTO = new AIMessageToDTOMapper().apply(aiService.sendMessage(user, id, aiMessage)); - return Response.status(HttpStatus.CREATED.value()).entity(aiMessageDTO).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(aiMessageDTO); } /** @@ -270,29 +260,27 @@ public Response createConversationMessage(final @Context HttpServletRequest requ * pagination. * This endpoint allows users to view the conversation history with AI. * - * @param request the HttpServletRequest used to access the user's session. - * @param id the ID of the AI conversation from which to retrieve messages. - * @param uriInfo UriInfo object to retrieve query parameters. + * @param request the HttpServletRequest used to access the user's session. + * @param id the ID of the AI conversation from which to retrieve messages. + * @param filters All query parameters for filtering results. * @param queryFilter the filter criteria and pagination information. * @return a Response object containing a paginated list of AIMessageDTOs. */ - @GET - @Path("/conversations/{id}/messages") - public Response findAllMessages(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/conversations/{id}/messages") + public ResponseEntity> findAllMessages(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get AI messages with conversation id {} with the following filters: {}", user.getLogin(), id.toString(), filters); - Page resources = aiService.findAllMessages(user, id, filters, queryFilter.getPagination()) + Page resources = aiService.findAllMessages(user, id, filters, queryFilter) .map(new AIMessageToDTOMapper()); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -303,12 +291,11 @@ public Response findAllMessages(final @Context HttpServletRequest request, * * @param request the {@link HttpServletRequest} containing the current HTTP request information, used to retrieve * the session details. - * @return a {@link Response} with a 204 (No Content) status, indicating the configuration was successfully sent - * to the AI proxy. + * @return a {@link ResponseEntity} with a 204 (No Content) status, indicating the configuration was successfully + * sent to the AI proxy. */ - @GET - @Path("/proxy/configuration") - public Response sendConfigurationToProxy(final @Context HttpServletRequest request) { + @GetMapping("/proxy/configuration") + public ResponseEntity sendConfigurationToProxy(final HttpServletRequest request) { HttpSession session = request.getSession(); log.info("[{}] Received GET request to send configuration to proxy", session.getAttribute(Constants.DEFAULT_USER_PROPERTY)); @@ -317,7 +304,7 @@ public Response sendConfigurationToProxy(final @Context HttpServletRequest reque aiService.sendConfiguration(configuration); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -328,12 +315,11 @@ public Response sendConfigurationToProxy(final @Context HttpServletRequest reque * * @param request the {@link HttpServletRequest} containing the current HTTP request information, used to retrieve * the session details and user information. - * @return a {@link Response} containing the configuration descriptions in the response body with a 200 (OK) status. - * If the user lacks permission, an appropriate error response will be returned. + * @return a {@link ResponseEntity} containing the configuration descriptions in the response body with a 200 (OK) + * status. If the user lacks permission, an appropriate error response will be returned. */ - @GET - @Path("/proxy/descriptions") - public Response retrieveConfigurationDescriptions(final @Context HttpServletRequest request) { + @GetMapping("/proxy/descriptions") + public ResponseEntity retrieveConfigurationDescriptions(final HttpServletRequest request) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_SECRET, ActionPermission.ACCESS); @@ -342,6 +328,6 @@ public Response retrieveConfigurationDescriptions(final @Context HttpServletRequ var descriptions = aiService.getConfigurationDescriptions(); - return Response.ok(descriptions).build(); + return ResponseEntity.ok(descriptions); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/AISecretController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/AISecretController.java index 13e170c2..eccacd1d 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/AISecretController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/AISecretController.java @@ -14,25 +14,23 @@ import jakarta.servlet.http.HttpSession; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; - -import java.util.HashMap; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; import java.util.Map; import java.util.UUID; @@ -43,9 +41,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/ai/secrets") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/ai/secrets") @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class AISecretController implements DefaultController { @@ -70,27 +67,25 @@ public class AISecretController implements DefaultController { * based on the provided query parameters and pagination settings. * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AISecretDTO objects representing the * secrets. The status of the response can vary based on the outcome of the request. */ - @GET - public Response getAllSecrets(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> getAllSecrets(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_SECRET, ActionPermission.ACCESS); - Map filters = new HashMap<>(this.getFilters(uriInfo)); - log.info("[{}] Received GET request to get secrets with the following filters: {}", user.getLogin(), filters); - var resources = aiSecretService.findAll(filters, queryFilter.getPagination()) + var resources = aiSecretService.findAll(filters, queryFilter) .map(new BeanMapper<>(AISecretDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -101,10 +96,9 @@ public Response getAllSecrets(final @Context HttpServletRequest request, * @return a Response object containing theAISecretDTO object representing the secret. * The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}") - public Response getSecretById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}") + public ResponseEntity getSecretById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_SECRET, ActionPermission.ACCESS); @@ -113,9 +107,7 @@ public Response getSecretById(final @Context HttpServletRequest request, var aiSecret = aiSecretService.findById(id); - return Response.status(HttpStatus.OK.value()) - .entity(new BeanMapper<>(AISecretDTO.class).apply(aiSecret)) - .build(); + return ResponseEntity.ok(new BeanMapper<>(AISecretDTO.class).apply(aiSecret)); } /** @@ -131,9 +123,9 @@ public Response getSecretById(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the secret creation. A successful operation returns * a status of CREATED. */ - @POST - public Response createSecret(final @Context HttpServletRequest request, - final @Valid AISecretRecord aiSecretRecord) { + @PostMapping + public ResponseEntity createSecret(final HttpServletRequest request, + final @Valid AISecretRecord aiSecretRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, null, EntityPermission.AI_SECRET, ActionPermission.CREATE); @@ -142,9 +134,8 @@ public Response createSecret(final @Context HttpServletRequest request, aiSecretRecord.key()); var aiSecret = aiSecretService.create(aiSecretRecord); - return Response.status(HttpStatus.CREATED.value()) - .entity(new BeanMapper<>(AISecretDTO.class).apply(aiSecret)) - .build(); + return ResponseEntity.status(HttpStatus.CREATED.value()) + .body(new BeanMapper<>(AISecretDTO.class).apply(aiSecret)); } /** @@ -161,11 +152,10 @@ public Response createSecret(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the secret update. A successful operation returns * a status of OK. */ - @PUT - @Path("/{id}") - public Response updateSecret(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AISecretRecord aiSecretRecord) { + @PutMapping("/{id}") + public ResponseEntity updateSecret(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AISecretRecord aiSecretRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_SECRET, ActionPermission.UPDATE); @@ -173,9 +163,8 @@ public Response updateSecret(final @Context HttpServletRequest request, log.info("[{}] Received PUT request to update secret {}", user.getLogin(), id.toString()); var aiSecret = aiSecretService.update(id, aiSecretRecord); - return Response.status(HttpStatus.OK.value()) - .entity(new BeanMapper<>(AISecretDTO.class).apply(aiSecret)) - .build(); + return ResponseEntity.status(HttpStatus.OK.value()) + .body(new BeanMapper<>(AISecretDTO.class).apply(aiSecret)); } /** @@ -189,10 +178,9 @@ public Response updateSecret(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the deletion operation. A successful operation * returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}") - public Response deleteSecret(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/{id}") + public ResponseEntity deleteSecret(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkPermission(user, "id", EntityPermission.AI_SECRET, ActionPermission.DELETE); @@ -200,6 +188,6 @@ public Response deleteSecret(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to delete secret {}", user.getLogin(), id); aiSecretService.delete(id); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/CsrfController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/CsrfController.java index 4939d7b2..7cef5740 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/CsrfController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/CsrfController.java @@ -9,25 +9,21 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.security.web.csrf.CsrfToken; -import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; /** * Controller to manage '/csrf' endpoint. */ @Slf4j -@Path("/csrf") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/csrf") @AllArgsConstructor(onConstructor = @__(@Autowired)) public class CsrfController { @@ -57,9 +53,8 @@ public class CsrfController { * @param request the HttpServletRequest from which to retrieve the current user session and CSRF token. * @return a Response object containing the UserCsrfTokenDTO, which includes the CSRF token details. */ - @GET - @Produces(MediaType.APPLICATION_JSON) - public Response getCsrfToken(final @Context HttpServletRequest request) { + @GetMapping + public ResponseEntity getCsrfToken(final HttpServletRequest request) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -76,6 +71,6 @@ public Response getCsrfToken(final @Context HttpServletRequest request) { token.setExpirationDate(userToken.getExpirationDate()); - return Response.ok(token).build(); + return ResponseEntity.ok(token); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/CurrentUserController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/CurrentUserController.java index 74712a2d..d36b397b 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/CurrentUserController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/CurrentUserController.java @@ -14,21 +14,18 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.validation.Valid; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.net.http.HttpResponse; import java.util.List; @@ -37,9 +34,8 @@ /** * Controller to manage all current user endpoints. */ -@Path("/users/me") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/users/me") @Slf4j public class CurrentUserController implements DefaultController { @@ -103,17 +99,14 @@ public CurrentUserController(final UserService userService, * @param request Http request to get session. * @return Response with user information. */ - @GET - public Response getMyInformation(final @Context HttpServletRequest request) { + @GetMapping + public ResponseEntity getMyInformation(final HttpServletRequest request) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); log.info("[{}] Received GET request to get current user information", user.getLogin()); - return Response - .status(HttpStatus.OK.value()) - .entity(new BeanMapper<>(UserDTO.class).apply(user)) - .build(); + return ResponseEntity.ok(new BeanMapper<>(UserDTO.class).apply(user)); } /** @@ -121,9 +114,8 @@ public Response getMyInformation(final @Context HttpServletRequest request) { * @param request Http request to get session. * @return Response with image in body. */ - @GET - @Path("/picture") - public Response getMyPicture(final @Context HttpServletRequest request) { + @GetMapping("/picture") + public ResponseEntity getMyPicture(final HttpServletRequest request) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); HttpResponse response = userService.getPicture(user); @@ -133,7 +125,14 @@ public Response getMyPicture(final @Context HttpServletRequest request) { log.info("[{}] Received GET request to get current user picture", user.getLogin()); - return Response.ok(response.body(), contentType).cacheControl(getCacheControl(userPictureCacheMaxAge)).build(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType(contentType)); + headers.setCacheControl(getCacheControl(userPictureCacheMaxAge)); + + return ResponseEntity + .ok() + .headers(headers) + .body(response.body()); } /** @@ -141,9 +140,8 @@ public Response getMyPicture(final @Context HttpServletRequest request) { * @param request Http request to get session. * @return Response with permissions. */ - @GET - @Path("/permissions") - public Response getMyPermissions(final @Context HttpServletRequest request) { + @GetMapping("/permissions") + public ResponseEntity> getMyPermissions(final HttpServletRequest request) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -154,7 +152,7 @@ public Response getMyPermissions(final @Context HttpServletRequest request) { .map(new BeanMapper<>(PermissionDTO.class)) .toList(); - return Response.ok(permissions).build(); + return ResponseEntity.ok(permissions); } /** @@ -164,19 +162,17 @@ public Response getMyPermissions(final @Context HttpServletRequest request) { * then fetches their roles using the AccessControlService. * * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of AccessControlDTO objects representing the roles of the current * user. */ - @GET - @Path("/roles") - public Response getMyRoles(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/roles") + public ResponseEntity> getMyRoles(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get current user roles with the following filters: {}", @@ -188,10 +184,10 @@ public Response getMyRoles(final @Context HttpServletRequest request, AccessControlType.ROLE, user, filters, - queryFilter.getPagination() + queryFilter ).map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -200,20 +196,18 @@ public Response getMyRoles(final @Context HttpServletRequest request, * The method uses the session information from the HttpServletRequest to identify the current user and * then fetches their roles using the AccessControlService. * - * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of AccessControlDTO objects representing the roles of the current * user. */ - @GET - @Path("/groups") - public Response getMyGroups(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/groups") + public ResponseEntity> getMyGroups(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get current user groups with the following filters: {}", @@ -225,10 +219,10 @@ public Response getMyGroups(final @Context HttpServletRequest request, AccessControlType.GROUP, user, filters, - queryFilter.getPagination() + queryFilter ).map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -237,20 +231,18 @@ public Response getMyGroups(final @Context HttpServletRequest request, * The method uses the session information from the HttpServletRequest to identify the current user and * then fetches their scopes using the AccessControlService. * - * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of AccessControlDTO objects representing the scopes of the current * user. */ - @GET - @Path("/scopes") - public Response getMyScopes(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/scopes") + public ResponseEntity> getMyScopes(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get current user scopes with the following filters: {}", @@ -262,10 +254,10 @@ public Response getMyScopes(final @Context HttpServletRequest request, AccessControlType.SCOPE, user, filters, - queryFilter.getPagination() + queryFilter ).map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -275,20 +267,19 @@ public Response getMyScopes(final @Context HttpServletRequest request, * The method uses the session information from the HttpServletRequest to identify the current user and * then fetches their AI conversations using the AIService. * - * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param request HttpServletRequest to access the HTTP session and thereby identify the current user. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of AIConversationDTO objects representing the AI conversation of * the current user. */ - @GET - @Path("/ai/conversations") - public Response getMyAIConversations(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/ai/conversations") + public ResponseEntity> getMyAIConversations( + final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get current user AI conversations with the following filters: {}", @@ -299,9 +290,9 @@ public Response getMyAIConversations(final @Context HttpServletRequest request, Page resources = aiService.findAll( user, filters, - queryFilter.getPagination() + queryFilter ).map(new BeanMapper<>(AIConversationDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/DefaultController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/DefaultController.java index 533d0777..f9cf7ea9 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/DefaultController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/DefaultController.java @@ -1,12 +1,10 @@ package com.ditrit.letomodelizerapi.controller; -import jakarta.ws.rs.core.CacheControl; -import jakarta.ws.rs.core.UriInfo; import org.springframework.data.domain.Page; +import org.springframework.http.CacheControl; import org.springframework.http.HttpStatus; -import java.util.Map; -import java.util.stream.Collectors; +import java.time.Duration; /** * Interface defining default controller behaviors. This interface provides common utility @@ -15,20 +13,6 @@ * the pagination details of a resource. */ public interface DefaultController { - /** - * Extracts filter parameters from the URI query parameters. - * This method is useful for parsing query parameters into a map, where each - * parameter name is mapped to its corresponding value. - * - * @param uriInfo URI information containing the query parameters. - * @return A map of query parameter names to their respective single value, - * extracted from the provided {@link UriInfo}. - */ - default Map getFilters(final UriInfo uriInfo) { - return uriInfo.getQueryParameters().entrySet().stream() - .map(entry -> Map.entry(entry.getKey(), entry.getValue().get(0))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } /** * Determines the appropriate HTTP status code based on the pagination details @@ -60,13 +44,11 @@ default int getStatus(final Page resources) { * no-store. */ default CacheControl getCacheControl(String maxAge) { - CacheControl cacheControl = new CacheControl(); - cacheControl.setNoCache(false); - cacheControl.setNoStore(false); - cacheControl.setPrivate(true); - cacheControl.setMustRevalidate(true); - cacheControl.setMaxAge(Integer.valueOf(maxAge)); + int maxAgeInSeconds = Integer.parseInt(maxAge); - return cacheControl; + return CacheControl + .maxAge(Duration.ofSeconds(maxAgeInSeconds)) + .cachePrivate() + .mustRevalidate(); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/GroupController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/GroupController.java index 47c9c7e5..77935805 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/GroupController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/GroupController.java @@ -1,6 +1,5 @@ package com.ditrit.letomodelizerapi.controller; -import com.ditrit.letomodelizerapi.config.Constants; import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.BeanMapper; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; @@ -21,26 +20,24 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; - +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; import java.util.Map; import java.util.UUID; @@ -51,9 +48,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/groups") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/groups") @AllArgsConstructor(onConstructor = @__(@Autowired)) public class GroupController implements DefaultController { @@ -81,25 +77,24 @@ public class GroupController implements DefaultController { * Finds and returns all groups based on the provided query filters. * * @param request HttpServletRequest to access the HTTP session - * @param uriInfo UriInfo to extract query parameters - * @param queryFilter BeanParam for pagination and filtering + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a page of AccessControlDTO objects */ - @GET - public Response findAll(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> findAll(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get groups with the following filters: {}", user.getLogin(), filters); Page resources = accessControlService - .findAll(AccessControlType.GROUP, filters, queryFilter.getPagination()) + .findAll(AccessControlType.GROUP, filters, queryFilter) .map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -109,10 +104,9 @@ public Response findAll(final @Context HttpServletRequest request, * @param id the ID of the group to retrieve * @return a Response containing the AccessControlDTO of the requested group */ - @GET - @Path("/{id}") - public Response getGroupById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}") + public ResponseEntity getGroupById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -121,7 +115,7 @@ public Response getGroupById(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.findById(AccessControlType.GROUP, id)); - return Response.ok(accessControlDTO).build(); + return ResponseEntity.ok(accessControlDTO); } /** @@ -131,9 +125,9 @@ public Response getGroupById(final @Context HttpServletRequest request, * @param accessControlRecord Data for creating the new group * @return a Response indicating the outcome of the creation operation */ - @POST - public Response createGroup(final @Context HttpServletRequest request, - final @Valid AccessControlRecord accessControlRecord) { + @PostMapping + public ResponseEntity createGroup(final HttpServletRequest request, + final @Valid AccessControlRecord accessControlRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -142,7 +136,7 @@ public Response createGroup(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.create(AccessControlType.GROUP, accessControlRecord)); - return Response.status(HttpStatus.CREATED.value()).entity(accessControlDTO).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(accessControlDTO); } /** @@ -153,11 +147,10 @@ public Response createGroup(final @Context HttpServletRequest request, * @param accessControlRecord Data for updating the group * @return a Response indicating the outcome of the update operation */ - @PUT - @Path("/{id}") - public Response updateGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AccessControlRecord accessControlRecord) { + @PutMapping("/{id}") + public ResponseEntity updateGroup(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AccessControlRecord accessControlRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -172,7 +165,7 @@ public Response updateGroup(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.update(AccessControlType.GROUP, id, accessControlRecord)); - return Response.ok(accessControlDTO).build(); + return ResponseEntity.ok(accessControlDTO); } /** @@ -182,10 +175,9 @@ public Response updateGroup(final @Context HttpServletRequest request, * @param id the ID of the group to delete * @return a Response indicating the outcome of the delete operation */ - @DELETE - @Path("/{id}") - public Response deleteGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/{id}") + public ResponseEntity deleteGroup(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -193,7 +185,7 @@ public Response deleteGroup(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to delete group with id {}", user.getLogin(), id); accessControlService.delete(AccessControlType.GROUP, id); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -203,22 +195,19 @@ public Response deleteGroup(final @Context HttpServletRequest request, * * @param request HttpServletRequest to access the HTTP session for authentication and authorization. * @param id the ID of the group for which users are to be retrieved. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of UserDTO objects associated with the group. */ - @GET - @Path("/{id}/users") - public Response getUsersByGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/users") + public ResponseEntity> getUsersByGroup(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get users of group {} with the following filters: {}", user.getLogin(), @@ -227,10 +216,10 @@ public Response getUsersByGroup(final @Context HttpServletRequest request, ); Page resources = accessControlService - .findAllUsers(AccessControlType.GROUP, id, filters, queryFilter.getPagination()) + .findAllUsers(AccessControlType.GROUP, id, filters, queryFilter) .map(new BeanMapper<>(UserDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -243,12 +232,10 @@ public Response getUsersByGroup(final @Context HttpServletRequest request, * @param login the login identifier of the user to associate with the group. * @return a Response indicating the outcome of the association operation. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/users") - public Response associateUser(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotBlank String login) { + @PostMapping("/{id}/users") + public ResponseEntity associateUser(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -256,7 +243,7 @@ public Response associateUser(final @Context HttpServletRequest request, log.info("[{}] Received POST request to associate group {} with user {}", user.getLogin(), id, login); accessControlService.associateUser(AccessControlType.GROUP, id, login); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -269,11 +256,10 @@ public Response associateUser(final @Context HttpServletRequest request, * @param login the login identifier of the user to dissociate from the group. * @return a Response indicating the outcome of the dissociation operation. */ - @DELETE - @Path("/{id}/users/{login}") - public Response dissociateUser(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login) { + @DeleteMapping("/{id}/users/{login}") + public ResponseEntity dissociateUser(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -281,7 +267,7 @@ public Response dissociateUser(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to dissociate group {} with user {}", user.getLogin(), id, login); accessControlService.dissociateUser(AccessControlType.GROUP, id, login); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -292,23 +278,21 @@ public Response dissociateUser(final @Context HttpServletRequest request, * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param id the ID of the group for which to retrieve sub-groups. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDirectDTO objects representing the * sub-groups of the specified group. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/groups") - public Response getSubGroupsOfGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/groups") + public ResponseEntity> getSubGroupsOfGroup( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get sub-groups of group {} with the following filters: {}", user.getLogin(), @@ -322,10 +306,10 @@ public Response getSubGroupsOfGroup(final @Context HttpServletRequest request, id, AccessControlType.GROUP, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -343,12 +327,10 @@ public Response getSubGroupsOfGroup(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the association operation. A successful operation returns * a status of CREATED. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/groups") - public Response associate(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotNull String subGroupId) { + @PostMapping("/{id}/groups") + public ResponseEntity associate(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotNull String subGroupId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -361,7 +343,7 @@ public Response associate(final @Context HttpServletRequest request, UUID.fromString(subGroupId) ); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -379,11 +361,10 @@ public Response associate(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the dissociation operation. A successful * operation returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}/groups/{subGroupId}") - public Response dissociate(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("subGroupId") @Valid @NotNull UUID subGroupId) { + @DeleteMapping("/{id}/groups/{subGroupId}") + public ResponseEntity dissociate(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull UUID subGroupId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -397,7 +378,7 @@ public Response dissociate(final @Context HttpServletRequest request, accessControlService.dissociate(AccessControlType.GROUP, id, AccessControlType.GROUP, subGroupId); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -411,25 +392,22 @@ public Response dissociate(final @Context HttpServletRequest request, * * @param request The HttpServletRequest providing context to access the HTTP session. * @param id The unique identifier of the group whose roles are being retrieved. - * @param uriInfo URI information for extracting query parameters to apply as filters. - * @param queryFilter A BeanParam object encapsulating pagination and filtering criteria to manage result set size - * and relevance. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return A Response object containing a paginated list of AccessControlDirectDTO objects representing the roles * associated with the specified group. The response includes pagination details and adheres to the * HTTP status code conventions to indicate the outcome of the request. */ - @GET - @Path("/{id}/roles") - public Response getRolesOfGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/roles") + public ResponseEntity> getRolesOfGroup( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get roles of group {} with the following filters: {}", user.getLogin(), @@ -442,10 +420,10 @@ public Response getRolesOfGroup(final @Context HttpServletRequest request, AccessControlType.GROUP, id, AccessControlType.ROLE, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -459,25 +437,22 @@ public Response getRolesOfGroup(final @Context HttpServletRequest request, * * @param request The HttpServletRequest providing context to access the HTTP session. * @param id The unique identifier of the group whose scopes are being retrieved. - * @param uriInfo URI information for extracting query parameters to apply as filters. - * @param queryFilter A BeanParam object encapsulating pagination and filtering criteria to manage result set size - * and relevance. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return A Response object containing a paginated list of AccessControlDirectDTO objects representing the scopes * associated with the specified group. The response includes pagination details and adheres to the * HTTP status code conventions to indicate the outcome of the request. */ - @GET - @Path("/{id}/scopes") - public Response getScopesOfGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/scopes") + public ResponseEntity> getScopesOfGroup( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get scopes of group {} with the following filters: {}", user.getLogin(), @@ -491,10 +466,10 @@ public Response getScopesOfGroup(final @Context HttpServletRequest request, id, AccessControlType.SCOPE, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -506,23 +481,21 @@ public Response getScopesOfGroup(final @Context HttpServletRequest request, * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param id the ID of the groups for which to retrieve permissions. Must be a valid and non-null Long * value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of PermissionDirectDTO objects representing the * permissions of the specified group. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/permissions") - public Response getPermissionsOfGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/permissions") + public ResponseEntity> getPermissionsOfGroup( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get permissions of group {} with the following filters: {}", user.getLogin(), @@ -532,10 +505,10 @@ public Response getPermissionsOfGroup(final @Context HttpServletRequest request, AccessControl accessControl = accessControlService.findById(AccessControlType.GROUP, id); Page resources = accessControlPermissionService - .findAll(accessControl.getId(), filters, queryFilter.getPagination()) + .findAll(accessControl.getId(), filters, queryFilter) .map(new AccessControlPermissionViewToPermissionDirectDTOFunction()); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/HomeController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/HomeController.java index 03194b93..fdc07a2e 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/HomeController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/HomeController.java @@ -5,17 +5,16 @@ import jakarta.annotation.security.PermitAll; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.io.InputStream; import java.net.URI; @@ -24,9 +23,8 @@ /** * Controller to manage '/' endpoint. */ -@Path("/") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/") @Slf4j public class HomeController { @@ -75,12 +73,12 @@ public HomeController(final UserService userService, * * @return A static page that redirects to LetoModelizer upon successful authentication. */ - @GET + @GetMapping @PermitAll - public Response home() { + public ResponseEntity home() { InputStream stream = this.getClass().getClassLoader().getResourceAsStream("index.html"); - return Response.ok(stream).type("text/html").build(); + return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(stream); } /** @@ -97,10 +95,9 @@ public Response home() { * This parameter dictates the target URL for redirection. * @return A Response object that redirects the user to the wanted application. */ - @GET - @Path("/redirect") - public Response redirect(final @Context HttpServletRequest request, - final @QueryParam("app") String app) throws URISyntaxException { + @GetMapping("/redirect") + public ResponseEntity redirect(final HttpServletRequest request, + final @RequestParam("app") String app) throws URISyntaxException { HttpSession session = request.getSession(); User user = userService.getFromSession(session); String url = letoModelizerUrl; @@ -111,7 +108,10 @@ public Response redirect(final @Context HttpServletRequest request, log.info("[{}] Received GET request to redirect to {}", user.getLogin(), url); - return Response.seeOther(new URI(url)).build(); + return ResponseEntity + .status(HttpStatus.SEE_OTHER) // Code de statut 303 + .location(new URI(url)) // URL de redirection + .build(); } /** @@ -123,9 +123,11 @@ public Response redirect(final @Context HttpServletRequest request, * * @return A Response object that redirects the user to the GitHub OAuth2 authorization endpoint. */ - @GET - @Path("/login") - public Response login() { - return Response.temporaryRedirect(URI.create("/api/oauth2/authorization/github")).build(); + @GetMapping("/login") + public ResponseEntity login() { + return ResponseEntity + .status(HttpStatus.FOUND) + .location(URI.create("/api/oauth2/authorization/github")) + .build(); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/LibraryController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/LibraryController.java index d8a159b3..69514b98 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/LibraryController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/LibraryController.java @@ -18,28 +18,29 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.HttpHeaders; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; +import org.springframework.http.ContentDisposition; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.net.http.HttpResponse; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -50,8 +51,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/libraries") -@Produces(MediaType.APPLICATION_JSON) +@RestController +@RequestMapping("/libraries") @Controller public class LibraryController implements DefaultController { @@ -114,30 +115,29 @@ public LibraryController(final UserService userService, * while others can only view libraries based on specific criteria. * * @param request the HttpServletRequest containing the session information to identify the user. - * @param uriInfo the UriInfo to extract query parameters for filters. - * @param queryFilter the query parameters encapsulated in a QueryFilter object for pagination and filtering. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing the list of libraries with status code and pagination details. */ - @GET - public Response findAll(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> findAll(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get libraries with the following filters: {}", user.getLogin(), filters); Page resources; if (userPermissionService.hasPermission(user, EntityPermission.LIBRARY, ActionPermission.ACCESS)) { - resources = libraryService.findAll(filters, queryFilter.getPagination()) + resources = libraryService.findAll(filters, queryFilter) .map(new BeanMapper<>(LibraryDTO.class)); } else { - resources = libraryService.findAll(user, filters, queryFilter.getPagination()) + resources = libraryService.findAll(user, filters, queryFilter) .map(new BeanMapper<>(LibraryDTO.class)); } - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -149,10 +149,9 @@ public Response findAll(final @Context HttpServletRequest request, * @param id the unique identifier of the library to be retrieved, validated for non-null value. * @return a Response object containing the library details if accessible, with an OK status. */ - @GET - @Path("/{id}") - public Response getLibraryById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}") + public ResponseEntity getLibraryById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkLibraryPermission(user, ActionPermission.ACCESS, id); @@ -160,7 +159,7 @@ public Response getLibraryById(final @Context HttpServletRequest request, log.info("[{}] Received GET request to get library with id {}", user.getLogin(), id); LibraryDTO library = new BeanMapper<>(LibraryDTO.class).apply(libraryService.findById(id)); - return Response.ok(library).build(); + return ResponseEntity.ok(library); } /** @@ -173,10 +172,9 @@ public Response getLibraryById(final @Context HttpServletRequest request, * @param id the unique identifier of the library whose icon is being retrieved, validated for non-null value. * @return a Response object containing the icon as a byte array and the appropriate content type. */ - @GET - @Path("/{id}/icon") - public Response getLibraryIcon(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}/icon") + public ResponseEntity getLibraryIcon(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkLibraryPermission(user, ActionPermission.ACCESS, id); @@ -184,11 +182,14 @@ public Response getLibraryIcon(final @Context HttpServletRequest request, log.info("[{}] Received GET request to get library icon with id {}", user.getLogin(), id); HttpResponse response = libraryService.getIcon(id); - String contentType = response.headers() - .firstValue(HttpHeaders.CONTENT_TYPE) - .orElse(MediaType.APPLICATION_OCTET_STREAM); - - return Response.ok(response.body(), contentType).cacheControl(getCacheControl(resourceCacheMaxAge)).build(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setCacheControl(getCacheControl(resourceCacheMaxAge)); + + return ResponseEntity + .ok() + .headers(headers) + .body(response.body()); } /** @@ -197,24 +198,25 @@ public Response getLibraryIcon(final @Context HttpServletRequest request, * additional filters provided through the URI and the QueryFilter bean to refine the search for templates. * It ensures that only templates associated with the specified library ID are fetched. * - * @param request the HttpServletRequest containing the session information to identify the user. - * @param uriInfo the UriInfo containing query parameters for additional filtering. - * @param queryFilter a QueryFilter bean containing pagination settings. - * @param id the unique identifier of the library whose templates are being retrieved, validated for non-null value. + * @param request the HttpServletRequest containing the session information to identify the user. + * @param id the unique identifier of the library whose templates are being retrieved, validated for + * non-null value. + * @param immutableFilters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing a page of LibraryTemplate entities associated with the library and matching * the specified filters and pagination settings. */ - @GET - @Path("/{id}/templates") - public Response getLibraryTemplates(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}/templates") + public ResponseEntity> getLibraryTemplates( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> immutableFilters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkLibraryPermission(user, ActionPermission.ACCESS, id); - Map filters = new HashMap<>(this.getFilters(uriInfo)); - filters.put("libraryId", id.toString()); + Map> filters = new HashMap<>(immutableFilters); + filters.put("libraryId", List.of(id.toString())); log.info( "[{}] Received GET request to get templates of library with id {} with the following filters: {}", @@ -223,9 +225,9 @@ public Response getLibraryTemplates(final @Context HttpServletRequest request, filters ); - Page resources = libraryService.findAllTemplates(filters, queryFilter.getPagination()); + Page resources = libraryService.findAllTemplates(filters, queryFilter); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -240,9 +242,10 @@ public Response getLibraryTemplates(final @Context HttpServletRequest request, * @return a Response object with the status set to CREATED and the newly created library as the entity. * @throws JsonProcessingException if there is an error processing the input library record. */ - @POST - public Response createLibrary(final @Context HttpServletRequest request, - final @Valid LibraryRecord libraryRecord) throws JsonProcessingException { + @PostMapping + public ResponseEntity createLibrary(final HttpServletRequest request, + final @Valid LibraryRecord libraryRecord) + throws JsonProcessingException { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkLibraryPermission(user, ActionPermission.CREATE, null); @@ -251,7 +254,7 @@ public Response createLibrary(final @Context HttpServletRequest request, LibraryDTO library = new BeanMapper<>(LibraryDTO.class) .apply(libraryService.create(libraryRecord, user.getLogin())); - return Response.status(HttpStatus.CREATED.value()).entity(library).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(library); } /** @@ -268,10 +271,9 @@ public Response createLibrary(final @Context HttpServletRequest request, * (204 status code) is returned if the validation is successful, indicating that the library at the specified URL * meets the required standards. */ - @POST - @Path("/validate") - public Response validateLibrary(final @Context HttpServletRequest request, - final @Valid @Pattern(regexp = ".+/index\\.json$") String url) { + @PostMapping("/validate") + public ResponseEntity validateLibrary(final HttpServletRequest request, + final @Valid @Pattern(regexp = ".+/index\\.json$") String url) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkLibraryPermission(user, ActionPermission.CREATE, null); @@ -279,7 +281,7 @@ public Response validateLibrary(final @Context HttpServletRequest request, log.info("[{}] Received POST request to validate a library with {}", user.getLogin(), url); libraryService.validateLibrary(url); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -294,11 +296,10 @@ public Response validateLibrary(final @Context HttpServletRequest request, * operation. * @throws JsonProcessingException if there is an error processing the new URL for the library. */ - @PUT - @Path("/{id}") - public Response updateLibrary(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @Pattern(regexp = ".+/index\\.json$") String url) + @PutMapping("/{id}") + public ResponseEntity updateLibrary(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid @Pattern(regexp = ".+/index\\.json$") String url) throws JsonProcessingException { HttpSession session = request.getSession(); User user = userService.getFromSession(session); @@ -307,7 +308,7 @@ public Response updateLibrary(final @Context HttpServletRequest request, log.info("[{}] Received PUT request to update a library {} with {}", user.getLogin(), id, url); libraryService.update(id, url); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -320,10 +321,9 @@ public Response updateLibrary(final @Context HttpServletRequest request, * @return a Response object with a status indicating that no content exists (successful deletion) after the * operation. */ - @DELETE - @Path("/{id}") - public Response deleteLibrary(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/{id}") + public ResponseEntity deleteLibrary(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkLibraryPermission(user, ActionPermission.DELETE, id); @@ -331,7 +331,7 @@ public Response deleteLibrary(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to delete library with id {}", user.getLogin(), id); libraryService.delete(id); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } @@ -340,19 +340,17 @@ public Response deleteLibrary(final @Context HttpServletRequest request, * Access is controlled based on the user's permissions. Users with access permission can view all library * templates, while others can only view library templates based on specific criteria. * - * @param request the HttpServletRequest containing the session information to identify the user. - * @param uriInfo the UriInfo to extract query parameters for filters. - * @param queryFilter the query parameters encapsulated in a QueryFilter object for pagination and filtering. + * @param request the HttpServletRequest containing the session information to identify the user. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing the list of library templates with status code and pagination details. */ - @GET - @Path("/templates") - public Response findAllTemplates(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/templates") + public ResponseEntity> findAllTemplates(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get library templates with the following filters: {}", @@ -363,12 +361,12 @@ public Response findAllTemplates(final @Context HttpServletRequest request, Page resources; if (userPermissionService.hasPermission(user, EntityPermission.LIBRARY, ActionPermission.ACCESS)) { - resources = libraryService.findAllTemplates(filters, queryFilter.getPagination()); + resources = libraryService.findAllTemplates(filters, queryFilter); } else { - resources = libraryService.findAllTemplates(user, filters, queryFilter.getPagination()); + resources = libraryService.findAllTemplates(user, filters, queryFilter); } - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -381,10 +379,9 @@ public Response findAllTemplates(final @Context HttpServletRequest request, * @param id the unique identifier of the library template being retrieved, validated for non-null value. * @return a Response object containing the LibraryTemplate entity if found and accessible by the user. */ - @GET - @Path("/templates/{id}") - public Response getTemplatesById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/templates/{id}") + public ResponseEntity getTemplatesById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); LibraryTemplate libraryTemplate = libraryService.getTemplateById(id); @@ -392,7 +389,7 @@ public Response getTemplatesById(final @Context HttpServletRequest request, log.info("[{}] Received GET request to get templates with id {}", user.getLogin(), id); - return Response.ok(libraryTemplate).build(); + return ResponseEntity.ok(libraryTemplate); } /** @@ -408,10 +405,9 @@ public Response getTemplatesById(final @Context HttpServletRequest request, * value. * @return a Response object containing the icon as a byte array and the appropriate content type. */ - @GET - @Path("/templates/{id}/icon") - public Response getTemplateIcon(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/templates/{id}/icon") + public ResponseEntity getTemplateIcon(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); LibraryTemplate libraryTemplate = libraryService.getTemplateById(id); @@ -420,11 +416,15 @@ public Response getTemplateIcon(final @Context HttpServletRequest request, log.info("[{}] Received GET request to get template icon with id {}", user.getLogin(), id); HttpResponse response = libraryService.getTemplateIcon(libraryTemplate); - String contentType = response.headers() - .firstValue(HttpHeaders.CONTENT_TYPE) - .orElse(MediaType.APPLICATION_OCTET_STREAM); - return Response.ok(response.body(), contentType).cacheControl(getCacheControl(resourceCacheMaxAge)).build(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setCacheControl(getCacheControl(resourceCacheMaxAge)); + + return ResponseEntity + .ok() + .headers(headers) + .body(response.body()); } /** @@ -441,11 +441,10 @@ public Response getTemplateIcon(final @Context HttpServletRequest request, * @param index the index of the schema within the template, validated to be non-null and minimum 0. * @return a Response object containing the schema as a byte array and the appropriate content type. */ - @GET - @Path("/templates/{id}/schemas/{index}") - public Response getTemplateSchema(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("index") @Valid @NotNull @Min(0) Long index) { + @GetMapping("/templates/{id}/schemas/{index}") + public ResponseEntity getTemplateSchema(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull @Min(0) Long index) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); LibraryTemplate libraryTemplate = libraryService.getTemplateById(id); @@ -459,15 +458,16 @@ public Response getTemplateSchema(final @Context HttpServletRequest request, ); HttpResponse response = libraryService.getTemplateSchema(libraryTemplate, index); - String contentType = response.headers() - .firstValue(HttpHeaders.CONTENT_TYPE) - .orElse(MediaType.APPLICATION_OCTET_STREAM); String fileName = libraryService.getFileName(true, libraryTemplate, index); - - return Response.ok(response.body(), contentType) - .header("Content-Disposition", String.format("filename=\"%s\"", fileName)) - .cacheControl(getCacheControl(resourceCacheMaxAge)) - .build(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentDisposition(ContentDisposition.builder("attachment").filename(fileName).build()); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setCacheControl(getCacheControl(resourceCacheMaxAge)); + + return ResponseEntity + .ok() + .headers(headers) + .body(response.body()); } /** @@ -484,11 +484,10 @@ public Response getTemplateSchema(final @Context HttpServletRequest request, * @param index the index of the file within the template, validated to be non-null and minimum 0. * @return a Response object containing the file as a byte array and the appropriate content type. */ - @GET - @Path("/templates/{id}/files/{index}") - public Response getTemplateFile(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("index") @Valid @NotNull @Min(0) Long index) { + @GetMapping("/templates/{id}/files/{index}") + public ResponseEntity getTemplateFile(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull @Min(0) Long index) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); LibraryTemplate libraryTemplate = libraryService.getTemplateById(id); @@ -497,14 +496,15 @@ public Response getTemplateFile(final @Context HttpServletRequest request, log.info("[{}] Received GET request to get template file with id {} and index {}", user.getLogin(), id, index); HttpResponse response = libraryService.getTemplateFile(libraryTemplate, index); - String contentType = response.headers() - .firstValue(HttpHeaders.CONTENT_TYPE) - .orElse(MediaType.APPLICATION_OCTET_STREAM); - String fileName = libraryService.getFileName(false, libraryTemplate, index); - - return Response.ok(response.body(), contentType) - .header("Content-Disposition", String.format("filename=\"%s\"", fileName)) - .cacheControl(getCacheControl(resourceCacheMaxAge)) - .build(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentDisposition(ContentDisposition.builder("attachment") + .filename(libraryTemplate.getFiles().get(index.intValue())).build()); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setCacheControl(getCacheControl(resourceCacheMaxAge)); + + return ResponseEntity + .ok() + .headers(headers) + .body(response.body()); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/PermissionController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/PermissionController.java index ac2f2308..cd44da1c 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/PermissionController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/PermissionController.java @@ -9,21 +9,18 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.validation.Valid; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.stereotype.Controller; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; import java.util.Map; /** @@ -32,9 +29,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/permissions") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/permissions") @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class PermissionController implements DefaultController { @@ -58,18 +54,18 @@ public class PermissionController implements DefaultController { * Only accessible by users with administrative permissions. * * @param request HttpServletRequest to access the HTTP session - * @param uriInfo UriInfo to extract query parameters - * @param queryFilter BeanParam for pagination and filtering + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a page of Permission objects */ - @GET - public Response findAll(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> findAll( + final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get permissions with the following filters: {}", @@ -77,8 +73,8 @@ public Response findAll(final @Context HttpServletRequest request, filters ); - Page resources = permissionService.findAll(filters, queryFilter.getPagination()); + Page resources = permissionService.findAll(filters, queryFilter); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/RoleController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/RoleController.java index 48f099b1..617a3069 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/RoleController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/RoleController.java @@ -1,6 +1,5 @@ package com.ditrit.letomodelizerapi.controller; -import com.ditrit.letomodelizerapi.config.Constants; import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.BeanMapper; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; @@ -25,27 +24,25 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -56,9 +53,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/roles") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/roles") @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class RoleController implements DefaultController { @@ -92,25 +88,24 @@ public class RoleController implements DefaultController { * Only accessible by users with administrative permissions. * * @param request HttpServletRequest to access the HTTP session - * @param uriInfo UriInfo to extract query parameters - * @param queryFilter BeanParam for pagination and filtering + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a page of AccessControlDTO objects */ - @GET - public Response findAll(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> findAll(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get roles with the following filters: {}", user.getLogin(), filters); Page resources = accessControlService - .findAll(AccessControlType.ROLE, filters, queryFilter.getPagination()) + .findAll(AccessControlType.ROLE, filters, queryFilter) .map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -121,10 +116,9 @@ public Response findAll(final @Context HttpServletRequest request, * @param id the ID of the role to retrieve * @return a Response containing the AccessControlDTO of the requested role */ - @GET - @Path("/{id}") - public Response getRoleById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}") + public ResponseEntity getRoleById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -133,7 +127,7 @@ public Response getRoleById(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.findById(AccessControlType.ROLE, id)); - return Response.ok(accessControlDTO).build(); + return ResponseEntity.ok(accessControlDTO); } /** @@ -144,9 +138,9 @@ public Response getRoleById(final @Context HttpServletRequest request, * @param accessControlRecord Data for creating the new role * @return a Response indicating the outcome of the creation operation */ - @POST - public Response createRole(final @Context HttpServletRequest request, - final @Valid AccessControlRecord accessControlRecord) { + @PostMapping + public ResponseEntity createRole(final HttpServletRequest request, + final @Valid AccessControlRecord accessControlRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -155,7 +149,7 @@ public Response createRole(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.create(AccessControlType.ROLE, accessControlRecord)); - return Response.status(HttpStatus.CREATED.value()).entity(accessControlDTO).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(accessControlDTO); } /** @@ -167,11 +161,10 @@ public Response createRole(final @Context HttpServletRequest request, * @param accessControlRecord Data for updating the role * @return a Response indicating the outcome of the update operation */ - @PUT - @Path("/{id}") - public Response updateRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AccessControlRecord accessControlRecord) { + @PutMapping("/{id}") + public ResponseEntity updateRole(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AccessControlRecord accessControlRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -187,7 +180,7 @@ public Response updateRole(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.update(AccessControlType.ROLE, id, accessControlRecord)); - return Response.ok(accessControlDTO).build(); + return ResponseEntity.ok(accessControlDTO); } /** @@ -198,10 +191,9 @@ public Response updateRole(final @Context HttpServletRequest request, * @param id the ID of the role to delete * @return a Response indicating the outcome of the delete operation */ - @DELETE - @Path("/{id}") - public Response deleteRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/{id}") + public ResponseEntity deleteRole(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -210,7 +202,7 @@ public Response deleteRole(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to delete role with id {}", user.getLogin(), id); accessControlService.delete(AccessControlType.ROLE, id); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -220,22 +212,20 @@ public Response deleteRole(final @Context HttpServletRequest request, * * @param request HttpServletRequest to access the HTTP session for authentication and authorization. * @param id the ID of the role for which users are to be retrieved. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of UserDTO objects associated with the role. */ - @GET - @Path("/{id}/users") - public Response getUsersByRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/users") + public ResponseEntity> getUsersByRole( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get users of role {} with the following filters: {}", user.getLogin(), @@ -244,10 +234,10 @@ public Response getUsersByRole(final @Context HttpServletRequest request, ); Page resources = accessControlService - .findAllUsers(AccessControlType.ROLE, id, filters, queryFilter.getPagination()) + .findAllUsers(AccessControlType.ROLE, id, filters, queryFilter) .map(new BeanMapper<>(UserDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -260,12 +250,10 @@ public Response getUsersByRole(final @Context HttpServletRequest request, * @param login the login identifier of the user to associate with the role. * @return a Response indicating the outcome of the association operation. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/users") - public Response associateUser(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotBlank String login) { + @PostMapping("/{id}/users") + public ResponseEntity associateUser(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -273,7 +261,7 @@ public Response associateUser(final @Context HttpServletRequest request, log.info("[{}] Received POST request to associate role {} with user {}", user.getLogin(), id, login); accessControlService.associateUser(AccessControlType.ROLE, id, login); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -286,11 +274,10 @@ public Response associateUser(final @Context HttpServletRequest request, * @param login the login identifier of the user to dissociate from the role. * @return a Response indicating the outcome of the dissociation operation. */ - @DELETE - @Path("/{id}/users/{login}") - public Response dissociateUser(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login) { + @DeleteMapping("/{id}/users/{login}") + public ResponseEntity dissociateUser(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -298,7 +285,7 @@ public Response dissociateUser(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to dissociate role {} with user {}", user.getLogin(), id, login); accessControlService.dissociateUser(AccessControlType.ROLE, id, login); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -309,23 +296,21 @@ public Response dissociateUser(final @Context HttpServletRequest request, * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param id the ID of the role for which to retrieve sub-roles. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDirectDTO objects representing the * sub-roles of the specified role. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/roles") - public Response getSubRolesOfRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/roles") + public ResponseEntity> getSubRolesOfRole( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get sub roles of role {} with the following filters: {}", user.getLogin(), @@ -339,10 +324,10 @@ public Response getSubRolesOfRole(final @Context HttpServletRequest request, id, AccessControlType.ROLE, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -360,12 +345,10 @@ public Response getSubRolesOfRole(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the association operation. A successful operation returns * a status of CREATED. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/roles") - public Response associate(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotNull String roleId) { + @PostMapping("/{id}/roles") + public ResponseEntity associate(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotNull String roleId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -374,7 +357,7 @@ public Response associate(final @Context HttpServletRequest request, log.info("[{}] Received POST request to associate role {} with role {}", user.getLogin(), id, roleId); accessControlService.associate(AccessControlType.ROLE, id, AccessControlType.ROLE, UUID.fromString(roleId)); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -392,11 +375,10 @@ public Response associate(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the dissociation operation. A successful * operation returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}/roles/{roleId}") - public Response dissociate(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("roleId") @Valid @NotNull UUID roleId) { + @DeleteMapping("/{id}/roles/{roleId}") + public ResponseEntity dissociate(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull UUID roleId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -405,7 +387,7 @@ public Response dissociate(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to dissociate role {} with role {}", user.getLogin(), id, roleId); accessControlService.dissociate(AccessControlType.ROLE, id, AccessControlType.ROLE, roleId); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -416,24 +398,23 @@ public Response dissociate(final @Context HttpServletRequest request, * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param id the ID of the role for which to retrieve sub-roles. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param immutableFilters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDirectDTO objects representing the * groups of the specified role. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/groups") - public Response getGroupsOfRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/groups") + public ResponseEntity> getGroupsOfRole( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> immutableFilters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - - Map filters = new HashMap<>(this.getFilters(uriInfo)); - filters.put("parentId", id.toString()); - filters.put("parentType", AccessControlType.ROLE.name()); + var filters = new HashMap<>(immutableFilters); + filters.put("parentId", List.of(id.toString())); + filters.put("parentType", List.of(AccessControlType.ROLE.name())); log.info( "[{}] Received GET request to get groups of role {} with the following filters: {}", @@ -448,10 +429,10 @@ public Response getGroupsOfRole(final @Context HttpServletRequest request, id, AccessControlType.GROUP, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -467,12 +448,10 @@ public Response getGroupsOfRole(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the association operation. A successful operation returns * a status of CREATED. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/groups") - public Response associateGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotNull String groupId) { + @PostMapping("/{id}/groups") + public ResponseEntity associateGroup(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotNull String groupId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -481,7 +460,7 @@ public Response associateGroup(final @Context HttpServletRequest request, log.info("[{}] Received POST request to associate role {} with group {}", user.getLogin(), id, groupId); accessControlService.associate(AccessControlType.ROLE, id, AccessControlType.GROUP, UUID.fromString(groupId)); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -498,11 +477,10 @@ public Response associateGroup(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the dissociation operation. A successful * operation returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}/groups/{groupId}") - public Response dissociateGroup(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("groupId") @Valid @NotNull UUID groupId) { + @DeleteMapping("/{id}/groups/{groupId}") + public ResponseEntity dissociateGroup(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull UUID groupId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -511,7 +489,7 @@ public Response dissociateGroup(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to dissociate role {} with group {}", user.getLogin(), id, groupId); accessControlService.dissociate(AccessControlType.ROLE, id, AccessControlType.GROUP, groupId); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -522,23 +500,21 @@ public Response dissociateGroup(final @Context HttpServletRequest request, * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param id the ID of the role for which to retrieve sub-roles. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDirectDTO objects representing the * permissions of the specified role. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/permissions") - public Response getPermissionsOfRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/permissions") + public ResponseEntity> getPermissionsOfRole( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get permissions of role {} with the following filters: {}", user.getLogin(), @@ -548,10 +524,10 @@ public Response getPermissionsOfRole(final @Context HttpServletRequest request, AccessControl accessControl = accessControlService.findById(AccessControlType.ROLE, id); Page resources = accessControlPermissionService - .findAll(accessControl.getId(), filters, queryFilter.getPagination()) + .findAll(accessControl.getId(), filters, queryFilter) .map(new AccessControlPermissionViewToPermissionDirectDTOFunction()); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -570,12 +546,10 @@ public Response getPermissionsOfRole(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the association operation. A successful operation returns * a status of CREATED. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/permissions") - public Response associatePermission(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotNull String permissionId) { + @PostMapping("/{id}/permissions") + public ResponseEntity associatePermission(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotNull String permissionId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -592,7 +566,7 @@ public Response associatePermission(final @Context HttpServletRequest request, Permission permission = permissionService.findById(UUID.fromString(permissionId)); accessControlPermissionService.associate(accessControl.getId(), permission.getId()); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -610,11 +584,10 @@ public Response associatePermission(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the dissociation operation. A successful * operation returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}/permissions/{permissionId}") - public Response dissociatePermission(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("permissionId") @Valid @NotNull UUID permissionId) { + @DeleteMapping("/{id}/permissions/{permissionId}") + public ResponseEntity dissociatePermission(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull UUID permissionId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -631,7 +604,7 @@ public Response dissociatePermission(final @Context HttpServletRequest request, Permission permission = permissionService.findById(permissionId); accessControlPermissionService.dissociate(accessControl.getId(), permission.getId()); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -642,24 +615,24 @@ public Response dissociatePermission(final @Context HttpServletRequest request, * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param id the ID of the role for which to retrieve scopes. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param immutableFilters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDirectDTO objects representing the * scopes of the specified role. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/scopes") - public Response getScopesOfRole(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/scopes") + public ResponseEntity> getScopesOfRole( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> immutableFilters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = new HashMap<>(this.getFilters(uriInfo)); - filters.put("parentId", id.toString()); - filters.put("parentType", AccessControlType.ROLE.name()); + var filters = new HashMap<>(immutableFilters); + filters.put("parentId", List.of(id.toString())); + filters.put("parentType", List.of(AccessControlType.ROLE.name())); log.info( "[{}] Received GET request to get scopes of role {} with the following filters: {}", @@ -674,10 +647,10 @@ public Response getScopesOfRole(final @Context HttpServletRequest request, id, AccessControlType.SCOPE, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -693,12 +666,10 @@ public Response getScopesOfRole(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the association operation. A successful operation returns * a status of CREATED. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/scopes") - public Response associateScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotNull String scopeId) { + @PostMapping("/{id}/scopes") + public ResponseEntity associateScope(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid @NotNull String scopeId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -707,7 +678,7 @@ public Response associateScope(final @Context HttpServletRequest request, log.info("[{}] Received POST request to associate role {} with scope {}", user.getLogin(), id, scopeId); accessControlService.associate(AccessControlType.ROLE, id, AccessControlType.SCOPE, UUID.fromString(scopeId)); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -724,11 +695,10 @@ public Response associateScope(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the dissociation operation. A successful * operation returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}/scopes/{scopeId}") - public Response dissociateScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("scopeId") @Valid @NotNull UUID scopeId) { + @DeleteMapping("/{id}/scopes/{scopeId}") + public ResponseEntity dissociateScope(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull UUID scopeId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -737,7 +707,7 @@ public Response dissociateScope(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to dissociate role {} with scope {}", user.getLogin(), id, scopeId); accessControlService.dissociate(AccessControlType.ROLE, id, AccessControlType.SCOPE, scopeId); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/ScopeController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/ScopeController.java index 853589f1..ca1bccb8 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/ScopeController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/ScopeController.java @@ -1,6 +1,5 @@ package com.ditrit.letomodelizerapi.controller; -import com.ditrit.letomodelizerapi.config.Constants; import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.BeanMapper; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; @@ -21,26 +20,24 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; - +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; import java.util.Map; import java.util.UUID; @@ -51,9 +48,8 @@ * Only accessible by users with administrative permissions. */ @Slf4j -@Path("/scopes") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/scopes") @AllArgsConstructor(onConstructor = @__(@Autowired)) public class ScopeController implements DefaultController { @@ -81,25 +77,24 @@ public class ScopeController implements DefaultController { * Finds and returns all scopes based on the provided query filters. * * @param request HttpServletRequest to access the HTTP session - * @param uriInfo UriInfo to extract query parameters - * @param queryFilter BeanParam for pagination and filtering + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a page of AccessControlDTO objects */ - @GET - public Response findAll(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> findAll(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get scopes with the following filters: {}", user.getLogin(), filters); Page resources = accessControlService - .findAll(AccessControlType.SCOPE, filters, queryFilter.getPagination()) + .findAll(AccessControlType.SCOPE, filters, queryFilter) .map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -109,10 +104,9 @@ public Response findAll(final @Context HttpServletRequest request, * @param id the ID of the scope to retrieve * @return a Response containing the AccessControlDTO of the requested scope */ - @GET - @Path("/{id}") - public Response getScopeById(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @GetMapping("/{id}") + public ResponseEntity getScopeById(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -121,7 +115,7 @@ public Response getScopeById(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.findById(AccessControlType.SCOPE, id)); - return Response.ok(accessControlDTO).build(); + return ResponseEntity.ok(accessControlDTO); } /** @@ -131,9 +125,9 @@ public Response getScopeById(final @Context HttpServletRequest request, * @param accessControlRecord Data for creating the new scope * @return a Response indicating the outcome of the creation operation */ - @POST - public Response createScope(final @Context HttpServletRequest request, - final @Valid AccessControlRecord accessControlRecord) { + @PostMapping + public ResponseEntity createScope(final HttpServletRequest request, + final @Valid AccessControlRecord accessControlRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -142,7 +136,7 @@ public Response createScope(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.create(AccessControlType.SCOPE, accessControlRecord)); - return Response.status(HttpStatus.CREATED.value()).entity(accessControlDTO).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).body(accessControlDTO); } /** @@ -153,11 +147,10 @@ public Response createScope(final @Context HttpServletRequest request, * @param accessControlRecord Data for updating the scope * @return a Response indicating the outcome of the update operation */ - @PUT - @Path("/{id}") - public Response updateScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid AccessControlRecord accessControlRecord) { + @PutMapping("/{id}") + public ResponseEntity updateScope(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid AccessControlRecord accessControlRecord) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -172,7 +165,7 @@ public Response updateScope(final @Context HttpServletRequest request, AccessControlDTO accessControlDTO = new BeanMapper<>(AccessControlDTO.class) .apply(accessControlService.update(AccessControlType.SCOPE, id, accessControlRecord)); - return Response.ok(accessControlDTO).build(); + return ResponseEntity.ok(accessControlDTO); } /** @@ -182,10 +175,9 @@ public Response updateScope(final @Context HttpServletRequest request, * @param id the ID of the scope to delete * @return a Response indicating the outcome of the delete operation */ - @DELETE - @Path("/{id}") - public Response deleteScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id) { + @DeleteMapping("/{id}") + public ResponseEntity deleteScope(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -193,7 +185,7 @@ public Response deleteScope(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to delete scope with id {}", user.getLogin(), id); accessControlService.delete(AccessControlType.SCOPE, id); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -201,24 +193,21 @@ public Response deleteScope(final @Context HttpServletRequest request, * This endpoint fetches and returns a paginated list of users associated with the given scope ID. * The method is accessible only to users with administrative permissions. * - * @param request HttpServletRequest to access the HTTP session for authentication and authorization. - * @param id the ID of the scope for which users are to be retrieved. - * @param uriInfo UriInfo to extract query parameters for additional filtering. - * @param queryFilter BeanParam object for pagination and filtering purposes. + * @param request HttpServletRequest to access the HTTP session for authentication and authorization. + * @param id the ID of the scope for which users are to be retrieved. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response containing a paginated list of UserDTO objects associated with the scope. */ - @GET - @Path("/{id}/users") - public Response getUsersByScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/users") + public ResponseEntity> getUsersByScope(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get users of scope {} with the following filters: {}", user.getLogin(), @@ -227,10 +216,10 @@ public Response getUsersByScope(final @Context HttpServletRequest request, ); Page resources = accessControlService - .findAllUsers(AccessControlType.SCOPE, id, filters, queryFilter.getPagination()) + .findAllUsers(AccessControlType.SCOPE, id, filters, queryFilter) .map(new BeanMapper<>(UserDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -243,12 +232,10 @@ public Response getUsersByScope(final @Context HttpServletRequest request, * @param login the login identifier of the user to associate with the scope. * @return a Response indicating the outcome of the association operation. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/users") - public Response associateUser(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotBlank String login) { + @PostMapping("/{id}/users") + public ResponseEntity associateUser(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestBody @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -256,7 +243,7 @@ public Response associateUser(final @Context HttpServletRequest request, log.info("[{}] Received POST request to associate scope {} with user {}", user.getLogin(), id, login); accessControlService.associateUser(AccessControlType.SCOPE, id, login); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -269,11 +256,10 @@ public Response associateUser(final @Context HttpServletRequest request, * @param login the login identifier of the user to dissociate from the scope. * @return a Response indicating the outcome of the dissociation operation. */ - @DELETE - @Path("/{id}/users/{login}") - public Response dissociateUser(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login) { + @DeleteMapping("/{id}/users/{login}") + public ResponseEntity dissociateUser(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -281,7 +267,7 @@ public Response dissociateUser(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to dissociate scope {} with user {}", user.getLogin(), id, login); accessControlService.dissociateUser(AccessControlType.SCOPE, id, login); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -290,25 +276,23 @@ public Response dissociateUser(final @Context HttpServletRequest request, *

This method processes a GET request to obtain groups associated with a given scope ID. It filters the * scopes based on the provided query parameters and pagination settings. * - * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. - * @param id the ID of the scope for which to retrieve sub-scopes. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. + * @param id the ID of the scope for which to retrieve sub-scopes. Must be a valid and non-null Long value. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDirectDTO objects representing the * groups of the specified scope. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/groups") - public Response getGroupsOfScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/groups") + public ResponseEntity> getGroupsOfScope( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get groups of scope {} with the following filters: {}", user.getLogin(), @@ -322,10 +306,10 @@ public Response getGroupsOfScope(final @Context HttpServletRequest request, id, AccessControlType.GROUP, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -341,12 +325,10 @@ public Response getGroupsOfScope(final @Context HttpServletRequest request, * @return a Response object indicating the outcome of the association operation. A successful operation returns * a status of CREATED. */ - @POST - @Consumes(MediaType.TEXT_PLAIN) - @Path("/{id}/groups") - public Response associate(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Valid @NotNull String groupId) { + @PostMapping("/{id}/groups") + public ResponseEntity associate(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @Valid @NotNull String groupId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -359,7 +341,7 @@ public Response associate(final @Context HttpServletRequest request, UUID.fromString(groupId) ); - return Response.status(HttpStatus.CREATED.value()).build(); + return ResponseEntity.status(HttpStatus.CREATED.value()).build(); } /** @@ -376,11 +358,10 @@ public Response associate(final @Context HttpServletRequest request, * @return a Response object with a status indicating the outcome of the dissociation operation. A successful * operation returns a status of NO_CONTENT. */ - @DELETE - @Path("/{id}/groups/{groupId}") - public Response dissociate(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @PathParam("groupId") @Valid @NotNull UUID groupId) { + @DeleteMapping("/{id}/groups/{groupId}") + public ResponseEntity dissociate(final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @PathVariable @Valid @NotNull UUID groupId) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -394,7 +375,7 @@ public Response dissociate(final @Context HttpServletRequest request, accessControlService.dissociate(AccessControlType.SCOPE, id, AccessControlType.SCOPE, groupId); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -406,27 +387,24 @@ public Response dissociate(final @Context HttpServletRequest request, * for a scope. It is particularly useful for managing and reviewing the roles and permissions assigned to a scope * within an access control system. * - * @param request The HttpServletRequest providing context to access the HTTP session. - * @param id The unique identifier of the scope whose roles are being retrieved. - * @param uriInfo URI information for extracting query parameters to apply as filters. - * @param queryFilter A BeanParam object encapsulating pagination and filtering criteria to manage result set size - * and relevance. + * @param request The HttpServletRequest providing context to access the HTTP session. + * @param id The unique identifier of the scope whose roles are being retrieved. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return A Response object containing a paginated list of AccessControlDirectDTO objects representing the roles * associated with the specified scope. The response includes pagination details and adheres to the * HTTP status code conventions to indicate the outcome of the request. */ - @GET - @Path("/{id}/roles") - public Response getRolesOfScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/roles") + public ResponseEntity> getRolesOfScope( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get roles of scope {} with the following filters: {}", user.getLogin(), @@ -440,10 +418,10 @@ public Response getRolesOfScope(final @Context HttpServletRequest request, id, AccessControlType.ROLE, filters, - queryFilter.getPagination() + queryFilter ); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -452,25 +430,24 @@ public Response getRolesOfScope(final @Context HttpServletRequest request, *

This method processes a GET request to obtain permissions associated with a given scope ID. It filters the * permissions based on the provided query parameters and pagination settings. * - * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. - * @param id the ID of the scopes for which to retrieve permissions. Must be a valid and non-null Long value. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. + * @param id the ID of the scopes for which to retrieve permissions. Must be a valid and non-null Long + * value. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of PermissionDirectDTO objects representing the * permissions of the specified scope. The status of the response can vary based on the outcome of the request. */ - @GET - @Path("/{id}/permissions") - public Response getPermissionsOfScope(final @Context HttpServletRequest request, - final @PathParam("id") @Valid @NotNull UUID id, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{id}/permissions") + public ResponseEntity> getPermissionsOfScope( + final HttpServletRequest request, + final @PathVariable @Valid @NotNull UUID id, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); - log.info( "[{}] Received GET request to get permissions of scope {} with the following filters: {}", user.getLogin(), @@ -480,10 +457,10 @@ public Response getPermissionsOfScope(final @Context HttpServletRequest request, AccessControl accessControl = accessControlService.findById(AccessControlType.SCOPE, id); Page resources = accessControlPermissionService - .findAll(accessControl.getId(), filters, queryFilter.getPagination()) + .findAll(accessControl.getId(), filters, queryFilter) .map(new AccessControlPermissionViewToPermissionDirectDTOFunction()); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/UserController.java b/src/main/java/com/ditrit/letomodelizerapi/controller/UserController.java index aac73aed..3c3f9ec0 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/UserController.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/UserController.java @@ -1,6 +1,5 @@ package com.ditrit.letomodelizerapi.controller; -import com.ditrit.letomodelizerapi.config.Constants; import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.BeanMapper; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; @@ -18,32 +17,31 @@ import jakarta.servlet.http.HttpSession; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; -import jakarta.ws.rs.BeanParam; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.UriInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; -import org.springframework.stereotype.Controller; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.net.http.HttpResponse; +import java.util.List; import java.util.Map; /** * Controller to manage all users endpoints. */ @Slf4j -@Path("/users") -@Produces(MediaType.APPLICATION_JSON) -@Controller +@RestController +@RequestMapping("/users") public class UserController implements DefaultController { /** @@ -102,24 +100,23 @@ public UserController(final UserService userService, * This endpoint requires the requesting user to have admin privileges. * * @param request The HTTP request containing the user's session. - * @param uriInfo URI information containing query parameters for filtering. - * @param queryFilter Bean parameter for valid query filters including pagination. - * @return A {@link Response} containing a paginated list of {@link UserDTO}. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. + * @return A {@link ResponseEntity} containing a paginated list of {@link UserDTO}. */ - @GET - public Response getUsers(final @Context HttpServletRequest request, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping + public ResponseEntity> getUsers(final HttpServletRequest request, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); - Map filters = this.getFilters(uriInfo); log.info("[{}] Received GET request to get users with the following filters: {}", user.getLogin(), filters); - Page resources = userService.findAll(filters, queryFilter.getPagination()) + Page resources = userService.findAll(filters, queryFilter) .map(new BeanMapper<>(UserDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -128,12 +125,11 @@ public Response getUsers(final @Context HttpServletRequest request, * * @param request The HTTP request containing the user's session. * @param login The login identifier of the user to retrieve. - * @return A {@link Response} containing the {@link UserDTO} of the requested user. + * @return A {@link ResponseEntity} containing the {@link UserDTO} of the requested user. */ - @GET - @Path("/{login}") - public Response getUserByLogin(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login) { + @GetMapping("/{login}") + public ResponseEntity getUserByLogin(final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -141,7 +137,7 @@ public Response getUserByLogin(final @Context HttpServletRequest request, log.info("[{}] Received GET request to get user with login {}", user.getLogin(), login); UserDTO userDTO = new BeanMapper<>(UserDTO.class).apply(userService.findByLogin(login)); - return Response.ok(userDTO).build(); + return ResponseEntity.ok(userDTO); } /** @@ -151,12 +147,11 @@ public Response getUserByLogin(final @Context HttpServletRequest request, * * @param request The HTTP request containing the user's session, used to verify administrative privileges. * @param login The login identifier of the user to be deleted. - * @return A {@link Response} with a status of 204 No Content on successful deletion of the user. + * @return A {@link ResponseEntity} with a status of 204 No Content on successful deletion of the user. */ - @DELETE - @Path("/{login}") - public Response deleteUserByLogin(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login) { + @DeleteMapping("/{login}") + public ResponseEntity deleteUserByLogin(final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login) { HttpSession session = request.getSession(); User user = userService.getFromSession(session); userPermissionService.checkIsAdmin(user, null); @@ -164,7 +159,7 @@ public Response deleteUserByLogin(final @Context HttpServletRequest request, log.info("[{}] Received DELETE request to delete user with login {}", user.getLogin(), login); userService.deleteByLogin(login); - return Response.noContent().build(); + return ResponseEntity.noContent().build(); } /** @@ -176,22 +171,21 @@ public Response deleteUserByLogin(final @Context HttpServletRequest request, * * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param login the login identifier of the user whose roles are being requested. Must be a valid, non-blank String. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDTO objects representing the roles * associated with the specified user. The response status varies based on the outcome of the request. */ - @GET - @Path("/{login}/roles") - public Response getRolesOfUser(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{login}/roles") + public ResponseEntity> getRolesOfUser( + final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User me = userService.getFromSession(session); userPermissionService.checkIsAdmin(me, null); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get roles of user {} with the following filters: {}", me.getLogin(), @@ -201,9 +195,9 @@ public Response getRolesOfUser(final @Context HttpServletRequest request, User user = userService.findByLogin(login); Page resources = accessControlService - .findAll(AccessControlType.ROLE, user, filters, queryFilter.getPagination()); + .findAll(AccessControlType.ROLE, user, filters, queryFilter); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -216,22 +210,20 @@ public Response getRolesOfUser(final @Context HttpServletRequest request, * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param login the login identifier of the user whose groups are being requested. Must be a valid, non-blank * String. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDTO objects representing the groups * associated with the specified user. The response status varies based on the outcome of the request. */ - @GET - @Path("/{login}/groups") - public Response getGroupsOfUser(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{login}/groups") + public ResponseEntity> getGroupsOfUser(final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User me = userService.getFromSession(session); userPermissionService.checkIsAdmin(me, null); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get groups of user {} with the following filters: {}", me.getLogin(), @@ -241,10 +233,10 @@ public Response getGroupsOfUser(final @Context HttpServletRequest request, User user = userService.findByLogin(login); Page resources = accessControlService - .findAll(AccessControlType.GROUP, user, filters, queryFilter.getPagination()) + .findAll(AccessControlType.GROUP, user, filters, queryFilter) .map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -257,20 +249,18 @@ public Response getGroupsOfUser(final @Context HttpServletRequest request, * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param login the login identifier of the user whose groups are being requested. Must be a valid, non-blank * String. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDTO objects representing the groups * associated with the specified user. The response status varies based on the outcome of the request. */ - @GET - @Path("/{login}/permissions") - public Response getPermissionsOfUser(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank - String login, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{login}/permissions") + public ResponseEntity> getPermissionsOfUser( + final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); - Map filters = this.getFilters(uriInfo); User me = userService.getFromSession(session); log.info( @@ -286,10 +276,10 @@ public Response getPermissionsOfUser(final @Context HttpServletRequest request, } Page resources = userPermissionService - .findAll(user, filters, queryFilter.getPagination()) + .findAll(user, filters, queryFilter) .map(new BeanMapper<>(PermissionDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -302,22 +292,21 @@ public Response getPermissionsOfUser(final @Context HttpServletRequest request, * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param login the login identifier of the user whose scopes are being requested. Must be a valid, non-blank * String. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDTO objects representing the scopes * associated with the specified user. The response status varies based on the outcome of the request. */ - @GET - @Path("/{login}/scopes") - public Response getScopesOfUser(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{login}/scopes") + public ResponseEntity> getScopesOfUser( + final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User me = userService.getFromSession(session); userPermissionService.checkIsAdmin(me, null); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get scopes of user {} with the following filters: {}", me.getLogin(), @@ -327,10 +316,10 @@ public Response getScopesOfUser(final @Context HttpServletRequest request, User user = userService.findByLogin(login); Page resources = accessControlService - .findAll(AccessControlType.SCOPE, user, filters, queryFilter.getPagination()) + .findAll(AccessControlType.SCOPE, user, filters, queryFilter) .map(new BeanMapper<>(AccessControlDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -343,21 +332,20 @@ public Response getScopesOfUser(final @Context HttpServletRequest request, * @param request the HttpServletRequest from which to obtain the HttpSession for user validation. * @param login the login identifier of the user whose scopes are being requested. Must be a valid, non-blank * String. - * @param uriInfo UriInfo context to extract query parameters for filtering results. - * @param queryFilter bean parameter encapsulating filtering and pagination criteria. + * @param filters All query parameters for filtering results. + * @param queryFilter the filter criteria and pagination information. * @return a Response object containing the requested page of AccessControlDTO objects representing the scopes * associated with the specified user. The response status varies based on the outcome of the request. */ - @GET - @Path("/{login}/ai/conversations") - public Response getAIConversationsOfUser(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login, - final @Context UriInfo uriInfo, - final @BeanParam @Valid QueryFilter queryFilter) { + @GetMapping("/{login}/ai/conversations") + public ResponseEntity> getAIConversationsOfUser( + final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login, + final @RequestParam Map> filters, + final @ModelAttribute QueryFilter queryFilter) { HttpSession session = request.getSession(); User me = userService.getFromSession(session); - Map filters = this.getFilters(uriInfo); log.info( "[{}] Received GET request to get AI conversations of user {} with the following filters: {}", me.getLogin(), @@ -371,10 +359,10 @@ public Response getAIConversationsOfUser(final @Context HttpServletRequest reque userPermissionService.checkIsAdmin(me, null); } - Page resources = aiService.findAll(user, filters, queryFilter.getPagination()) + Page resources = aiService.findAll(user, filters, queryFilter) .map(new BeanMapper<>(AIConversationDTO.class)); - return Response.status(this.getStatus(resources)).entity(resources).build(); + return ResponseEntity.status(this.getStatus(resources)).body(resources); } /** @@ -385,13 +373,12 @@ public Response getAIConversationsOfUser(final @Context HttpServletRequest reque * * @param request The HTTP request containing the user's session, used to check for administrative privileges. * @param login The login identifier of the user whose picture is being requested. - * @return A {@link Response} containing the user's profile picture as a byte array and the content type of the - * image. The response status and content type may vary based on the outcome of the request. + * @return A {@link ResponseEntity} containing the user's profile picture as a byte array and the content type of + * the image. The response status and content type may vary based on the outcome of the request. */ - @GET - @Path("/{login}/picture") - public Response getPictureOfUser(final @Context HttpServletRequest request, - final @PathParam(Constants.DEFAULT_USER_PROPERTY) @Valid @NotBlank String login) { + @GetMapping("/{login}/picture") + public ResponseEntity getPictureOfUser(final HttpServletRequest request, + final @PathVariable @Valid @NotBlank String login) { HttpSession session = request.getSession(); User me = userService.getFromSession(session); userPermissionService.checkIsAdmin(me, null); @@ -405,6 +392,13 @@ public Response getPictureOfUser(final @Context HttpServletRequest request, .firstValue("Content-Type") .orElse("application/octet-stream"); - return Response.ok(response.body(), contentType).cacheControl(getCacheControl(userPictureCacheMaxAge)).build(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType(contentType)); + headers.setCacheControl(getCacheControl(userPictureCacheMaxAge)); + + return ResponseEntity + .ok() + .headers(headers) + .body(response.body()); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandler.java b/src/main/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandler.java deleted file mode 100644 index 16a54483..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ApiException; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.ext.ExceptionMapper; -import jakarta.ws.rs.ext.Provider; -import lombok.extern.slf4j.Slf4j; - -/** - * Handle api exception and send appropriate response. - */ -@Provider -@Slf4j -public class ApiExceptionHandler implements ExceptionMapper { - - @Override - public final Response toResponse(final ApiException exception) { - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - - log.debug("General error", exception); - - try { - return Response.status(exception.getStatus().value()) - .entity(mapper.writeValueAsString(exception.getError())) - .type(MediaType.APPLICATION_JSON) - .build(); - } catch (Exception e) { - throw new ApiException(exception, ErrorType.INTERNAL_ERROR, exception.getError().getField()); - } - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandler.java b/src/main/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandler.java deleted file mode 100644 index 9a7e26c2..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandler.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ErrorDTO; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.validation.ConstraintViolation; -import jakarta.validation.ConstraintViolationException; -import jakarta.validation.Path; -import jakarta.ws.rs.ClientErrorException; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.ext.ExceptionMapper; -import jakarta.ws.rs.ext.Provider; - -import java.util.Iterator; -import java.util.Optional; - -/** - * Handle validation exception and send appropriate response. - */ -@Provider -public class ConstraintViolationExceptionHandler implements ExceptionMapper { - - @Override - public final Response toResponse(final ConstraintViolationException exception) { - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - Optional> opt = exception.getConstraintViolations().stream().findFirst(); - - if (opt.isEmpty()) { - return Response.status(Response.Status.BAD_REQUEST).build(); - } - - ConstraintViolation violation = opt.get(); - ErrorDTO error = new ErrorDTO(); - int status; - - error.setField(getLastPath(violation.getPropertyPath())); - - if (violation.getInvalidValue() == null) { - status = ErrorType.EMPTY_VALUE.getStatus().value(); - error.setCode(ErrorType.EMPTY_VALUE.getCode()); - error.setMessage(ErrorType.EMPTY_VALUE.getMessage()); - } else { - status = ErrorType.WRONG_VALUE.getStatus().value(); - error.setCode(ErrorType.WRONG_VALUE.getCode()); - error.setMessage(ErrorType.WRONG_VALUE.getMessage()); - error.setValue(violation.getInvalidValue().toString()); - } - - try { - return Response.status(status).entity(mapper.writeValueAsString(error)) - .type(MediaType.APPLICATION_JSON) - .build(); - } catch (JsonProcessingException e) { - throw new ClientErrorException(Response.Status.INTERNAL_SERVER_ERROR, e); - } - } - - /** - * Retrieves the last node's name in the given Path. - *

- * This method iterates through the entire Path, returning the name of the last node in the sequence. - *

- * @param path The Path object to be processed. - * @return The name of the last node in the Path. - */ - public String getLastPath(final Path path) { - Iterator iterator = path.iterator(); - Path.Node node = iterator.next(); - - while (iterator.hasNext()) { - node = iterator.next(); - } - return node.getName(); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandler.java b/src/main/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandler.java deleted file mode 100644 index 73d2d67f..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ErrorDTO; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.ws.rs.ClientErrorException; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.ext.ExceptionMapper; -import org.hibernate.exception.ConstraintViolationException; -import org.springframework.dao.DataIntegrityViolationException; - -/** - * Exception handler for handling {@link DataIntegrityViolationException}. - * This class implements the {@link ExceptionMapper} interface to provide a custom response - * when a {@link DataIntegrityViolationException} is thrown in the application. - * It maps the exception to a structured error response in JSON format. - */ -public class DataIntegrityViolationExceptionHandler implements ExceptionMapper { - - @Override - public final Response toResponse(final DataIntegrityViolationException exception) { - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - - int status = ErrorType.WRONG_VALUE.getStatus().value(); - ErrorDTO error = new ErrorDTO(); - error.setCode(ErrorType.WRONG_VALUE.getCode()); - error.setMessage(ErrorType.WRONG_VALUE.getMessage()); - - if (exception.contains(ConstraintViolationException.class)) { - ConstraintViolationException violation = (ConstraintViolationException) exception.getCause(); - error.setField("constraint"); - error.setValue(violation.getConstraintName()); - error.setCause(violation.getSQLException().getMessage()); - } - - try { - return Response.status(status).entity(mapper.writeValueAsString(error)) - .type(MediaType.APPLICATION_JSON) - .build(); - } catch (JsonProcessingException e) { - throw new ClientErrorException(Response.Status.INTERNAL_SERVER_ERROR, e); - } - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandler.java b/src/main/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandler.java new file mode 100644 index 00000000..7748c349 --- /dev/null +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandler.java @@ -0,0 +1,179 @@ +package com.ditrit.letomodelizerapi.controller.handler; + +import com.ditrit.letomodelizerapi.model.error.ApiException; +import com.ditrit.letomodelizerapi.model.error.ErrorDTO; +import com.ditrit.letomodelizerapi.model.error.ErrorType; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Path; +import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.Iterator; +import java.util.Optional; + +/** + * Handle api exception and send appropriate response. + */ +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + /** + * Handles {@link ApiException} by returning a JSON response with the error details and HTTP status. + * + * @param exception the {@link ApiException} to handle + * @return a {@link ResponseEntity} containing the serialized error details and HTTP status + * @throws ApiException if an error occurs during error serialization + */ + @ExceptionHandler(ApiException.class) + public final ResponseEntity handleApiException(final ApiException exception) { + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + + log.debug("General error", exception); + + try { + return ResponseEntity.status(exception.getStatus().value()) + .contentType(org.springframework.http.MediaType.APPLICATION_JSON) + .body(mapper.writeValueAsString(exception.getError())); + } catch (Exception e) { + throw new ApiException(exception, ErrorType.INTERNAL_ERROR, exception.getError().getField()); + } + } + + /** + * Handles {@link ConstraintViolationException} and sends a detailed error response. + * + * @param exception the {@link ConstraintViolationException} to handle + * @return a {@link ResponseEntity} containing the serialized error details and HTTP status + * @throws ApiException if an error occurs during error serialization + */ + @ExceptionHandler(ConstraintViolationException.class) + public final ResponseEntity handleConstraintViolationException( + final ConstraintViolationException exception) { + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + Optional> opt = exception.getConstraintViolations().stream().findFirst(); + + if (opt.isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST.value()).build(); + } + + ConstraintViolation violation = opt.get(); + ErrorDTO error = new ErrorDTO(); + int status; + + error.setField(getLastPath(violation.getPropertyPath())); + + if (violation.getInvalidValue() == null) { + status = ErrorType.EMPTY_VALUE.getStatus().value(); + error.setCode(ErrorType.EMPTY_VALUE.getCode()); + error.setMessage(ErrorType.EMPTY_VALUE.getMessage()); + } else { + status = ErrorType.WRONG_VALUE.getStatus().value(); + error.setCode(ErrorType.WRONG_VALUE.getCode()); + error.setMessage(ErrorType.WRONG_VALUE.getMessage()); + error.setValue(violation.getInvalidValue().toString()); + } + + try { + return ResponseEntity.status(status) + .contentType(MediaType.APPLICATION_JSON) + .body(mapper.writeValueAsString(error)); + } catch (JsonProcessingException e) { + throw new ApiException(e, ErrorType.INTERNAL_ERROR, null); + } + } + + /** + * Retrieves the last node's name in the given Path. + *

+ * This method iterates through the entire Path, returning the name of the last node in the sequence. + *

+ * @param path The Path object to be processed. + * @return The name of the last node in the Path. + */ + public String getLastPath(final Path path) { + Iterator iterator = path.iterator(); + Path.Node node = iterator.next(); + + while (iterator.hasNext()) { + node = iterator.next(); + } + return node.getName(); + } + + /** + * Handles {@link DataIntegrityViolationException} and sends a detailed error response. + * + * @param exception the {@link DataIntegrityViolationException} to handle + * @return a {@link ResponseEntity} containing the serialized error details and HTTP status + * @throws ApiException if an error occurs during error serialization + */ + @ExceptionHandler(DataIntegrityViolationException.class) + public final ResponseEntity handleDataIntegrityViolationException( + final DataIntegrityViolationException exception) { + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + + int status = ErrorType.WRONG_VALUE.getStatus().value(); + ErrorDTO error = new ErrorDTO(); + error.setCode(ErrorType.WRONG_VALUE.getCode()); + error.setMessage(ErrorType.WRONG_VALUE.getMessage()); + + if (exception.contains(org.hibernate.exception.ConstraintViolationException.class)) { + org.hibernate.exception.ConstraintViolationException violation = + (org.hibernate.exception.ConstraintViolationException) exception.getCause(); + error.setField("constraint"); + error.setValue(violation.getConstraintName()); + error.setCause(violation.getSQLException().getMessage()); + } + + try { + return ResponseEntity + .status(status) + .contentType(MediaType.APPLICATION_JSON) + .body(mapper.writeValueAsString(error)); + } catch (JsonProcessingException e) { + throw new ApiException(e, ErrorType.INTERNAL_ERROR, "constraint"); + } + } + + /** + * Handles {@link IllegalArgumentException} and sends a detailed error response. + * + * @param exception the {@link IllegalArgumentException} to handle + * @return a {@link ResponseEntity} containing the serialized error details and HTTP status + * @throws ApiException if an error occurs during error serialization + */ + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity handleIllegalArgumentException(final IllegalArgumentException exception) { + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + + ErrorDTO error = new ErrorDTO(); + error.setCode(ErrorType.WRONG_VALUE.getCode()); + error.setMessage(ErrorType.WRONG_VALUE.getMessage()); + error.setField("id"); + error.setCause(exception.getMessage()); + + try { + return ResponseEntity + .status(ErrorType.WRONG_VALUE.getStatus().value()) + .contentType(MediaType.APPLICATION_JSON) + .body(mapper.writeValueAsString(error)); + } catch (JsonProcessingException e) { + throw new ApiException(e, ErrorType.INTERNAL_ERROR, "id"); + } + } +} diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandler.java b/src/main/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandler.java deleted file mode 100644 index 2d182825..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ErrorDTO; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.ws.rs.ClientErrorException; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.ext.ExceptionMapper; - -/** - * Handle IllegalArgumentException on UUID error and send appropriate response. - */ -public class IllegalArgumentExceptionHandler implements ExceptionMapper { - - @Override - public Response toResponse(final IllegalArgumentException exception) { - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - - ErrorDTO error = new ErrorDTO(); - error.setCode(ErrorType.WRONG_VALUE.getCode()); - error.setMessage(ErrorType.WRONG_VALUE.getMessage()); - error.setField("id"); - error.setCause(exception.getMessage()); - - try { - return Response.status(ErrorType.WRONG_VALUE.getStatus().value()) - .entity(mapper.writeValueAsString(error)) - .type(MediaType.APPLICATION_JSON) - .build(); - } catch (JsonProcessingException e) { - throw new ClientErrorException(Response.Status.INTERNAL_SERVER_ERROR, e); - } - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/controller/model/QueryFilter.java b/src/main/java/com/ditrit/letomodelizerapi/controller/model/QueryFilter.java index 5685cf1e..8296bc3d 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/controller/model/QueryFilter.java +++ b/src/main/java/com/ditrit/letomodelizerapi/controller/model/QueryFilter.java @@ -2,12 +2,13 @@ import com.ditrit.letomodelizerapi.config.Constants; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.github.zorin95670.query.ISpringQueryFilter; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Pattern; -import jakarta.ws.rs.QueryParam; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.lang.StringUtils; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -20,19 +21,17 @@ @JsonIgnoreProperties(ignoreUnknown = true) @Data @NoArgsConstructor -public class QueryFilter { +public class QueryFilter implements ISpringQueryFilter { /** * The current page. */ - @QueryParam("page") @Min(0) private Integer page = 0; /** * The maximum size of resources. */ - @QueryParam("count") @Min(1) @Max(Constants.MAXIMUM_RESOURCE_SIZE) private Integer count = Constants.DEFAULT_RESOURCE_SIZE; @@ -40,40 +39,80 @@ public class QueryFilter { /** * Name of the field to sort. */ - @QueryParam("order") private String order; /** * Type of sort. Can be 'asc' or 'desc'. */ - @QueryParam("sort") @Pattern(regexp = "asc|desc") private String sort; - private Sort getOrderBy() { - if (sort == null) { - return null; + @Override + public int getComputedPage() { + return Math.max(Optional.ofNullable(page).orElse(0), 0); + } + + @Override + public int getComputedPageSize() { + return Math.clamp(Optional.ofNullable(getCount()) + .orElse(Constants.DEFAULT_RESOURCE_SIZE), + Constants.MINIMUM_RESOURCE_SIZE, + Constants.MAXIMUM_RESOURCE_SIZE); + } + + @Override + public boolean isAscendantSort() { + return "asc".equalsIgnoreCase(sort); + } + + /** + * Determines the {@link Sort.Direction} (ascending or descending) based on the provided sorting order. + * + *

This method first checks if a custom sort order has been specified. If so, it uses that order. + * Otherwise, it defaults to ascending or descending based on the provided {@code isAscending} flag. + * + * @param isAscending a boolean flag indicating whether the sorting order should be ascending. + * If no custom sort order is provided, this flag is used to determine the direction. + * @return {@link Sort.Direction#ASC} for ascending order, or {@link Sort.Direction#DESC} for descending order. + */ + public Sort.Direction getDirection(final boolean isAscending) { + if (StringUtils.isNotBlank(sort)) { + if (isAscendantSort()) { + return Sort.Direction.ASC; + } + return Sort.Direction.DESC; } - if ("asc".equalsIgnoreCase(sort)) { - return Sort.by(Sort.Direction.ASC, order); + if (isAscending) { + return Sort.Direction.ASC; } - return Sort.by(Sort.Direction.DESC, order); + + return Sort.Direction.DESC; } /** - * Create pagination from query parameters. + * Constructs a {@link Pageable} object based on the provided sorting order and the current pagination parameters. + * + *

This method creates a {@link PageRequest} with sorting directions and the provided field names. + * If a custom sorting order is already set, it is used; otherwise, the method uses the provided + * {@code isAsc} flag to determine the sorting direction. * - * @return Page options. + * @param isAsc a boolean flag indicating whether the sorting should be ascending or descending. + * If {@code true}, the sorting will be ascending; if {@code false}, descending. + * @param orders a variable number of string parameters representing the field names to sort by. + * @return a {@link Pageable} object with the appropriate page size, page number, and sort order. */ - public final Pageable getPagination() { - Sort sortOption = getOrderBy(); - int pageNumber = Optional.ofNullable(this.page).orElse(0); - int countNumber = Optional.ofNullable(this.count).orElse(Constants.DEFAULT_RESOURCE_SIZE); + public Pageable getPageable(final boolean isAsc, final String... orders) { + Sort currentSort = this.getOrderBy(null); - if (sortOption != null) { - return PageRequest.of(pageNumber, countNumber, sortOption); + if (sort != null) { + return PageRequest.of(this.getComputedPage(), this.getComputedPageSize(), currentSort); } - return PageRequest.of(pageNumber, countNumber); + + return PageRequest.of( + this.getComputedPage(), + this.getComputedPageSize(), + Sort.by(getDirection(isAsc), orders) + ); } } diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConfiguration.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConfiguration.java index 7b9025a7..98769828 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConfiguration.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConfiguration.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -30,28 +30,28 @@ public class AIConfiguration extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "acf_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The configuration handler. */ @Column(name = "handler") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String handler; /** * The configuration key. */ @Column(name = "key") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String key; /** * The value of the configuration. */ @Column(name = "value") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String value; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConversation.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConversation.java index 2a443d7e..df534665 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConversation.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIConversation.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -32,21 +32,21 @@ public class AIConversation extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "aic_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The login identifier of the user to whom the conversation is associated. */ @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID userId; /** * The conversation key. */ @Column(name = "key") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String key; /** @@ -65,7 +65,7 @@ public class AIConversation extends AbstractEntity { * Size of all conversation messages. */ @Column(name = "size") - @FilterType(type = FilterType.Type.NUMBER) + @FilterType(type = Long.class) private Long size; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIMessage.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIMessage.java index fe1a231b..18b72566 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIMessage.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AIMessage.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -31,14 +31,14 @@ public class AIMessage extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "aim_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The identifier of the conversation. */ @Column(name = "aic_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID aiConversation; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AISecret.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AISecret.java index 00e54e87..a1c89c3f 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AISecret.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AISecret.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -30,14 +30,14 @@ public class AISecret extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ais_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The secret key given by the user, must be unique. */ @Column(name = "key") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String key; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AbstractEntity.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AbstractEntity.java index d5cfbdd5..f45aa518 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AbstractEntity.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AbstractEntity.java @@ -1,7 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; - -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.MappedSuperclass; import jakarta.persistence.Version; @@ -20,14 +19,14 @@ public class AbstractEntity { * The creation date of this entity. */ @Column(name = "insert_date", updatable = false) - @FilterType(type = FilterType.Type.DATE) + @FilterType(type = Data.class) private Timestamp insertDate; /** * The last update date of this entity. */ @Column(name = "update_date") - @FilterType(type = FilterType.Type.DATE) + @FilterType(type = Data.class) @Version private Timestamp updateDate; } diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControl.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControl.java index b33ebca7..60225525 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControl.java @@ -2,7 +2,7 @@ import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; import com.ditrit.letomodelizerapi.persistence.converter.AccessControlTypeConverter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; @@ -34,14 +34,14 @@ public class AccessControl extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "aco_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The name of the access control. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** @@ -51,7 +51,7 @@ public class AccessControl extends AbstractEntity { @Column(name = "type", nullable = false) @Convert(converter = AccessControlTypeConverter.class) @ColumnTransformer(write = "?::access_control_type") - @FilterType(type = FilterType.Type.ENUM) + @FilterType(type = AccessControlType.class) private AccessControlType type; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermission.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermission.java index a6b2eb9b..a71d9a85 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermission.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermission.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -37,21 +37,21 @@ public class AccessControlPermission extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "pac_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The identifier of the access control to whom this permission is assigned. */ @Column(name = "aco_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID accessControlId; /** * The identifier of the access control to whom this permission is assigned. */ @Column(name = "per_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID permissionId; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermissionView.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermissionView.java index a126a415..8d201b35 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermissionView.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlPermissionView.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -31,42 +31,42 @@ public class AccessControlPermissionView extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "acp_id") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String id; /** * The identifier of the access control to whom this permission is assigned. */ @Column(name = "aco_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID accessControlId; /** * The identifier of the access control to whom this permission is assigned. */ @Column(name = "per_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID permissionId; /** * The entity associated with this permission. */ @Column(name = "entity") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String entity; /** * The action associated with this permission. */ @Column(name = "action") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String action; /** * The identifier of the library associated with this permission. */ @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryId; /** @@ -75,6 +75,6 @@ public class AccessControlPermissionView extends AbstractEntity { * inherited through the role's position in the role hierarchy, offering a nuanced view of permission origins. */ @Column(name = "direct") - @FilterType(type = FilterType.Type.BOOLEAN) + @FilterType(type = Boolean.class) private Boolean isDirect; } diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTree.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTree.java index e4141443..2436bfce 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTree.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTree.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -33,7 +33,7 @@ public class AccessControlTree extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "act_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** @@ -41,7 +41,7 @@ public class AccessControlTree extends AbstractEntity { * This field represents the parent node in the access control tree structure. */ @Column(name = "parent") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID parent; /** @@ -49,7 +49,7 @@ public class AccessControlTree extends AbstractEntity { * This field represents the current node in the access control tree structure. */ @Column(name = "current") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID current; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTreeView.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTreeView.java index f785657e..5660684c 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTreeView.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/AccessControlTreeView.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -28,7 +28,7 @@ public class AccessControlTreeView { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "aca_id") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String internalId; /** @@ -36,42 +36,42 @@ public class AccessControlTreeView { * This field represents the current node in the access control tree structure. */ @Column(name = "aco_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * Type of the current access control. */ @Column(name = "type") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String type; /** * Name of the current access control. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** * Identifier of the parent access control in the tree structure. */ @Column(name = "parent") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID parentId; /** * Name of the parent access control. */ @Column(name = "parent_name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String parentName; /** * Type of the parent access control. */ @Column(name = "parent_type") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String parentType; /** @@ -82,6 +82,6 @@ public class AccessControlTreeView { * hierarchical structure and for operations that depend on direct lineage. */ @Column(name = "direct") - @FilterType(type = FilterType.Type.BOOLEAN) + @FilterType(type = Boolean.class) private Boolean isDirect; } diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Library.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Library.java index 515b1137..3cc30e5f 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Library.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Library.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -32,49 +32,49 @@ public class Library extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * URL of the library. */ @Column(name = "url") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String url; /** * URL for the library's documentation. */ @Column(name = "documentation_url") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String documentationUrl; /** * Name of the library. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** * Version of the library. */ @Column(name = "version") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String version; /** * Maintainer of the library. */ @Column(name = "maintainer") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String maintainer; /** * Description of the library. */ @Column(name = "description") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String description; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/LibraryTemplate.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/LibraryTemplate.java index 5f7ba443..ab4d6067 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/LibraryTemplate.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/LibraryTemplate.java @@ -3,7 +3,7 @@ import com.ditrit.letomodelizerapi.model.library.LibraryTemplateType; import com.ditrit.letomodelizerapi.persistence.converter.LibraryTemplateTypeConverter; import com.ditrit.letomodelizerapi.persistence.converter.StringListConverter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; @@ -38,28 +38,28 @@ public class LibraryTemplate extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "lit_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * Library ID this template belongs to. */ @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryId; /** * URL for the template's documentation. */ @Column(name = "documentation_url") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String documentationUrl; /** * Name of the template. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** @@ -68,14 +68,14 @@ public class LibraryTemplate extends AbstractEntity { @Column(name = "type", nullable = false) @Convert(converter = LibraryTemplateTypeConverter.class) @ColumnTransformer(write = "?::library_template_type") - @FilterType(type = FilterType.Type.ENUM) + @FilterType(type = String.class) private LibraryTemplateType type; /** * Description of the template. */ @Column(name = "description") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String description; /** @@ -89,7 +89,7 @@ public class LibraryTemplate extends AbstractEntity { */ @Column(name = "plugins") @Convert(converter = StringListConverter.class) - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private List plugins; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Permission.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Permission.java index 3e586bb0..2d32d500 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Permission.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/Permission.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -31,7 +31,7 @@ public class Permission extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "per_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** @@ -39,7 +39,7 @@ public class Permission extends AbstractEntity { */ @Column(name = "entity") @ColumnTransformer(write = "?::entity_type") - @FilterType(type = FilterType.Type.ENUM) + @FilterType(type = String.class) private String entity; /** @@ -47,14 +47,14 @@ public class Permission extends AbstractEntity { */ @Column(name = "action") @ColumnTransformer(write = "?::action_type") - @FilterType(type = FilterType.Type.ENUM) + @FilterType(type = String.class) private String action; /** * The identifier of the library associated with this permission. */ @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryId; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/User.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/User.java index 900afa54..685c7d2b 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/User.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/User.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -30,35 +30,35 @@ public class User extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * Email of the user. */ @Column(name = "email") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String email; /** * Login of the user. */ @Column(name = "login") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String login; /** * Full name of the user. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** * URL link to the user's profile picture. */ @Column(name = "picture") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String picture; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControl.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControl.java index 11d1e932..29444af0 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControl.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -30,14 +30,14 @@ public class UserAccessControl extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "uac_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The identifier of the user. */ @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID userId; @@ -45,7 +45,7 @@ public class UserAccessControl extends AbstractEntity { * The identifier of the access control. */ @Column(name = "aco_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID accessControlId; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControlView.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControlView.java index c4481904..977e3707 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControlView.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserAccessControlView.java @@ -1,7 +1,7 @@ package com.ditrit.letomodelizerapi.persistence.model; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -26,49 +26,49 @@ public class UserAccessControlView { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "usa_id") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String id; /** * The identifier of the user to whom this access control is assigned. */ @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID userId; /** * Email of the user. */ @Column(name = "email") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String email; /** * Login of the user. */ @Column(name = "login") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String login; /** * Full name of the user. */ @Column(name = "user_name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String userName; /** * The identifier of the access control. */ @Column(name = "aco_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID accessControlId; /** * The name of the access control. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** @@ -76,7 +76,7 @@ public class UserAccessControlView { * This is defined by the AccessControlType enum. */ @Column(name = "type", nullable = false) - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = AccessControlType.class) private AccessControlType type; /** @@ -87,6 +87,6 @@ public class UserAccessControlView { * hierarchical structure and for operations that depend on direct lineage. */ @Column(name = "direct") - @FilterType(type = FilterType.Type.BOOLEAN) + @FilterType(type = Boolean.class) private Boolean isDirect; } diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserCsrfToken.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserCsrfToken.java index d7fbdb6a..5044d296 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserCsrfToken.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserCsrfToken.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -55,14 +55,14 @@ public UserCsrfToken(final long timeout) { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "cst_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID id; /** * The login identifier of the user to whom the CSRF token is associated. */ @Column(name = "login") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String login; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryTemplateView.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryTemplateView.java index 2c02fc91..70cace26 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryTemplateView.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryTemplateView.java @@ -3,7 +3,7 @@ import com.ditrit.letomodelizerapi.model.library.LibraryTemplateType; import com.ditrit.letomodelizerapi.persistence.converter.LibraryTemplateTypeConverter; import com.ditrit.letomodelizerapi.persistence.converter.StringListConverter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; @@ -33,42 +33,42 @@ public class UserLibraryTemplateView { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ult_id") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String id; /** * The identifier of the user to whom this template of library is assigned. */ @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID userId; /** * Library template ID associated with this view. */ @Column(name = "lit_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryTemplateId; /** * Library ID associated with this library template. */ @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryId; /** * Documentation URL for the library template. */ @Column(name = "documentation_url") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String documentationUrl; /** * Name of the library template. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** @@ -77,14 +77,14 @@ public class UserLibraryTemplateView { @Column(name = "type", nullable = false) @Convert(converter = LibraryTemplateTypeConverter.class) @ColumnTransformer(write = "?::library_template_type") - @FilterType(type = FilterType.Type.ENUM) + @FilterType(type = String.class) private LibraryTemplateType type; /** * Description of the library template. */ @Column(name = "description") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String description; /** @@ -98,7 +98,7 @@ public class UserLibraryTemplateView { */ @Column(name = "plugins") @Convert(converter = StringListConverter.class) - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private List plugins; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryView.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryView.java index 42dd1840..2cc9e64c 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryView.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserLibraryView.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -26,63 +26,63 @@ public class UserLibraryView { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "uli_id") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String id; /** * The identifier of the user to whom this template of library is assigned. */ @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID userId; /** * Library ID associated with this library template. */ @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryId; /** * URL of the library. */ @Column(name = "url") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String url; /** * URL for the library's documentation. */ @Column(name = "documentation_url") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String documentationUrl; /** * Name of the library. */ @Column(name = "name") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String name; /** * Version of the library. */ @Column(name = "version") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String version; /** * Maintainer of the library. */ @Column(name = "maintainer") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String maintainer; /** * Description of the library. */ @Column(name = "description") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String description; /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserPermission.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserPermission.java index de878570..bdf6479d 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserPermission.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/model/UserPermission.java @@ -1,6 +1,6 @@ package com.ditrit.letomodelizerapi.persistence.model; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; +import io.github.zorin95670.predicate.FilterType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -27,14 +27,14 @@ public class UserPermission extends AbstractEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "usp_id") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String id; /** * The identifier of the user to whom this permission is assigned. */ @Column(name = "usr_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID userId; @@ -42,27 +42,27 @@ public class UserPermission extends AbstractEntity { * The identifier of permission. */ @Column(name = "per_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID permissionId; /** * The entity associated with this permission. */ @Column(name = "entity") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String entity; /** * The action associated with this permission. */ @Column(name = "action") - @FilterType(type = FilterType.Type.TEXT) + @FilterType(type = String.class) private String action; /** * The identifier of the library associated with this permission. */ @Column(name = "lib_id") - @FilterType(type = FilterType.Type.UUID) + @FilterType(type = UUID.class) private UUID libraryId; } diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/repository/UserRepository.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/repository/UserRepository.java index f083e41a..5756c17f 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/repository/UserRepository.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/repository/UserRepository.java @@ -5,6 +5,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import java.util.Optional; import java.util.UUID; @@ -16,6 +17,7 @@ * * @see JpaRepository */ +@Repository public interface UserRepository extends JpaRepository { /** diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/AccessControlTypePredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/AccessControlTypePredicateFilter.java new file mode 100644 index 00000000..7ed4d596 --- /dev/null +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/AccessControlTypePredicateFilter.java @@ -0,0 +1,33 @@ +package com.ditrit.letomodelizerapi.persistence.specification; + +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; +import io.github.zorin95670.exception.SpringQueryFilterException; +import io.github.zorin95670.predicate.PredicateFilter; + +public class AccessControlTypePredicateFilter extends PredicateFilter { + + /** + * Constructs a new {@link AccessControlTypePredicateFilter} with the specified name and filter value. + * + * @param name The name of the field to filter by. + * @param value The filter value(s) to apply. + */ + public AccessControlTypePredicateFilter(final String name, final String value) { + super(name, value); + } + + @Override + public AccessControlType parseValue(final String value) { + try { + return AccessControlType.valueOf(value); + } catch (IllegalArgumentException exception) { + throw new SpringQueryFilterException( + "Invalid AccessControlType format: Unable to parse the value '" + value + "' as an AccessControlType.", + exception, + "AccessControlType", + this.getName(), + value + ); + } + } +} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/CustomSpringQueryFilterSpecification.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/CustomSpringQueryFilterSpecification.java new file mode 100644 index 00000000..ca6456ad --- /dev/null +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/CustomSpringQueryFilterSpecification.java @@ -0,0 +1,33 @@ +package com.ditrit.letomodelizerapi.persistence.specification; + +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; +import io.github.zorin95670.predicate.IPredicateFilter; +import io.github.zorin95670.specification.SpringQueryFilterSpecification; + +import java.util.List; +import java.util.Map; + +/** + * Custom class to manage our type to generate predicate. + * @param Entity class. + */ +public class CustomSpringQueryFilterSpecification extends SpringQueryFilterSpecification { + /** + * Constructs a new specification with the provided entity class and filters. + * + * @param entityClass The entity class to apply the specification to. + * @param filters The map of filters for field names and values. + */ + public CustomSpringQueryFilterSpecification(final Class entityClass, final Map> filters) { + super(entityClass, filters); + } + + @Override + public IPredicateFilter getPredicateFilter(final Class type, final String name, final String value) { + if (AccessControlType.class.equals(type)) { + return new AccessControlTypePredicateFilter<>(name, value); + } + + return super.getPredicateFilter(type, name, value); + } +} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperator.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperator.java deleted file mode 100644 index f793c52c..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperator.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification; - -import lombok.Getter; - -import java.util.Arrays; -import java.util.Optional; - -/** - * List of available operator for QueryFilter. - */ -public enum PredicateOperator { - /** - * Operator equals, value "=". - */ - EQUALS("eq"), - /** - * Operator inferior, value "<". - */ - INFERIOR("lt"), - /** - * Operator superior, value ">". - */ - SUPERIOR("gt"), - /** - * Operator between, value "<>". - */ - BETWEEN("bt"), - /** - * Operator null, value "null". - */ - NULL("null"), - /** - * Operator like, value "lk". - */ - LIKE("lk_"); - - /** - * String representation of operator. - */ - @Getter - private final String value; - - /** - * Default constructor. - * - * @param value Representation of operator - */ - PredicateOperator(final String value) { - this.value = value; - } - - /** - * Indicates if operator is valid or not. - * - * @param operator Operator value. - * @return If operator exists return true otherwise false. - */ - public static boolean isValid(final String operator) { - return Arrays.stream(PredicateOperator.values()).anyMatch(o -> o.getValue().equalsIgnoreCase(operator)); - } - - /** - * Get operator from value. - * - * @param operator Operator value. - * @return Operator or null. - */ - public static Optional get(final String operator) { - return Arrays.stream(PredicateOperator.values()) - .filter(predicateOperator -> predicateOperator.getValue().equalsIgnoreCase(operator)) - .findAny(); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelper.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelper.java deleted file mode 100644 index fe9c87a4..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelper.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification; - -import com.ditrit.letomodelizerapi.persistence.specification.filter.BooleanPredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.DatePredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.EnumPredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.FilterType; -import com.ditrit.letomodelizerapi.persistence.specification.filter.IPredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.NumberPredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.TextPredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.TokenPredicateFilter; -import com.ditrit.letomodelizerapi.persistence.specification.filter.UUIDPredicateFilter; -import com.ditrit.letomodelizerapi.reflect.FieldUtils; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import lombok.Getter; -import lombok.Setter; -import org.springframework.data.jpa.domain.Specification; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Generate predicates from a map of filters. - * - * @param Entity class. - */ -public class SpecificationHelper implements Specification { - - /** - * Filter's map. - */ - @Setter - private Map filters; - - /** - * Entity class. - */ - @Getter - @Setter - private Class entityClass; - - /** - * Construct specification. - * - * @param entityClass Entity class. - * @param filters Filter's map. - */ - public SpecificationHelper(final Class entityClass, final Map filters) { - setEntityClass(entityClass); - setFilters(filters); - } - - - @Override - public final Predicate toPredicate(final Root root, final CriteriaQuery query, - final CriteriaBuilder builder) { - return builder.and(this.getFilters().stream() - .map(filter -> filter.getPredicate(builder, root, query)) - .toArray(Predicate[]::new)); - } - - final List getFilters() { - final List filterList = new ArrayList<>(); - final List fields = FieldUtils.getFields(this.getEntityClass()); - - fields.stream().filter(field -> field.isAnnotationPresent(FilterType.class)).forEach(field -> { - final String name = field.getName(); - if (!this.filters.containsKey(name)) { - return; - } - final String value = this.filters.get(name); - final FilterType filterType = field.getAnnotation(FilterType.class); - - IPredicateFilter filter; - - if (FilterType.Type.DATE.equals(filterType.type())) { - filter = new DatePredicateFilter(name, value); - } else if (FilterType.Type.NUMBER.equals(filterType.type())) { - filter = new NumberPredicateFilter(name, value); - } else if (FilterType.Type.BOOLEAN.equals(filterType.type())) { - filter = new BooleanPredicateFilter(name, value); - } else if (FilterType.Type.TOKEN.equals(filterType.type())) { - filter = new TokenPredicateFilter(name, value); - } else if (FilterType.Type.ENUM.equals(filterType.type())) { - filter = new EnumPredicateFilter(name, value); - } else if (FilterType.Type.UUID.equals(filterType.type())) { - filter = new UUIDPredicateFilter(name, value); - } else { - filter = new TextPredicateFilter(name, value); - } - - if (filter.extract()) { - filterList.add(filter); - } - }); - - return filterList; - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilter.java deleted file mode 100644 index 49506ddb..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Predicate; - -/** - * Class to extract boolean filter from the query. - */ -public class BooleanPredicateFilter extends PredicateFilter { - - /** - * Create boolean filter with field name and default type is "boolean". - * - * @param name Field name. - * @param value Field value. - */ - public BooleanPredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.BOOLEAN); - } - - @Override - public final Predicate getPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - if (this.getIsNotOperator(index)) { - return builder.notEqual(field, Boolean.parseBoolean(this.getValue(index))); - } - return builder.equal(field, Boolean.parseBoolean(this.getValue(index))); - } - -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilter.java deleted file mode 100644 index 942a8edf..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilter.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.model.error.ApiException; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Predicate; - -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Class to extract date filter from the query. - */ -public class DatePredicateFilter extends PredicateFilter { - /** - * Default date format for date filter. - */ - public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; - /** - * Regex pattern for date format. - */ - private static final String FILTER_SUB_PATTERN = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}"; - /** - * Regex to extract date. - *

- * This regex has 3 groups : - *

    - *
  • Date for between value, with format "yyyy-MM-dd" can be null.
  • - *
  • Operator
  • - *
  • Default date with format "yyy-MM-dd"
  • - *
- *

- * - * @see PredicateOperator - */ - private static final Pattern FILTER_PATTERN = Pattern - .compile("(" + FILTER_SUB_PATTERN + ")?([a-zA-Z]{2})?(" + FILTER_SUB_PATTERN + ")"); - /** - * Position of sub-value in Regex group. - */ - private static final int SUBVALUE_POSITION = 1; - /** - * Position of operator in Regex group. - */ - private static final int OPERATOR_POSITION = 2; - /** - * Position of value in Regex group. - */ - private static final int VALUE_POSITION = 3; - /** - * Date format parser. - */ - private final SimpleDateFormat parser = new SimpleDateFormat(DATE_FORMAT); - /** - * Second date of 'between search'. - */ - private String[] subValues; - - /** - * Create date filter with field name and default type is "date". - * - * @param name Field name. - * @param value Field value. - */ - public DatePredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.DATE); - this.setSubValues(new String[this.getValues().length]); - this.parser.setTimeZone(TimeZone.getTimeZone("UTC")); - } - - /** - * Set sub value. - * - * @param index Index of sub value to set. - * @param value Value of sub value. - */ - public void setSubValue(final int index, final String value) { - this.subValues[index] = value; - } - - /** - * Set sub value. - * - * @param subValues Sub values. - */ - public void setSubValues(final String[] subValues) { - this.subValues = Arrays.copyOf(subValues, subValues.length); - } - - /** - * Convert value to Date. - * - * @param value Date value. - * @return Date or throw HarmonyRestException. - */ - public Date getDate(final String value) { - try { - return this.parser.parse(value); - } catch (final Exception e) { - throw new ApiException(e, ErrorType.WRONG_FILTER_VALUE, this.getName(), value); - } - } - - @Override - public final boolean extract() { - if (this.getValues().length == 0) { - return false; - } - - for (int index = 0; index < this.getValues().length; ++index) { - this.setOperatorFromValue(index); - if (PredicateOperator.NULL.equals(this.getOperator(index))) { - continue; - } - String value = this.getValue(index); - final Matcher matcher = FILTER_PATTERN.matcher(value); - if (!matcher.find()) { - throw new ApiException(ErrorType.WRONG_FILTER_VALUE, this.getName(), value); - } - - String operator = matcher.group(OPERATOR_POSITION); - if (operator != null) { - this.setOperator(index, PredicateOperator.get(operator).orElseThrow(() -> - new ApiException(ErrorType.WRONG_FILTER_OPERATOR, this.getName(), operator))); - } - this.setValue(index, matcher.group(VALUE_POSITION)); - this.setSubValue(index, matcher.group(SUBVALUE_POSITION)); - - if (PredicateOperator.BETWEEN.equals(this.getOperator(index)) - && this.subValues[index] == null) { - throw new ApiException(ErrorType.EMPTY_VALUE, this.getName()); - } - } - return true; - } - - @Override - public final Predicate getPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - Predicate predicate; - if (PredicateOperator.EQUALS.equals(this.getOperator(index))) { - predicate = builder.equal(field, this.getDate(this.getValue(index))); - } else if (PredicateOperator.INFERIOR.equals(this.getOperator(index))) { - predicate = builder.lessThan(field.as(Date.class), this.getDate(this.getValue(index))); - } else if (PredicateOperator.SUPERIOR.equals(this.getOperator(index))) { - predicate = builder.greaterThan(field.as(Date.class), this.getDate(this.getValue(index))); - } else { - predicate = builder.between(field.as(Date.class), this.getDate(this.subValues[index]), - this.getDate(this.getValue(index))); - } - - if (this.getIsNotOperator(index)) { - return builder.not(predicate); - } - return predicate; - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilter.java deleted file mode 100644 index e9859b7b..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilter.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Predicate; - -/** - * Class to extract enum filter from the query. - */ -public class EnumPredicateFilter extends PredicateFilter { - - /** - * Create enum filter with field name and default type filter as "enum". - * - * @param name Field name. - * @param value Field value. - */ - public EnumPredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.ENUM); - } - - @Override - public final Predicate getPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - if (this.getIsNotOperator(index)) { - return builder.notEqual(field.as(String.class), this.getValue(index)); - } - return builder.equal(field.as(String.class), this.getValue(index)); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/FilterType.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/FilterType.java deleted file mode 100644 index b9ba6865..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/FilterType.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that turns a field into a filterable field. - * The type of filter must be adapted to the value's type of the field. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface FilterType { - - /** - * Type of filter. - * - * @return Type of filter. - */ - Type type(); - - /** - * Type of filter. - */ - enum Type { - /** - * Text. - */ - TEXT, - /** - * Date. - */ - DATE, - /** - * Number. - */ - NUMBER, - /** - * Boolean. - */ - BOOLEAN, - /** - * Token. - */ - TOKEN, - /** - * Enum. - */ - ENUM, - /** - * UUID. - */ - UUID, - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/IPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/IPredicateFilter.java deleted file mode 100644 index 6b630cd9..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/IPredicateFilter.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import jakarta.persistence.criteria.CommonAbstractCriteria; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.From; -import jakarta.persistence.criteria.Predicate; - -/** - * Predicate extractor. - */ -public interface IPredicateFilter { - - /** - * Extract Filter from query value. - * - * @return True if there is a predicate, otherwise false. - */ - boolean extract(); - - /** - * Create predicate from entity. - * - * @param Entity class. - * @param Entity class. - * @param builder Criteria builder. - * @param root Entity root. - * @param query Default Query. - * @return Predicate from entity. - */ - Predicate getPredicate(CriteriaBuilder builder, From root, CommonAbstractCriteria query); - -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilter.java deleted file mode 100644 index 8e562dd2..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilter.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.model.error.ApiException; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.criteria.CommonAbstractCriteria; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.From; -import jakarta.persistence.criteria.Predicate; - -import java.util.Arrays; - -/** - * Class to extract number filter from the query. - */ -public class NumberPredicateFilter extends PredicateFilter { - - /** - * Create number filter with field name and default type is "number". - * - * @param name Field name. - * @param value Field value. - */ - public NumberPredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.NUMBER); - } - - @Override - public final void setOperatorFromValue(final int index) { - super.setOperatorFromValue(index); - if (PredicateOperator.EQUALS.equals(this.getOperator(index))) { - try { - Long.parseLong(this.getValue(index)); - } catch (NumberFormatException e) { - throw new ApiException(e, ErrorType.WRONG_FILTER_VALUE, this.getName(), this.getValue(index)); - } - } - } - - /** - * Constructs a {@link Predicate} based on the specified criteria. - * This method analyzes the operator types and values associated with the current - * context and creates an appropriate {@link Predicate}. It supports handling both - * 'EQUALS' and 'NOT EQUALS' operators. If all operators are 'EQUALS', a direct - * 'in' predicate is created. If all are 'NOT EQUALS', a negated 'in' predicate - * is formed. Otherwise, a combination of predicates is built. - */ - @Override - public final Predicate getPredicate(final CriteriaBuilder builder, - final From root, - final CommonAbstractCriteria query) { - int allNotEquals = 0; - int allEquals = 0; - - for (int index = 0; index < this.getValues().length; index++) { - if (!PredicateOperator.EQUALS.equals(this.getOperator(index))) { - break; - } - if (this.getIsNotOperator(index)) { - allNotEquals += 1; - } else { - allEquals += 1; - } - } - - if (this.getValues().length == allNotEquals) { - return builder - .not( - root.get(this.getName()) - .in(Arrays.stream(this.getValues()) - .map(Long::parseLong) - .toList())); - } - if (this.getValues().length == allEquals) { - return root - .get(this.getName()) - .in(Arrays.stream(this.getValues()) - .map(Long::parseLong) - .toList()); - } - Predicate[] predicates = new Predicate[this.getValues().length]; - for (int index = 0; index < getValues().length; index++) { - predicates[index] = this.getPredicate(index, builder, root); - } - return builder.and(builder.or(predicates)); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilter.java deleted file mode 100644 index 779d16d3..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilter.java +++ /dev/null @@ -1,266 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.criteria.CommonAbstractCriteria; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.From; -import jakarta.persistence.criteria.Predicate; -import lombok.Getter; -import lombok.Setter; - -import java.util.Arrays; - -/** - * Abstract class for implementing the default field of QueryFilter. - */ -public abstract class PredicateFilter implements IPredicateFilter { - - /** - * Or delimiter. - */ - protected static final String OR_DELIMITER = "\\|"; - - /** - * Not delimiter. - */ - protected static final String NOT_DELIMITER = "not_"; - /** - * Operator of this filter. - */ - private PredicateOperator[] operators; - /** - * Indicate if it's not operator. - */ - private boolean[] isNotOperators; - /** - * Name of field to apply filter. - */ - @Getter - @Setter - private String name; - /** - * Values of filter. - */ - private String[] values; - - /** - * Create filter with field name. - * - * @param name Field's name to apply filter. - * @param value Text to convert in filters. - * @param type Type of filter. - */ - PredicateFilter(final String name, final String value, final FilterType.Type type) { - this.setName(name); - this.setValues(value); - this.setOperators(new PredicateOperator[this.getValues().length]); - this.setIsNotOperators(new boolean[this.getValues().length]); - } - - /** - * Get the state of the 'isNotOperator' at position 'index'. - * - * @param index Value index. - * @return State. - */ - public boolean getIsNotOperator(final int index) { - return this.isNotOperators[index]; - } - - /** - * Set the state of the 'isNotOperator' at position 'index'. - * - * @param index Index of value to set. - * @param state State. - */ - public void setIsNotOperator(final int index, final boolean state) { - this.isNotOperators[index] = state; - } - - /** - * Set is not operator states. - * - * @param states States list. - */ - public final void setIsNotOperators(final boolean[] states) { - this.isNotOperators = Arrays.copyOf(states, states.length); - } - - /** - * Get value of filter from index. - * - * @param index Value index. - * @return Value. - */ - public String getValue(final int index) { - return this.values[index]; - } - - /** - * Set value on index. - * - * @param index Index of value to set. - * @param value Value. - */ - public void setValue(final int index, final String value) { - this.values[index] = value; - } - - /** - * Get values of filter. - * - * @return Values. - */ - public String[] getValues() { - return Arrays.copyOf(this.values, this.values.length); - } - - /** - * Set values of filter. - * - * @param value Not split value. - */ - public void setValues(final String value) { - if (value != null) { - this.values = value.split(OR_DELIMITER); - } else { - this.values = new String[0]; - } - } - - /** - * Get operator. - * - * @param index Operator index. - * @return Operator. - */ - public final PredicateOperator getOperator(final int index) { - return operators[index]; - } - - /** - * Set operator on index. - * - * @param index Operator index. - * @param operator Operator to set. - */ - public final void setOperator(final int index, final PredicateOperator operator) { - this.operators[index] = operator; - } - - /** - * Get operators. - * - * @return Operator. - */ - public final PredicateOperator[] getOperators() { - return Arrays.copyOf(this.operators, this.operators.length); - } - - /** - * Set operators. - * - * @param operators Operator list. - */ - public final void setOperators(final PredicateOperator[] operators) { - this.operators = Arrays.copyOf(operators, operators.length); - } - - /** - * Set operator from value. - * - * @param index Value index. - */ - public void setOperatorFromValue(final int index) { - this.setOperator(index, PredicateOperator.EQUALS); - if (this.values[index].toLowerCase().startsWith(NOT_DELIMITER)) { - this.setIsNotOperator(index, true); - this.setValue(index, this.values[index].substring(NOT_DELIMITER.length())); - } - if (PredicateOperator.NULL.getValue().equalsIgnoreCase(this.values[index])) { - this.setOperator(index, PredicateOperator.NULL); - } - } - - /** - * If field value is null return false, otherwise set field value in value - * and return true. - */ - @Override - public boolean extract() { - if (this.getValues().length == 0) { - return false; - } - - for (int index = 0; index < this.getValues().length; index++) { - this.setOperatorFromValue(index); - } - - return true; - } - - /** - * Override this if you need to add predicate on sub-query. - */ - @Override - public Predicate getPredicate(final CriteriaBuilder builder, final From root, - final CommonAbstractCriteria query) { - Predicate[] predicates = new Predicate[this.getValues().length]; - for (int index = 0; index < this.getValues().length; index++) { - predicates[index] = this.getPredicate(index, builder, root); - } - return builder.and(builder.or(predicates)); - } - - /** - * Return default predicate. This method call getPredicate with Expression. - * Override it, to use your wanted expression. - * - * @param Entity class. - * @param Entity class. - * @param index Index of predicate. - * @param builder Criteria builder. - * @param root Root path. - * @return Predicate. - */ - public Predicate getPredicate(final int index, final CriteriaBuilder builder, final From root) { - if (PredicateOperator.NULL.equals(this.operators[index])) { - return this.getNullPredicate(index, builder, root.get(this.getName())); - } - - return this.getPredicate(index, builder, root.get(this.getName())); - } - - /** - * Override to return specific null predicate. - * - * @param Entity class. - * @param index Index of predicate. - * @param builder Criteria builder. - * @param field Field expression. - * @return Null predicate. - */ - private Predicate getNullPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - if (this.getIsNotOperator(index)) { - return builder.isNotNull(field); - } - return builder.isNull(field); - } - - /** - * Override to return specific predicate. - * - * @param Entity class. - * @param index Index of predicate. - * @param builder Criteria builder. - * @param field Field expression. - * @return Predicate. - */ - public Predicate getPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - if (this.getIsNotOperator(index)) { - return builder.notEqual(field, this.getValue(index)); - } - return builder.equal(field, this.getValue(index)); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilter.java deleted file mode 100644 index 5f5fc3d3..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilter.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Predicate; - -/** - * Class to extract text filter from the query. - */ -public class TextPredicateFilter extends PredicateFilter { - - /** - * Create text filter with field name and default type filter as "text". - * - * @param name Field name. - * @param value Field value. - */ - public TextPredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.TEXT); - } - - @Override - public final void setOperatorFromValue(final int index) { - super.setOperatorFromValue(index); - String value = getValue(index); - if (value.toLowerCase().startsWith(PredicateOperator.LIKE.getValue())) { - value = value.replace("*", "%"); - this.setOperator(index, PredicateOperator.LIKE); - value = value.substring(PredicateOperator.LIKE.getValue().length()); - } - this.setValue(index, value.toUpperCase()); - } - - @Override - public final Predicate getPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - if (PredicateOperator.LIKE.equals(this.getOperator(index))) { - String value = this.getValue(index).toUpperCase(); - if (this.getIsNotOperator(index)) { - return builder.notLike(builder.upper((Expression) field), value); - } - return builder.like(builder.upper((Expression) field), value); - } - return super.getPredicate(index, builder, builder.upper((Expression) field)); - } -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilter.java deleted file mode 100644 index 9e4d9f4e..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilter.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -/** - * Class to extract token filter from the query. - */ -public class TokenPredicateFilter extends PredicateFilter { - - /** - * Create token filter with field name and default type filter as "token". - * - * @param name Field name. - * @param value Field value. - */ - public TokenPredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.TOKEN); - } - -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilter.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilter.java deleted file mode 100644 index 8fb832d1..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilter.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Predicate; - -import java.util.UUID; - -/** - * Class to extract token filter from the query. - */ -public class UUIDPredicateFilter extends PredicateFilter { - - /** - * Create token filter with field name and default type filter as "token". - * - * @param name Field name. - * @param value Field value. - */ - public UUIDPredicateFilter(final String name, final String value) { - super(name, value, FilterType.Type.UUID); - } - - @Override - public Predicate getPredicate(final int index, final CriteriaBuilder builder, final Expression field) { - if (this.getIsNotOperator(index)) { - return builder.notEqual(field, UUID.fromString(this.getValue(index))); - } - return builder.equal(field, UUID.fromString(this.getValue(index))); - } - -} diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/package-info.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/package-info.java deleted file mode 100644 index bff8e6de..00000000 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/filter/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Common predicate filters. - */ -package com.ditrit.letomodelizerapi.persistence.specification.filter; diff --git a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/package-info.java b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/package-info.java index 01654f37..27b7f690 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/package-info.java +++ b/src/main/java/com/ditrit/letomodelizerapi/persistence/specification/package-info.java @@ -1,4 +1,4 @@ /** - * Specification management. + * Package that contains all classes that extends SpringQueryFilter. */ package com.ditrit.letomodelizerapi.persistence.specification; diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationService.java b/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationService.java index 656574b8..1cb1be08 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationService.java @@ -1,10 +1,11 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AIConfigurationRecord; import com.ditrit.letomodelizerapi.persistence.model.AIConfiguration; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -18,10 +19,10 @@ public interface AIConfigurationService { * Finds and returns a page of AIConfiguration entities, filtered by provided criteria. * * @param filters a Map of strings representing the filtering criteria. - * @param pageable a Pageable object for pagination information. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AIConfiguration entities matching the specified type and filters. */ - Page findAll(Map filters, Pageable pageable); + Page findAll(Map> filters, QueryFilter queryFilter); /** * Finds and returns an AIConfiguration entity of a specific type by its ID. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImpl.java index f84a8f40..f94fdfb1 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImpl.java @@ -1,21 +1,20 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AIConfigurationRecord; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.persistence.model.AIConfiguration; import com.ditrit.letomodelizerapi.persistence.repository.AIConfigurationRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import jakarta.transaction.Transactional; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -41,13 +40,11 @@ public class AIConfigurationServiceImpl implements AIConfigurationService { private final AIConfigurationRepository aiConfigurationRepository; @Override - public Page findAll(final Map filters, final Pageable pageable) { - return aiConfigurationRepository.findAll(new SpecificationHelper<>(AIConfiguration.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "key")) - ) + public Page findAll(final Map> filters, + final QueryFilter queryFilter) { + return aiConfigurationRepository.findAll( + new CustomSpringQueryFilterSpecification<>(AIConfiguration.class, filters), + queryFilter.getPageable("key") ); } diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AISecretService.java b/src/main/java/com/ditrit/letomodelizerapi/service/AISecretService.java index e09e9e18..e0740ab5 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AISecretService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AISecretService.java @@ -1,10 +1,11 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AISecretRecord; import com.ditrit.letomodelizerapi.persistence.model.AISecret; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -17,11 +18,11 @@ public interface AISecretService { /** * Finds and returns a page of AISecret entities, filtered by provided criteria. * - * @param filters a Map of strings representing the filtering criteria. - * @param pageable a Pageable object for pagination information. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AISecret entities matching the specified type and filters. */ - Page findAll(Map filters, Pageable pageable); + Page findAll(Map> filters, QueryFilter queryFilter); /** * Finds and returns an AISecret entity of a specific type by its ID. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AISecretServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/AISecretServiceImpl.java index 5c2845f5..3e488066 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AISecretServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AISecretServiceImpl.java @@ -1,6 +1,7 @@ package com.ditrit.letomodelizerapi.service; import com.ditrit.letomodelizerapi.config.Constants; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.BeanMapper; import com.ditrit.letomodelizerapi.model.ai.AISecretRecord; import com.ditrit.letomodelizerapi.model.error.ApiException; @@ -9,7 +10,7 @@ import com.ditrit.letomodelizerapi.persistence.model.AISecret; import com.ditrit.letomodelizerapi.persistence.repository.AIConfigurationRepository; import com.ditrit.letomodelizerapi.persistence.repository.AISecretRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.hubspot.jinjava.Jinjava; import jakarta.transaction.Transactional; @@ -17,9 +18,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import javax.crypto.Cipher; @@ -201,24 +199,21 @@ public String decrypt(final String key, final byte[] encryptedIvTextBytes) { * This method return data with encoded secret value. * Ensure the secret value is not exposed, even if it is encrypted. * - * @param filters a Map of strings representing the filtering criteria. - * @param pageable a Pageable object for pagination information. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AISecret entities matching the specified type and filters. */ - private Page findAllWithSecretValue(final Map filters, - final Pageable pageable) { - return aiSecretRepository.findAll(new SpecificationHelper<>(AISecret.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "key")) - ) - ); + private Page findAllWithSecretValue(final Map> filters, + final QueryFilter queryFilter) { + return aiSecretRepository.findAll( + new CustomSpringQueryFilterSpecification<>(AISecret.class, filters), + queryFilter.getPageable(true, "key")); } @Override - public Page findAll(final Map filters, final Pageable pageable) { - return findAllWithSecretValue(filters, pageable) + public Page findAll(final Map> filters, + final QueryFilter queryFilter) { + return findAllWithSecretValue(filters, queryFilter) .map(new BeanMapper<>(AISecret.class, Constants.DEFAULT_AI_SECRET_VALUE_PROPERTY)); } diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AIService.java b/src/main/java/com/ditrit/letomodelizerapi/service/AIService.java index 756efa2a..b26ffc7b 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AIService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AIService.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AIConversationRecord; import com.ditrit.letomodelizerapi.model.ai.AICreateFileRecord; import com.ditrit.letomodelizerapi.model.ai.AIMessageRecord; @@ -8,9 +9,9 @@ import com.ditrit.letomodelizerapi.persistence.model.User; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import java.io.IOException; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -91,32 +92,31 @@ AIConversation updateConversationById(User user, UUID id, AIConversationRecord a * Finds all AI conversations for a user with optional filtering and pagination. * * @param user the user for whom to find conversations. - * @param filters a map of filters to apply to the search. - * @param pageable pagination information. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page containing the AI conversations matching the filters. */ - Page findAll(User user, Map filters, Pageable pageable); + Page findAll(User user, Map> filters, QueryFilter queryFilter); /** * Finds all messages for a specific AI conversation with optional filtering and pagination. * * @param user the user requesting the messages. * @param id the ID of the conversation for which to find messages. - * @param filters a map of filters to apply to the search. - * @param pageable pagination information. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page containing the messages for the specified conversation. */ - Page findAllMessages(User user, UUID id, Map filters, Pageable pageable); + Page findAllMessages(User user, UUID id, Map> filters, QueryFilter queryFilter); /** * Finds all AI conversations with optional filtering and pagination. * - * @param immutableFilters a map of immutable filters to apply to the search. - * @param pageable pagination information. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page containing all AI conversations matching the filters. */ - Page findAllConversations(Map immutableFilters, - Pageable pageable); + Page findAllConversations(Map> filters, QueryFilter queryFilter); /** * Sends the encrypted configuration to the AI proxy. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AIServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/AIServiceImpl.java index 187cda89..ff926ead 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AIServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AIServiceImpl.java @@ -1,6 +1,7 @@ package com.ditrit.letomodelizerapi.service; import com.ditrit.letomodelizerapi.config.Constants; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AIConversationRecord; import com.ditrit.letomodelizerapi.model.ai.AICreateFileRecord; import com.ditrit.letomodelizerapi.model.ai.AIMessageRecord; @@ -12,7 +13,7 @@ import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.persistence.repository.AIConversationRepository; import com.ditrit.letomodelizerapi.persistence.repository.AIMessageRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -28,16 +29,13 @@ import com.github.erosb.jsonsKema.Validator; import com.github.erosb.jsonsKema.ValidatorConfig; import jakarta.transaction.Transactional; -import jakarta.ws.rs.core.HttpHeaders; -import jakarta.ws.rs.core.MediaType; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import java.io.ByteArrayOutputStream; @@ -153,7 +151,7 @@ public String sendRequest(final String endpoint, final String contentType, final HttpRequest request = HttpRequest.newBuilder() .uri(uri) .header(HttpHeaders.CONTENT_TYPE, contentType) - .headers(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON) + .headers(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString()) .POST(HttpRequest.BodyPublishers.ofByteArray(body)) .build(); @@ -205,8 +203,10 @@ public String sendFiles(final AIConversation conversation, final List findAll(final User user, - final Map immutableFilters, - final Pageable pageable) { - Map filters = new HashMap<>(immutableFilters); - filters.put("userId", user.getId().toString()); + final Map> immutableFilters, + final QueryFilter queryFilter) { + var filters = new HashMap<>(immutableFilters); + filters.put("userId", List.of(user.getId().toString())); return aiConversationRepository.findAll( - new SpecificationHelper<>(AIConversation.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.DESC, Constants.DEFAULT_UPDATE_DATE_PROPERTY)) - ) + new CustomSpringQueryFilterSpecification<>(AIConversation.class, filters), + queryFilter.getPageable(Constants.DEFAULT_UPDATE_DATE_PROPERTY) ); } @Override public Page findAllMessages(final User user, final UUID id, - final Map immutableFilters, - final Pageable pageable) { + final Map> immutableFilters, + final QueryFilter queryFilter) { AIConversation conversation = aiConversationRepository.findByIdAndUserId(id, user.getId()) .orElseThrow(() -> new ApiException(ErrorType.ENTITY_NOT_FOUND, "id", id.toString())); - Map filters = new HashMap<>(immutableFilters); - filters.put("aiConversation", conversation.getId().toString()); + var filters = new HashMap<>(immutableFilters); + filters.put("aiConversation", List.of(conversation.getId().toString())); return aiMessageRepository.findAll( - new SpecificationHelper<>(AIMessage.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.DESC, Constants.DEFAULT_UPDATE_DATE_PROPERTY))) + new CustomSpringQueryFilterSpecification<>(AIMessage.class, filters), + queryFilter.getPageable(Constants.DEFAULT_UPDATE_DATE_PROPERTY) ); } @Override - public Page findAllConversations(final Map immutableFilters, - final Pageable pageable) { - + public Page findAllConversations(final Map> filters, + final QueryFilter queryFilter) { return aiConversationRepository.findAll( - new SpecificationHelper<>(AIConversation.class, immutableFilters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.DESC, Constants.DEFAULT_UPDATE_DATE_PROPERTY)) - )); + new CustomSpringQueryFilterSpecification<>(AIConversation.class, filters), + queryFilter.getPageable(Constants.DEFAULT_UPDATE_DATE_PROPERTY) + ); } @Override public void sendConfiguration(final byte[] configuration) { - sendRequest("configurations", MediaType.APPLICATION_OCTET_STREAM, configuration); + sendRequest("configurations", MediaType.APPLICATION_OCTET_STREAM.toString(), configuration); } @Override @@ -396,8 +385,8 @@ public String getConfigurationDescriptions() { URI uri = new URI(aiHost).resolve(endpoint); HttpRequest request = HttpRequest.newBuilder() .uri(uri) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) - .headers(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString()) + .headers(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString()) .GET() .build(); diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionService.java b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionService.java index 8a500295..bd5f7392 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionService.java @@ -1,9 +1,10 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.persistence.model.AccessControlPermissionView; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -17,11 +18,11 @@ public interface AccessControlPermissionService { * Finds and returns a page of AccessControl entities of a specific type, filtered by provided criteria. * * @param id the ID of the AccessControl entity - * @param filters a Map of strings representing the filtering criteria - * @param pageable a Pageable object for pagination information + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AccessControl entities matching the specified type and filters */ - Page findAll(UUID id, Map filters, Pageable pageable); + Page findAll(UUID id, Map> filters, QueryFilter queryFilter); /** * Associates a specific permission with an AccessControl entity. This method creates a new linkage between the diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImpl.java index 39f42492..5d8b5e37 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImpl.java @@ -1,22 +1,22 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.persistence.model.AccessControlPermission; import com.ditrit.letomodelizerapi.persistence.model.AccessControlPermissionView; import com.ditrit.letomodelizerapi.persistence.repository.AccessControlPermissionRepository; import com.ditrit.letomodelizerapi.persistence.repository.AccessControlPermissionViewRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import jakarta.transaction.Transactional; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -51,15 +51,14 @@ public class AccessControlPermissionServiceImpl implements AccessControlPermissi @Override public Page findAll(final UUID id, - final Map immutableFilters, - final Pageable pageable) { - Map filters = new HashMap<>(immutableFilters); - filters.put("accessControlId", id.toString()); + final Map> immutableFilters, + final QueryFilter queryFilter) { + var filters = new HashMap<>(immutableFilters); + filters.put("accessControlId", List.of(id.toString())); return accessControlPermissionViewRepository.findAll( - new SpecificationHelper<>(AccessControlPermissionView.class, filters), - PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()) - ); + new CustomSpringQueryFilterSpecification<>(AccessControlPermissionView.class, filters), + queryFilter.getPageable()); } @Override diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlService.java b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlService.java index 719fa325..e4a87b7a 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlService.java @@ -1,13 +1,14 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDirectDTO; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; import com.ditrit.letomodelizerapi.persistence.model.AccessControl; import com.ditrit.letomodelizerapi.persistence.model.User; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -21,11 +22,11 @@ public interface AccessControlService { * Finds and returns a page of AccessControl entities of a specific type, filtered by provided criteria. * * @param type the AccessControlType to filter the AccessControl entities - * @param filters a Map of strings representing the filtering criteria - * @param pageable a Pageable object for pagination information + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AccessControl entities matching the specified type and filters */ - Page findAll(AccessControlType type, Map filters, Pageable pageable); + Page findAll(AccessControlType type, Map> filters, QueryFilter queryFilter); /** * Finds and returns a paginated list of AccessControlDirectDTOs representing the children access controls of a @@ -40,16 +41,16 @@ public interface AccessControlService { * @param type the AccessControlType of the parent AccessControl entity whose children are to be found * @param id the ID of the parent AccessControl entity * @param childrenType the AccessControlType to filter the children AccessControl entities by their specific type - * @param filters a Map of strings representing additional filtering criteria to apply - * @param pageable a Pageable object for pagination information + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AccessControlDirectDTOs representing the filtered children of the specified parent access * control */ Page findAllChildren(AccessControlType type, UUID id, AccessControlType childrenType, - Map filters, - Pageable pageable); + Map> filters, + QueryFilter queryFilter); /** * Finds and returns a paginated list of AccessControlDirectDTO entities of a specific type associated with a given @@ -58,14 +59,14 @@ Page findAllChildren(AccessControlType type, * * @param type the AccessControlType to filter the AccessControl entities * @param user the User object associated with the AccessControl entities - * @param filters a Map of strings representing the filtering criteria - * @param pageable a Pageable object for pagination information + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of AccessControlDirectDTO entities matching the specified type, user, and filters */ Page findAll(AccessControlType type, - User user, Map filters, - Pageable pageable); + User user, + Map> filters, + QueryFilter queryFilter); /** * Finds and returns a paginated list of Users associated with a specific AccessControl entity, filtered by @@ -75,31 +76,31 @@ Page findAll(AccessControlType type, * * @param type the AccessControlType to filter the AccessControl entities * @param id the ID of the AccessControl entity - * @param filters a Map of strings representing the filtering criteria - * @param pageable a Pageable object for pagination information + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of Users associated with the specified AccessControl entity */ - Page findAllUsers(AccessControlType type, UUID id, Map filters, Pageable pageable); + Page findAllUsers(AccessControlType type, + UUID id, + Map> filters, + QueryFilter queryFilter); /** * Retrieves all sub-access controls associated with a specific parent access control ID. - * + *

* This method is designed to find and return all sub-access controls for a given parent access control, identified * by its ID. It applies a set of filtering criteria and pagination to efficiently manage and return large datasets. * The method is essential for hierarchical access control systems where access controls may have multiple levels * of granularity or inheritance. + *

* * @param type the AccessControlType of the parent AccessControl entity whose children are to be found * @param id the ID of the parent access control for which sub-access controls are being searched. This ID uniquely * identifies an access control entity within the system. * @param subType the specific type of access control entities to retrieve, which helps in narrowing down the search * to relevant sub-categories or classifications of access controls. - * @param filters a map containing key-value pairs used for filtering the search results. These filters can apply to - * various attributes of the access controls, such as names, statuses, or custom properties, to - * refine the results further. - * @param pageable an object that encapsulates pagination and sorting criteria. This parameter allows the method to - * return a subset of the results in a manageable, paginated format, facilitating easier data - * handling and user interface rendering. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a {@code Page} object containing the sub-access controls associated with the * specified parent ID. This paginated object includes the subset of access controls that match the search criteria, * along with pagination details such as total results, current page number, and total pages available. @@ -107,8 +108,8 @@ Page findAll(AccessControlType type, Page findAllAccessControls(AccessControlType type, UUID id, AccessControlType subType, - Map filters, - Pageable pageable); + Map> filters, + QueryFilter queryFilter); /** * Finds and returns an AccessControl entity of a specific type by its ID. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImpl.java index 195afc10..b2e86a15 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImpl.java @@ -1,6 +1,7 @@ package com.ditrit.letomodelizerapi.service; import com.ditrit.letomodelizerapi.config.Constants; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.BeanMapper; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDirectDTO; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; @@ -21,27 +22,26 @@ import com.ditrit.letomodelizerapi.persistence.repository.AccessControlTreeViewRepository; import com.ditrit.letomodelizerapi.persistence.repository.UserAccessControlRepository; import com.ditrit.letomodelizerapi.persistence.repository.UserAccessControlViewRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; /** * Implementation of the AccessControlService interface. - * + *

* This class provides concrete implementations for the access control management operations defined in * AccessControlService. + *

* AccessControlServiceImpl interacts with the underlying repository layer to perform these operations, * ensuring that business logic and data access are effectively managed. */ @@ -104,33 +104,29 @@ public class AccessControlServiceImpl implements AccessControlService { @Override public Page findAll(final AccessControlType type, - final Map immutableFilters, - final Pageable pageable) { - Map filters = new HashMap<>(immutableFilters); - filters.put("type", type.name()); - - return accessControlRepository.findAll(new SpecificationHelper<>(AccessControl.class, filters), PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "name")))); + final Map> immutableFilters, + final QueryFilter queryFilter) { + var filters = new HashMap<>(immutableFilters); + filters.put("type", List.of(type.name())); + + return accessControlRepository.findAll( + new CustomSpringQueryFilterSpecification<>(AccessControl.class, filters), + queryFilter.getPageable(true, "name") + ); } @Override public Page findAll(final AccessControlType type, final User user, - final Map immutableFilters, - final Pageable pageable) { - Map filters = new HashMap<>(immutableFilters); - filters.put("type", type.name()); - filters.put("userId", user.getId().toString()); + final Map> immutableFilters, + final QueryFilter queryFilter) { + var filters = new HashMap<>(immutableFilters); + filters.put("type", List.of(type.name())); + filters.put("userId", List.of(user.getId().toString())); return userAccessControlViewRepository.findAll( - new SpecificationHelper<>(UserAccessControlView.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "name")) - ) + new CustomSpringQueryFilterSpecification<>(UserAccessControlView.class, filters), + queryFilter.getPageable(true, "name") ).map(new UserAccessControlViewToAccessControlDirectDTOFunction()); } @@ -138,37 +134,31 @@ public Page findAll(final AccessControlType type, public Page findAllChildren(final AccessControlType type, final UUID id, final AccessControlType childrenType, - final Map immutableFilters, - final Pageable pageable) { + final Map> immutableFilters, + final QueryFilter queryFilter) { AccessControl accessControl = findById(type, id); - Map filters = new HashMap<>(immutableFilters); - filters.put("type", childrenType.name()); - filters.put("parentId", accessControl.getId().toString()); + var filters = new HashMap<>(immutableFilters); + filters.put("type", List.of(childrenType.name())); + filters.put("parentId", List.of(accessControl.getId().toString())); return accessControlTreeViewRepository.findAll( - new SpecificationHelper<>(AccessControlTreeView.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "parentName")) - ) + new CustomSpringQueryFilterSpecification<>(AccessControlTreeView.class, filters), + queryFilter.getPageable(true, "parentName") ).map(new AccessControlTreeViewToAccessControlDirectDTOFunction(false)); } @Override public Page findAllUsers(final AccessControlType type, final UUID id, - final Map immutableFilters, - final Pageable pageable) { + final Map> immutableFilters, + final QueryFilter queryFilter) { AccessControl accessControl = findById(type, id); - Map filters = new HashMap<>(immutableFilters); - filters.put("accessControlId", accessControl.getId().toString()); - - return userAccessControlViewRepository.findAll(new SpecificationHelper<>(UserAccessControlView.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "userName"))) + var filters = new HashMap<>(immutableFilters); + filters.put("accessControlId", List.of(accessControl.getId().toString())); + + return userAccessControlViewRepository.findAll( + new CustomSpringQueryFilterSpecification<>(UserAccessControlView.class, filters), + queryFilter.getPageable(true, "userName") ).map(new UserAccesControlViewToUserFunction()); } @@ -176,25 +166,29 @@ public Page findAllUsers(final AccessControlType type, public Page findAllAccessControls(final AccessControlType type, final UUID id, final AccessControlType subType, - final Map immutableFilters, - final Pageable pageable) { + final Map> immutableFilters, + final QueryFilter queryFilter) { AccessControl accessControl = this.findById(type, id); - Map filters = new HashMap<>(immutableFilters); - filters.put("id", accessControl.getId().toString()); - filters.put("parentType", subType.name()); - - return accessControlTreeViewRepository.findAll(new SpecificationHelper<>(AccessControlTreeView.class, filters), - PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "parentName"))) + var filters = new HashMap<>(immutableFilters); + filters.put("id", List.of(accessControl.getId().toString())); + filters.put("parentType", List.of(subType.name())); + + return accessControlTreeViewRepository.findAll( + new CustomSpringQueryFilterSpecification<>(AccessControlTreeView.class, filters), + queryFilter.getPageable(true, "parentName") ).map(new AccessControlTreeViewToAccessControlDirectDTOFunction()); } @Override public AccessControl findById(final AccessControlType type, final UUID id) { - Map filters = Map.of("id", id.toString(), "type", type.name()); - return accessControlRepository.findOne(new SpecificationHelper<>(AccessControl.class, filters)) + Map> filters = Map.of( + "id", + List.of(id.toString()), + "type", + List.of(type.name()) + ); + return accessControlRepository.findOne( + new CustomSpringQueryFilterSpecification<>(AccessControl.class, filters)) .orElseThrow(() -> new ApiException(ErrorType.ENTITY_NOT_FOUND, "id", id.toString())); } diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/LibraryService.java b/src/main/java/com/ditrit/letomodelizerapi/service/LibraryService.java index 7933c551..ed3f6c19 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/LibraryService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/LibraryService.java @@ -1,14 +1,15 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.library.LibraryRecord; import com.ditrit.letomodelizerapi.persistence.model.Library; import com.ditrit.letomodelizerapi.persistence.model.LibraryTemplate; import com.ditrit.letomodelizerapi.persistence.model.User; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import java.net.http.HttpResponse; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -77,40 +78,40 @@ public interface LibraryService { /** * Finds all libraries that match the given filters and pagination settings. * - * @param filters a map of filter criteria - * @param pageable the pagination settings + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a page of Library entities */ - Page findAll(Map filters, Pageable pageable); + Page findAll(Map> filters, QueryFilter queryFilter); /** * Finds all libraries accessible to a given user that match the provided filters and pagination settings. * * @param user the user for which to find accessible libraries - * @param filters a map of filter criteria - * @param pageable the pagination settings + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a page of Library entities accessible to the given user */ - Page findAll(User user, Map filters, Pageable pageable); + Page findAll(User user, Map> filters, QueryFilter queryFilter); /** * Finds all library templates that match the given filters and pagination settings. * - * @param filters a map of filter criteria - * @param pageable the pagination settings + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a page of LibraryTemplate entities */ - Page findAllTemplates(Map filters, Pageable pageable); + Page findAllTemplates(Map> filters, QueryFilter queryFilter); /** * Finds all library templates accessible to a given user that match the provided filters and pagination settings. * * @param user the user for which to find accessible libraries - * @param filters a map of filter criteria - * @param pageable the pagination settings + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a page of LibraryTemplate entities accessible to the given user */ - Page findAllTemplates(User user, Map filters, Pageable pageable); + Page findAllTemplates(User user, Map> filters, QueryFilter queryFilter); /** * Retrieves a library template by its ID. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/LibraryServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/LibraryServiceImpl.java index 52f5c153..c3f92344 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/LibraryServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/LibraryServiceImpl.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; import com.ditrit.letomodelizerapi.model.error.ApiException; @@ -19,7 +20,7 @@ import com.ditrit.letomodelizerapi.persistence.repository.LibraryTemplateRepository; import com.ditrit.letomodelizerapi.persistence.repository.UserLibraryTemplateViewRepository; import com.ditrit.letomodelizerapi.persistence.repository.UserLibraryViewRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -36,8 +37,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -338,40 +337,42 @@ public void delete(final UUID id) { } @Override - public Page findAll(final Map filters, final Pageable pageable) { + public Page findAll(final Map> filters, + final QueryFilter queryFilter) { return libraryRepository.findAll( - new SpecificationHelper<>(Library.class, filters), - PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()) - ); + new CustomSpringQueryFilterSpecification<>(Library.class, filters), + queryFilter.getPageable()); } @Override - public Page findAll(final User user, final Map immutableFilters, final Pageable pageable) { - Map filters = new HashMap<>(immutableFilters); - filters.put("userId", user.getId().toString()); + public Page findAll(final User user, + final Map> immutableFilters, + final QueryFilter queryFilter) { + var filters = new HashMap<>(immutableFilters); + filters.put("userId", List.of(user.getId().toString())); return userLibraryViewRepository.findAll( - new SpecificationHelper<>(UserLibraryView.class, filters), - PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), pageable.getSort()) + new CustomSpringQueryFilterSpecification<>(UserLibraryView.class, filters), + queryFilter.getPageable() ).map(new UserLibraryViewToLibraryFunction()); } @Override - public Page findAllTemplates(final Map filters, final Pageable pageable) { + public Page findAllTemplates(final Map> filters, + final QueryFilter queryFilter) { return libraryTemplateRepository.findAll( - new SpecificationHelper<>(LibraryTemplate.class, filters), - PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), pageable.getSort()) - ); + new CustomSpringQueryFilterSpecification<>(LibraryTemplate.class, filters), + queryFilter.getPageable()); } @Override public Page findAllTemplates(final User user, - final Map filters, - final Pageable pageable) { + final Map> filters, + final QueryFilter queryFilter) { return userLibraryTemplateViewRepository.findAllByUserId( user.getId(), - new SpecificationHelper<>(UserLibraryTemplateView.class, filters), - PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), pageable.getSort()) + new CustomSpringQueryFilterSpecification<>(UserLibraryTemplateView.class, filters), + queryFilter.getPageable() ).map(new UserLibraryTemplateViewToLibraryTemplateFunction()); } diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/PermissionService.java b/src/main/java/com/ditrit/letomodelizerapi/service/PermissionService.java index 1ff2704e..c7a90516 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/PermissionService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/PermissionService.java @@ -1,11 +1,12 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.persistence.model.AccessControl; import com.ditrit.letomodelizerapi.persistence.model.Library; import com.ditrit.letomodelizerapi.persistence.model.Permission; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -17,11 +18,11 @@ public interface PermissionService { /** * Finds and returns a page of Permission entities of a specific type, filtered by provided criteria. * - * @param filters a Map of strings representing the filtering criteria - * @param pageable a Pageable object for pagination information + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page of Permission entities matching the specified type and filters */ - Page findAll(Map filters, Pageable pageable); + Page findAll(Map> filters, QueryFilter queryFilter); /** * Retrieves a {@link Permission} entity by its unique identifier. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/PermissionServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/PermissionServiceImpl.java index edc723f6..562593a2 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/PermissionServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/PermissionServiceImpl.java @@ -1,6 +1,7 @@ package com.ditrit.letomodelizerapi.service; import com.ditrit.letomodelizerapi.config.Constants; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.model.permission.ActionPermission; @@ -10,17 +11,15 @@ import com.ditrit.letomodelizerapi.persistence.model.Permission; import com.ditrit.letomodelizerapi.persistence.repository.AccessControlRepository; import com.ditrit.letomodelizerapi.persistence.repository.PermissionRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import jakarta.transaction.Transactional; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -57,11 +56,11 @@ public class PermissionServiceImpl implements PermissionService { private AccessControlPermissionService accessControlPermissionService; @Override - public Page findAll(final Map filters, final Pageable pageable) { - return permissionRepository.findAll(new SpecificationHelper<>(Permission.class, filters), PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "entity")))); + public Page findAll(final Map> filters, + final QueryFilter queryFilter) { + return permissionRepository.findAll( + new CustomSpringQueryFilterSpecification<>(Permission.class, filters), + queryFilter.getPageable(true, "entity")); } @Override diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionService.java b/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionService.java index 44e16425..f98ff22e 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionService.java @@ -1,11 +1,11 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.permission.ActionPermission; import com.ditrit.letomodelizerapi.model.permission.EntityPermission; import com.ditrit.letomodelizerapi.persistence.model.Permission; import com.ditrit.letomodelizerapi.persistence.model.User; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import java.util.List; import java.util.Map; @@ -38,14 +38,12 @@ public interface UserPermissionService { * * @param user the User object for whom the permissions are being queried. This can be used to limit the search to * permissions relevant to the user, either directly or through roles and groups the user belongs to. - * @param filters a map containing key-value pairs representing the filters to apply to the search. Each entry in - * the map corresponds to a field and value to filter by. - * @param pageable a Pageable object specifying the pagination information such as page number, size, and sort - * order. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return a Page containing the permissions that match the given user, filters, and pagination * settings. */ - Page findAll(User user, Map filters, Pageable pageable); + Page findAll(User user, Map> filters, QueryFilter queryFilter); /** * Checks if a given user has permission for a specific action on an entity. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImpl.java index 50efa98d..a9c7914a 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImpl.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.model.permission.ActionPermission; @@ -9,15 +10,12 @@ import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.persistence.model.UserPermission; import com.ditrit.letomodelizerapi.persistence.repository.UserPermissionRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import jakarta.transaction.Transactional; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.util.HashMap; @@ -73,17 +71,15 @@ public List getAllPermissions(final User user) { @Override public Page findAll(final User user, - final Map immutableFilters, - final Pageable pageable) { - Map filters = new HashMap<>(immutableFilters); - filters.put(USER_ID, user.getId().toString()); + final Map> immutableFilters, + final QueryFilter queryFilter) { + var filters = new HashMap<>(immutableFilters); + filters.put(USER_ID, List.of(user.getId().toString())); return this.userPermissionRepository.findAll( - new SpecificationHelper<>(UserPermission.class, filters), PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, LIBRARY_ENTITY, LIBRARY_ACTION)))) - .map(new UserPermissionToPermissionFunction()); + new CustomSpringQueryFilterSpecification<>(UserPermission.class, filters), + queryFilter.getPageable(true, LIBRARY_ENTITY, LIBRARY_ACTION) + ).map(new UserPermissionToPermissionFunction()); } @Override @@ -91,13 +87,14 @@ public boolean hasPermission( final User user, final EntityPermission entity, final ActionPermission action) { - Map filters = new HashMap<>(); - filters.put(USER_ID, user.getId().toString()); - filters.put(LIBRARY_ENTITY, entity.name()); - filters.put(LIBRARY_ACTION, action.name()); - filters.put(LIBRARY_ID, null); - - return userPermissionRepository.exists(new SpecificationHelper<>(UserPermission.class, filters)); + Map> filters = new HashMap<>(); + filters.put(USER_ID, List.of(user.getId().toString())); + filters.put(LIBRARY_ENTITY, List.of(entity.name())); + filters.put(LIBRARY_ACTION, List.of(action.name())); + filters.put(LIBRARY_ID, List.of()); + + return userPermissionRepository.exists( + new CustomSpringQueryFilterSpecification<>(UserPermission.class, filters)); } @Override @@ -119,19 +116,20 @@ public void checkIsAdmin(final User user, final String field) { @Override public void checkLibraryPermission(final User user, final ActionPermission action, final UUID id) { String libraryId = null; - Map filters = new HashMap<>(); - filters.put(USER_ID, user.getId().toString()); - filters.put(LIBRARY_ENTITY, EntityPermission.LIBRARY.name()); - filters.put(LIBRARY_ACTION, action.name()); + Map> filters = new HashMap<>(); + filters.put(USER_ID, List.of(user.getId().toString())); + filters.put(LIBRARY_ENTITY, List.of(EntityPermission.LIBRARY.name())); + filters.put(LIBRARY_ACTION, List.of(action.name())); if (id == null) { - filters.put(LIBRARY_ID, "null"); + filters.put(LIBRARY_ID, List.of("null")); } else { libraryId = id.toString(); - filters.put(LIBRARY_ID, String.format("null|%s", libraryId)); + filters.put(LIBRARY_ID, List.of(String.format("null|%s", libraryId))); } - if (userPermissionRepository.exists(new SpecificationHelper<>(UserPermission.class, filters))) { + if (userPermissionRepository.exists( + new CustomSpringQueryFilterSpecification<>(UserPermission.class, filters))) { return; } diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/UserService.java b/src/main/java/com/ditrit/letomodelizerapi/service/UserService.java index 6745e807..0f8748c4 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/UserService.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/UserService.java @@ -1,12 +1,13 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.user.UserRecord; import com.ditrit.letomodelizerapi.persistence.model.User; import jakarta.servlet.http.HttpSession; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import java.net.http.HttpResponse; +import java.util.List; import java.util.Map; /** @@ -59,11 +60,11 @@ public interface UserService { * This method allows for dynamic querying of users based on specified filters * and includes pagination and sorting functionality. * - * @param filters A map of string key-value pairs representing the filtering criteria. - * @param pageable The pagination and sorting information. + * @param filters a Map of strings representing the filtering criteria. + * @param queryFilter a Pageable object for pagination information. * @return A {@link Page} containing users that match the filtering criteria. */ - Page findAll(Map filters, Pageable pageable); + Page findAll(Map> filters, QueryFilter queryFilter); /** * Retrieves a user by their login identifier. diff --git a/src/main/java/com/ditrit/letomodelizerapi/service/UserServiceImpl.java b/src/main/java/com/ditrit/letomodelizerapi/service/UserServiceImpl.java index 7d13afef..69e7fcf2 100644 --- a/src/main/java/com/ditrit/letomodelizerapi/service/UserServiceImpl.java +++ b/src/main/java/com/ditrit/letomodelizerapi/service/UserServiceImpl.java @@ -1,12 +1,13 @@ package com.ditrit.letomodelizerapi.service; import com.ditrit.letomodelizerapi.config.Constants; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.model.user.UserRecord; import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.persistence.repository.UserRepository; -import com.ditrit.letomodelizerapi.persistence.specification.SpecificationHelper; +import com.ditrit.letomodelizerapi.persistence.specification.CustomSpringQueryFilterSpecification; import jakarta.servlet.http.HttpSession; import jakarta.transaction.Transactional; import lombok.AllArgsConstructor; @@ -14,9 +15,6 @@ import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -26,6 +24,7 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.util.List; import java.util.Map; /** @@ -118,11 +117,11 @@ public HttpResponse getPicture(final User user) { } @Override - public Page findAll(final Map filters, final Pageable pageable) { - return this.userRepository.findAll(new SpecificationHelper<>(User.class, filters), PageRequest.of( - pageable.getPageNumber(), - pageable.getPageSize(), - pageable.getSortOr(Sort.by(Sort.Direction.ASC, "name")))); + public Page findAll(final Map> filters, + final QueryFilter queryFilter) { + return this.userRepository.findAll( + new CustomSpringQueryFilterSpecification<>(User.class, filters), + queryFilter.getPageable(true, "name")); } @Override diff --git a/src/test/java/com/ditrit/letomodelizerapi/config/JerseyConfigTest.java b/src/test/java/com/ditrit/letomodelizerapi/config/JerseyConfigTest.java deleted file mode 100644 index 2033ee0f..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/config/JerseyConfigTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.ditrit.letomodelizerapi.config; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertNull; - -@Tag("unit") -@DisplayName("Test class: JerseyConfig") -class JerseyConfigTest { - @Test - @DisplayName("Test constructor: should not throw exception") - void testConstructorShouldNotThrowException() { - Exception exception = null; - - try { - new JerseyConfig(""); - } catch (Exception e) { - exception = e; - } - - assertNull(exception); - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/AIConfigurationControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/AIConfigurationControllerTest.java index 8587d20a..b49e1285 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/AIConfigurationControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/AIConfigurationControllerTest.java @@ -2,6 +2,7 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.ai.AIConfigurationDTO; import com.ditrit.letomodelizerapi.model.ai.AIConfigurationRecord; import com.ditrit.letomodelizerapi.model.ai.UpdateMultipleAIConfigurationRecord; import com.ditrit.letomodelizerapi.persistence.model.AIConfiguration; @@ -13,7 +14,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -22,11 +22,14 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -69,11 +72,11 @@ void testGetAllConfigurations() { Mockito.when(this.aiConfigurationService.findAll(Mockito.any(), Mockito.any())) .thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.getAllConfigurations(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getAllConfigurations(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -90,11 +93,11 @@ void testGetConfigurationById() { Mockito.any()); Mockito.when(this.aiConfigurationService.findById(Mockito.any())).thenReturn(new AIConfiguration()); - final Response response = this.controller.getConfigurationById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getConfigurationById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -113,12 +116,12 @@ void testCreateConfiguration() { Mockito.when(this.aiSecretService.generateConfiguration()).thenReturn("test".getBytes()); Mockito.doNothing().when(this.aiService).sendConfiguration(Mockito.any()); - final Response response = this.controller.createConfiguration(request, + final ResponseEntity response = this.controller.createConfiguration(request, new AIConfigurationRecord("handler","key", "value")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -138,12 +141,12 @@ void testUpdateConfiguration() { Mockito.when(this.aiSecretService.generateConfiguration()).thenReturn("test".getBytes()); Mockito.doNothing().when(this.aiService).sendConfiguration(Mockito.any()); - final Response response = this.controller.updateConfiguration(request, UUID.randomUUID(), + final ResponseEntity response = this.controller.updateConfiguration(request, UUID.randomUUID(), new AIConfigurationRecord("handler", "key", "value")); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -163,12 +166,12 @@ void testUpdateConfigurations() { Mockito.when(this.aiSecretService.generateConfiguration()).thenReturn("test".getBytes()); Mockito.doNothing().when(this.aiService).sendConfiguration(Mockito.any()); - final Response response = this.controller.updateConfiguration(request, + final ResponseEntity> response = this.controller.updateConfiguration(request, List.of(new UpdateMultipleAIConfigurationRecord(UUID.randomUUID(), "handler", "key", "value"))); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -188,10 +191,10 @@ void testDeleteConfiguration() { Mockito.when(this.aiSecretService.generateConfiguration()).thenReturn("test".getBytes()); Mockito.doNothing().when(this.aiService).sendConfiguration(Mockito.any()); - final Response response = this.controller.deleteConfiguration(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.deleteConfiguration(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + assertNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/AIControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/AIControllerTest.java index e3a421c4..ac25a1bf 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/AIControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/AIControllerTest.java @@ -2,8 +2,10 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.ai.AIConversationDTO; import com.ditrit.letomodelizerapi.model.ai.AIConversationRecord; import com.ditrit.letomodelizerapi.model.ai.AICreateFileRecord; +import com.ditrit.letomodelizerapi.model.ai.AIMessageDTO; import com.ditrit.letomodelizerapi.model.ai.AIMessageRecord; import com.ditrit.letomodelizerapi.persistence.model.AIConversation; import com.ditrit.letomodelizerapi.persistence.model.AIMessage; @@ -15,7 +17,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -26,9 +27,11 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.io.IOException; import java.util.List; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -67,11 +70,11 @@ void testGenerateFiles() { .thenReturn(session); Mockito.when(aiService.createFile(aiCreateFileRecord)).thenReturn("OK"); - final Response response = this.controller.generateFiles(request, aiCreateFileRecord); + final ResponseEntity response = this.controller.generateFiles(request, aiCreateFileRecord); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -92,11 +95,11 @@ void testCreateConversations() throws JsonProcessingException { Mockito.when(userService.getFromSession(Mockito.any())).thenReturn(user); Mockito.when(aiService.createConversation(user, aiConversationRecord)).thenReturn(new AIConversation()); - Response response = this.controller.createConversations(request, aiConversationRecord); + ResponseEntity response = this.controller.createConversations(request, aiConversationRecord); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -112,11 +115,11 @@ void testFindAllConversations() { Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(aiService.findAllConversations(Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - Response response = this.controller.findAllConversations(request, mockUriInfo(), new QueryFilter()); + ResponseEntity> response = this.controller.findAllConversations(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -131,11 +134,11 @@ void testGetConversationById() { Mockito.when(userService.getFromSession(Mockito.any())).thenReturn(user); Mockito.when(aiService.getConversationById(Mockito.any(), Mockito.any())).thenReturn(new AIConversation()); - Response response = this.controller.getConversationById(request, UUID.randomUUID()); + ResponseEntity response = this.controller.getConversationById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -157,11 +160,11 @@ void testUpdateConversationById() throws JsonProcessingException { Mockito.when(userService.getFromSession(Mockito.any())).thenReturn(user); Mockito.when(aiService.updateConversationById(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new AIConversation()); - Response response = this.controller.updateConversationById(request, UUID.randomUUID(), aiConversationRecord); + ResponseEntity response = this.controller.updateConversationById(request, UUID.randomUUID(), aiConversationRecord); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -177,10 +180,10 @@ void testDeleteConversationById() { Mockito.when(userPermissionService.hasPermission(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(false); Mockito.doNothing().when(aiService).deleteConversationById(Mockito.any(), Mockito.any()); - Response response = this.controller.deleteConversationById(request, UUID.randomUUID()); + ResponseEntity response = this.controller.deleteConversationById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); Mockito.verify(aiService, Mockito.times(0)).deleteConversationById(Mockito.any()); Mockito.verify(aiService, Mockito.times(1)).deleteConversationById(Mockito.any(), Mockito.any()); } @@ -198,10 +201,10 @@ void testDeleteConversationByIdAsAdmin() { Mockito.when(userPermissionService.hasPermission(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true); Mockito.doNothing().when(aiService).deleteConversationById(Mockito.any()); - Response response = this.controller.deleteConversationById(request, UUID.randomUUID()); + ResponseEntity response = this.controller.deleteConversationById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); Mockito.verify(aiService, Mockito.times(1)).deleteConversationById(Mockito.any()); Mockito.verify(aiService, Mockito.times(0)).deleteConversationById(Mockito.any(), Mockito.any()); } @@ -220,11 +223,11 @@ void testCreateConversationMessage() throws IOException { Mockito.when(userService.getFromSession(Mockito.any())).thenReturn(user); Mockito.when(aiService.sendMessage(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(message); - Response response = this.controller.createConversationMessage(request, UUID.randomUUID(), new AIMessageRecord("ok", "plugin")); + ResponseEntity response = this.controller.createConversationMessage(request, UUID.randomUUID(), new AIMessageRecord("ok", "plugin")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -240,11 +243,11 @@ void testFindAllMessages() { Mockito.when(aiService.findAllMessages(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - Response response = this.controller.findAllMessages(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + ResponseEntity> response = this.controller.findAllMessages(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -258,11 +261,11 @@ void testSendConfigurationToProxy() { Mockito.when(aiSecretService.generateConfiguration()).thenReturn(new byte[0]); Mockito.doNothing().when(aiService).sendConfiguration(Mockito.any()); - Response response = this.controller.sendConfigurationToProxy(request); + ResponseEntity response = this.controller.sendConfigurationToProxy(request); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -279,10 +282,10 @@ void testRetrieveConfigurationDescriptions() { Mockito.doNothing().when(userPermissionService).checkPermission(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - Response response = this.controller.retrieveConfigurationDescriptions(request); + ResponseEntity response = this.controller.retrieveConfigurationDescriptions(request); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertEquals("test", response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("test", response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/AISecretControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/AISecretControllerTest.java index ae63a91e..77f2a061 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/AISecretControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/AISecretControllerTest.java @@ -2,6 +2,7 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.ai.AISecretDTO; import com.ditrit.letomodelizerapi.model.ai.AISecretRecord; import com.ditrit.letomodelizerapi.persistence.model.AISecret; import com.ditrit.letomodelizerapi.persistence.model.User; @@ -10,7 +11,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -19,10 +19,13 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.util.ArrayList; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -59,11 +62,11 @@ void testGetAllSecrets() { Mockito.when(this.aiSecretService.findAll(Mockito.any(), Mockito.any())) .thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.getAllSecrets(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getAllSecrets(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -80,11 +83,11 @@ void testGetSecretById() { Mockito.any()); Mockito.when(this.aiSecretService.findById(Mockito.any())).thenReturn(new AISecret()); - final Response response = this.controller.getSecretById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getSecretById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -101,11 +104,11 @@ void testCreateSecret() { Mockito.any()); Mockito.when(this.aiSecretService.create(Mockito.any())).thenReturn(new AISecret()); - final Response response = this.controller.createSecret(request, new AISecretRecord("key", "value")); + final ResponseEntity response = this.controller.createSecret(request, new AISecretRecord("key", "value")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -123,12 +126,12 @@ void testUpdateSecret() { Mockito.when(this.aiSecretService.update(Mockito.any(), Mockito.any())) .thenReturn(new AISecret()); - final Response response = this.controller.updateSecret(request, UUID.randomUUID(), + final ResponseEntity response = this.controller.updateSecret(request, UUID.randomUUID(), new AISecretRecord("key", "value")); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -145,10 +148,10 @@ void testDeleteSecret() { Mockito.any()); Mockito.doNothing().when(aiSecretService).delete(Mockito.any()); - final Response response = this.controller.deleteSecret(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.deleteSecret(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + assertNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/CsrfControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/CsrfControllerTest.java index 8c1f8d08..56bf922d 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/CsrfControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/CsrfControllerTest.java @@ -7,7 +7,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -51,7 +50,7 @@ void testHome() { Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(userCsrfTokenService.findByLogin(Mockito.any())).thenReturn(new UserCsrfToken()); - Response response = controller.getCsrfToken(request); - assertNotNull(response.getEntity()); + var response = controller.getCsrfToken(request); + assertNotNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/CurrentUserControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/CurrentUserControllerTest.java index 20c0722d..6711be85 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/CurrentUserControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/CurrentUserControllerTest.java @@ -2,6 +2,8 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; +import com.ditrit.letomodelizerapi.model.ai.AIConversationDTO; import com.ditrit.letomodelizerapi.model.permission.ActionPermission; import com.ditrit.letomodelizerapi.model.permission.EntityPermission; import com.ditrit.letomodelizerapi.model.permission.PermissionDTO; @@ -14,7 +16,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -25,6 +26,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.net.http.HttpHeaders; import java.net.http.HttpResponse; @@ -80,11 +82,11 @@ void testGetMyInformation() { .when(userService.getFromSession(Mockito.any())) .thenReturn(user); - Response response = currentUserController.getMyInformation(request); + ResponseEntity response = currentUserController.getMyInformation(request); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertEquals(expectedUser, response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(expectedUser, response.getBody()); } @Test @@ -121,10 +123,10 @@ void testGetPicture() { .when(userService.getPicture(Mockito.any())) .thenReturn(picture); - Response response = controller.getMyPicture(request); + ResponseEntity response = controller.getMyPicture(request); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -161,11 +163,11 @@ void testGetMyPermissions() { expectedPermission.setLibraryId(permission.getLibraryId()); List expectedPermissions = List.of(expectedPermission); - Response response = currentUserController.getMyPermissions(request); + ResponseEntity> response = currentUserController.getMyPermissions(request); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertEquals(expectedPermissions, response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(expectedPermissions, response.getBody()); } @Test @@ -187,11 +189,11 @@ void testGetMyRoles() { .when(accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - Response response = currentUserController.getMyRoles(request, mockUriInfo(), new QueryFilter()); + ResponseEntity> response = currentUserController.getMyRoles(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -213,11 +215,11 @@ void testGetMyGroups() { .when(accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - Response response = currentUserController.getMyGroups(request, mockUriInfo(), new QueryFilter()); + ResponseEntity> response = currentUserController.getMyGroups(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -239,11 +241,11 @@ void testGetMyScopes() { .when(accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - Response response = currentUserController.getMyScopes(request, mockUriInfo(), new QueryFilter()); + ResponseEntity> response = currentUserController.getMyScopes(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -265,10 +267,10 @@ void testMyAIConversations() { .when(aiService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - Response response = currentUserController.getMyAIConversations(request, mockUriInfo(), new QueryFilter()); + ResponseEntity> response = currentUserController.getMyAIConversations(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/DefaultControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/DefaultControllerTest.java index e72e5096..97aa69a7 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/DefaultControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/DefaultControllerTest.java @@ -7,7 +7,6 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; -import java.util.HashMap; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -17,13 +16,6 @@ class DefaultControllerTest extends MockHelper { class ControllerTest implements DefaultController {}; - @Test - @DisplayName("Test getFilters: should return map of filters") - void testGetFilters() { - HashMap map = new HashMap<>(); - assertEquals(map, new ControllerTest().getFilters(mockUriInfo())); - } - @Test @DisplayName("Test getStatus: should return 200 on complete response.") void testGetStatusComplete() { diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/GroupControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/GroupControllerTest.java index bca9ecc6..1ca1442f 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/GroupControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/GroupControllerTest.java @@ -2,7 +2,11 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDirectDTO; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; +import com.ditrit.letomodelizerapi.model.permission.PermissionDirectDTO; +import com.ditrit.letomodelizerapi.model.user.UserDTO; import com.ditrit.letomodelizerapi.persistence.model.AccessControl; import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.service.AccessControlPermissionService; @@ -11,7 +15,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -23,8 +26,10 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.util.ArrayList; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -64,11 +69,11 @@ void testFindAll() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAll(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAll(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -86,11 +91,11 @@ void testGetGroupById() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findById(Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.getGroupById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getGroupById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -108,11 +113,11 @@ void testCreateGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.create(Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.createGroup(request, new AccessControlRecord("test")); + final ResponseEntity response = this.controller.createGroup(request, new AccessControlRecord("test")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -130,11 +135,11 @@ void testUpdateGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.update(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.updateGroup(request, UUID.randomUUID(), new AccessControlRecord("test")); + final ResponseEntity response = this.controller.updateGroup(request, UUID.randomUUID(), new AccessControlRecord("test")); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -152,10 +157,10 @@ void testDeleteGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).delete(Mockito.any(), Mockito.any()); - final Response response = this.controller.deleteGroup(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.deleteGroup(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -173,11 +178,11 @@ void testGetUsersByGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllUsers(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getUsersByGroup(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getUsersByGroup(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -195,11 +200,11 @@ void testAssociateUser() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associateUser(Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associateUser(request, UUID.randomUUID(), "login"); + final ResponseEntity response = this.controller.associateUser(request, UUID.randomUUID(), "login"); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -217,10 +222,10 @@ void testDissociateUser() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociateUser(Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociateUser(request, UUID.randomUUID(), "login"); + final ResponseEntity response = this.controller.dissociateUser(request, UUID.randomUUID(), "login"); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -238,11 +243,11 @@ void testGetSubGroupsOfGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllAccessControls(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getSubGroupsOfGroup(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getSubGroupsOfGroup(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -260,11 +265,11 @@ void testAssociate() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associate(request, UUID.randomUUID(), UUID.randomUUID().toString()); + final ResponseEntity response = this.controller.associate(request, UUID.randomUUID(), UUID.randomUUID().toString()); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -282,10 +287,10 @@ void testDissociate() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociate(request, UUID.randomUUID(), UUID.randomUUID()); + final ResponseEntity response = this.controller.dissociate(request, UUID.randomUUID(), UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -303,11 +308,11 @@ void testGetRolesOfGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllAccessControls(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getRolesOfGroup(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getRolesOfGroup(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -325,11 +330,11 @@ void testGetScopesOfGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllAccessControls(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getScopesOfGroup(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getScopesOfGroup(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -352,10 +357,10 @@ void testGetPermissionsOfGroup() { Mockito .when(this.accessControlPermissionService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getPermissionsOfGroup(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getPermissionsOfGroup(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/HomeControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/HomeControllerTest.java index 2223762c..70fe4823 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/HomeControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/HomeControllerTest.java @@ -4,7 +4,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -13,8 +12,10 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.util.ReflectionTestUtils; +import java.io.InputStream; import java.net.URISyntaxException; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -36,11 +37,11 @@ HomeController newInstance() { @DisplayName("Test home: should return valid response") void testHome() { HomeController controller = newInstance(); - Response response = controller.home(); + ResponseEntity response = controller.home(); assertNotNull(response); - assertNotNull(response.getEntity()); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertNotNull(response.getBody()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -58,10 +59,10 @@ void testRedirect() throws URISyntaxException { .thenReturn(session); HomeController controller = newInstance(); ReflectionTestUtils.setField(controller, "letoModelizerUrl", "http://localhost:8080/"); - Response response = controller.redirect(request, null); + ResponseEntity response = controller.redirect(request, null); assertNotNull(response); - assertEquals("http://localhost:8080/", response.getLocation().toString()); + assertEquals("http://localhost:8080/", response.getHeaders().getLocation().toString()); } @Test @@ -80,10 +81,10 @@ void testRedirectAdmin() throws URISyntaxException { HomeController controller = newInstance(); ReflectionTestUtils.setField(controller, "letoModelizerUrl", "http://localhost:8080/"); ReflectionTestUtils.setField(controller, "letoAdminUrl", "http://localhost:9000/"); - Response response = controller.redirect(request, "admin"); + ResponseEntity response = controller.redirect(request, "admin"); assertNotNull(response); - assertEquals("http://localhost:9000/", response.getLocation().toString()); + assertEquals("http://localhost:9000/", response.getHeaders().getLocation().toString()); } @@ -91,9 +92,9 @@ void testRedirectAdmin() throws URISyntaxException { @DisplayName("Test redirect: should redirect to github oauth endpoint.") void testLogin() { HomeController controller = newInstance(); - Response response = controller.login(); + ResponseEntity response = controller.login(); assertNotNull(response); - assertEquals("/api/oauth2/authorization/github", response.getLocation().toString()); + assertEquals("/api/oauth2/authorization/github", response.getHeaders().getLocation().toString()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/LibraryControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/LibraryControllerTest.java index 594997c3..c852806a 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/LibraryControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/LibraryControllerTest.java @@ -2,6 +2,7 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.library.LibraryDTO; import com.ditrit.letomodelizerapi.model.library.LibraryRecord; import com.ditrit.letomodelizerapi.persistence.model.Library; import com.ditrit.letomodelizerapi.persistence.model.LibraryTemplate; @@ -12,7 +13,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -21,10 +21,11 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; -import java.net.http.HttpHeaders; import java.net.http.HttpResponse; import java.util.ArrayList; import java.util.HashMap; @@ -67,11 +68,11 @@ void testFindAllWithPermissionAllLibraries() { .thenReturn(session); Mockito.when(userPermissionService.hasPermission(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true); Mockito.when(this.libraryService.findAll(Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAll(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAll(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -89,11 +90,11 @@ void testFindAllWithPermissionSpecificLibraries() { .thenReturn(session); Mockito.when(userPermissionService.hasPermission(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(false); Mockito.when(this.libraryService.findAll(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAll(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAll(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -111,11 +112,11 @@ void testGetLibraryById() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.when(this.libraryService.findById(Mockito.any())).thenReturn(new Library()); - final Response response = this.controller.getLibraryById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getLibraryById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -131,11 +132,11 @@ void testCreateLibrary() throws JsonProcessingException { Mockito.when(userService.getFromSession(Mockito.any())).thenReturn(user); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.when(this.libraryService.create(Mockito.any(), Mockito.any())).thenReturn(new Library()); - final Response response = this.controller.createLibrary(request, new LibraryRecord("url", "role")); + final ResponseEntity response = this.controller.createLibrary(request, new LibraryRecord("url", "role")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -151,10 +152,10 @@ void testValidateLibrary() { Mockito.when(userService.getFromSession(Mockito.any())).thenReturn(user); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.libraryService).validateLibrary(Mockito.any()); - final Response response = this.controller.validateLibrary(request, "url"); + final ResponseEntity response = this.controller.validateLibrary(request, "url"); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -172,10 +173,10 @@ void testUpdateLibrary() throws JsonProcessingException { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.libraryService).update(Mockito.any(), Mockito.any()); - final Response response = this.controller.updateLibrary(request, UUID.randomUUID(), "url"); + final ResponseEntity response = this.controller.updateLibrary(request, UUID.randomUUID(), "url"); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -193,10 +194,10 @@ void testDeleteLibrary() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.libraryService).delete(Mockito.any()); - final Response response = this.controller.deleteLibrary(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.deleteLibrary(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -214,11 +215,11 @@ void testFindAllTemplatesWithPermissionAllLibraries() { .thenReturn(session); Mockito.when(userPermissionService.hasPermission(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true); Mockito.when(this.libraryService.findAllTemplates(Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAllTemplates(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAllTemplates(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -236,11 +237,11 @@ void testFindAllTemplatesWithPermissionSpecificLibraries() { .thenReturn(session); Mockito.when(userPermissionService.hasPermission(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(false); Mockito.when(this.libraryService.findAllTemplates(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAllTemplates(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAllTemplates(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -256,7 +257,6 @@ void testGetIcon() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); HttpResponse icon = Mockito.mock(HttpResponse.class); Map> headers = new HashMap<>(); - Mockito.when(icon.headers()).thenReturn(HttpHeaders.of(headers, (s, s2) -> true)); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito @@ -266,10 +266,10 @@ void testGetIcon() { .when(libraryService.getIcon(Mockito.any())) .thenReturn(icon); - Response response = controller.getLibraryIcon(request, UUID.randomUUID()); + ResponseEntity response = controller.getLibraryIcon(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -287,11 +287,11 @@ void testGetLibraryTemplates() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.when(this.libraryService.findAllTemplates(Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.getLibraryTemplates(request, mockUriInfo(), new QueryFilter(), UUID.randomUUID()); + final ResponseEntity> response = this.controller.getLibraryTemplates(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -309,11 +309,11 @@ void testGetTemplatesById() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.when(this.libraryService.getTemplateById(Mockito.any())).thenReturn(new LibraryTemplate()); - final Response response = this.controller.getTemplatesById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getTemplatesById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -329,7 +329,6 @@ void testGetTemplateIcon() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); HttpResponse icon = Mockito.mock(HttpResponse.class); Map> headers = new HashMap<>(); - Mockito.when(icon.headers()).thenReturn(HttpHeaders.of(headers, (s, s2) -> true)); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito @@ -342,10 +341,10 @@ void testGetTemplateIcon() { .when(libraryService.getTemplateById(Mockito.any())) .thenReturn(new LibraryTemplate()); - Response response = controller.getTemplateIcon(request, UUID.randomUUID()); + ResponseEntity response = controller.getTemplateIcon(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -361,7 +360,6 @@ void testGetTemplateSchema() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); HttpResponse icon = Mockito.mock(HttpResponse.class); Map> headers = new HashMap<>(); - Mockito.when(icon.headers()).thenReturn(HttpHeaders.of(headers, (s, s2) -> true)); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito @@ -377,10 +375,10 @@ void testGetTemplateSchema() { .when(libraryService.getFileName(Mockito.anyBoolean(), Mockito.any(), Mockito.any())) .thenReturn("test"); - Response response = controller.getTemplateSchema(request, UUID.randomUUID(), 1L); + ResponseEntity response = controller.getTemplateSchema(request, UUID.randomUUID(), 1L); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -396,7 +394,6 @@ void testGetTemplateFile() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); HttpResponse file = Mockito.mock(HttpResponse.class); Map> headers = new HashMap<>(); - Mockito.when(file.headers()).thenReturn(HttpHeaders.of(headers, (s, s2) -> true)); Mockito.doNothing().when(userPermissionService).checkLibraryPermission(Mockito.any(), Mockito.any(), Mockito.any()); Mockito @@ -405,16 +402,15 @@ void testGetTemplateFile() { Mockito .when(libraryService.getTemplateFile(Mockito.any(), Mockito.any())) .thenReturn(file); + LibraryTemplate template = new LibraryTemplate(); + template.setFiles(List.of("test")); Mockito .when(libraryService.getTemplateById(Mockito.any())) - .thenReturn(new LibraryTemplate()); - Mockito - .when(libraryService.getFileName(Mockito.anyBoolean(), Mockito.any(), Mockito.any())) - .thenReturn("test"); + .thenReturn(template); - Response response = controller.getTemplateFile(request, UUID.randomUUID(), 1L); + ResponseEntity response = controller.getTemplateFile(request, UUID.randomUUID(), 0L); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/PermissionControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/PermissionControllerTest.java index 3c177d5d..44c425af 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/PermissionControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/PermissionControllerTest.java @@ -2,13 +2,13 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.persistence.model.Permission; import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.service.PermissionService; import com.ditrit.letomodelizerapi.service.UserPermissionService; import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -19,6 +19,9 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -51,9 +54,9 @@ void testFindAll() { Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(permissionService.findAll(Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - Response response = this.controller.findAll(request, mockUriInfo(), new QueryFilter()); + ResponseEntity> response = this.controller.findAll(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/RoleControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/RoleControllerTest.java index c705a816..c7eb6dc0 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/RoleControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/RoleControllerTest.java @@ -2,9 +2,13 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDirectDTO; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; +import com.ditrit.letomodelizerapi.model.permission.PermissionDirectDTO; +import com.ditrit.letomodelizerapi.model.user.UserDTO; import com.ditrit.letomodelizerapi.persistence.model.AccessControl; import com.ditrit.letomodelizerapi.persistence.model.Permission; import com.ditrit.letomodelizerapi.persistence.model.User; @@ -15,7 +19,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -27,8 +30,10 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.util.ArrayList; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -71,11 +76,11 @@ void testFindAll() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAll(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAll(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -93,11 +98,11 @@ void testGetRoleById() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findById(Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.getRoleById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getRoleById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -115,11 +120,11 @@ void testCreateRole() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.create(Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.createRole(request, new AccessControlRecord("test")); + final ResponseEntity response = this.controller.createRole(request, new AccessControlRecord("test")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -138,11 +143,11 @@ void testUpdateRole() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.update(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.updateRole(request, UUID.randomUUID(), new AccessControlRecord("test")); + final ResponseEntity response = this.controller.updateRole(request, UUID.randomUUID(), new AccessControlRecord("test")); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -161,10 +166,10 @@ void testDeleteRole() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).delete(Mockito.any(), Mockito.any()); - final Response response = this.controller.deleteRole(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.deleteRole(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -182,11 +187,11 @@ void testGetUsersByRole() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllUsers(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getUsersByRole(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getUsersByRole(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -204,11 +209,11 @@ void testAssociateUser() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associateUser(Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associateUser(request, UUID.randomUUID(), "login"); + final ResponseEntity response = this.controller.associateUser(request, UUID.randomUUID(), "login"); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -226,10 +231,10 @@ void testDissociateUser() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociateUser(Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociateUser(request, UUID.randomUUID(), "login"); + final ResponseEntity response = this.controller.dissociateUser(request, UUID.randomUUID(), "login"); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -247,11 +252,11 @@ void testGetSubRolesOfRole() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllAccessControls(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getSubRolesOfRole(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getSubRolesOfRole(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -271,11 +276,11 @@ void testAssociate() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associate(request, UUID.randomUUID(), UUID.randomUUID().toString()); + final ResponseEntity response = this.controller.associate(request, UUID.randomUUID(), UUID.randomUUID().toString()); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -294,10 +299,10 @@ void testDissociate() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociate(request, UUID.randomUUID(), UUID.randomUUID()); + final ResponseEntity response = this.controller.dissociate(request, UUID.randomUUID(), UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -315,11 +320,11 @@ void testGetGroupsOfRole() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllChildren(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getGroupsOfRole(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getGroupsOfRole(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -337,11 +342,11 @@ void testGetScopesOfRole() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllChildren(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getScopesOfRole(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getScopesOfRole(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -360,11 +365,11 @@ void testAssociateScope() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associateScope(request, UUID.randomUUID(), UUID.randomUUID().toString()); + final ResponseEntity response = this.controller.associateScope(request, UUID.randomUUID(), UUID.randomUUID().toString()); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -383,10 +388,10 @@ void testDissociateScope() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociateScope(request, UUID.randomUUID(), UUID.randomUUID()); + final ResponseEntity response = this.controller.dissociateScope(request, UUID.randomUUID(), UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -405,11 +410,11 @@ void testAssociateGroup() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associateGroup(request, UUID.randomUUID(), UUID.randomUUID().toString()); + final ResponseEntity response = this.controller.associateGroup(request, UUID.randomUUID(), UUID.randomUUID().toString()); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -428,10 +433,10 @@ void testDissociateGroup() { Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociateGroup(request, UUID.randomUUID(), UUID.randomUUID()); + final ResponseEntity response = this.controller.dissociateGroup(request, UUID.randomUUID(), UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -454,11 +459,11 @@ void testGetPermissionsOfRole() { Mockito .when(this.accessControlPermissionService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getPermissionsOfRole(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getPermissionsOfRole(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -483,11 +488,11 @@ void testAssociatePermission() { .thenReturn(new Permission()); Mockito.when(accessControlService.getSuperAdministratorId()).thenReturn(UUID.randomUUID()); Mockito.doNothing().when(this.accessControlPermissionService).associate(Mockito.any(), Mockito.any()); - final Response response = this.controller.associatePermission(request, UUID.randomUUID(), UUID.randomUUID().toString()); + final ResponseEntity response = this.controller.associatePermission(request, UUID.randomUUID(), UUID.randomUUID().toString()); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -512,10 +517,10 @@ void testDissociatePermission() { .when(this.permissionService.findById(Mockito.any())) .thenReturn(new Permission()); Mockito.doNothing().when(this.accessControlPermissionService).dissociate(Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociatePermission(request, UUID.randomUUID(), UUID.randomUUID()); + final ResponseEntity response = this.controller.dissociatePermission(request, UUID.randomUUID(), UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/ScopeControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/ScopeControllerTest.java index 20bc8ba4..c61b78f6 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/ScopeControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/ScopeControllerTest.java @@ -2,7 +2,11 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDirectDTO; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; +import com.ditrit.letomodelizerapi.model.permission.PermissionDirectDTO; +import com.ditrit.letomodelizerapi.model.user.UserDTO; import com.ditrit.letomodelizerapi.persistence.model.AccessControl; import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.service.AccessControlPermissionService; @@ -11,7 +15,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -23,8 +26,10 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.util.ArrayList; +import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @@ -64,11 +69,11 @@ void testFindAll() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.findAll(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.findAll(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -86,11 +91,11 @@ void testGetGroupById() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findById(Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.getScopeById(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.getScopeById(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -108,11 +113,11 @@ void testCreateGroup() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.create(Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.createScope(request, new AccessControlRecord("test")); + final ResponseEntity response = this.controller.createScope(request, new AccessControlRecord("test")); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -130,11 +135,11 @@ void testUpdateScope() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.update(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new AccessControl()); - final Response response = this.controller.updateScope(request, UUID.randomUUID(), new AccessControlRecord("test")); + final ResponseEntity response = this.controller.updateScope(request, UUID.randomUUID(), new AccessControlRecord("test")); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -152,10 +157,10 @@ void testDeleteScope() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).delete(Mockito.any(), Mockito.any()); - final Response response = this.controller.deleteScope(request, UUID.randomUUID()); + final ResponseEntity response = this.controller.deleteScope(request, UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -173,11 +178,11 @@ void testGetUsersByScope() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllUsers(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getUsersByScope(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getUsersByScope(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -195,11 +200,11 @@ void testAssociateUser() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associateUser(Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associateUser(request, UUID.randomUUID(), "login"); + final ResponseEntity response = this.controller.associateUser(request, UUID.randomUUID(), "login"); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -217,10 +222,10 @@ void testDissociateUser() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociateUser(Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociateUser(request, UUID.randomUUID(), "login"); + final ResponseEntity response = this.controller.dissociateUser(request, UUID.randomUUID(), "login"); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -238,11 +243,11 @@ void testGetGroupsOfScope() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllAccessControls(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getGroupsOfScope(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getGroupsOfScope(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -260,11 +265,11 @@ void testAssociate() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).associate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.associate(request, UUID.randomUUID(), UUID.randomUUID().toString()); + final ResponseEntity response = this.controller.associate(request, UUID.randomUUID(), UUID.randomUUID().toString()); assertNotNull(response); - assertEquals(HttpStatus.CREATED.value(), response.getStatus()); - assertNull(response.getEntity()); + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertNull(response.getBody()); } @Test @@ -282,10 +287,10 @@ void testDissociate() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(this.accessControlService).dissociate(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); - final Response response = this.controller.dissociate(request, UUID.randomUUID(), UUID.randomUUID()); + final ResponseEntity response = this.controller.dissociate(request, UUID.randomUUID(), UUID.randomUUID()); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -303,11 +308,11 @@ void testGetRolesOfScope() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.accessControlService.findAllAccessControls(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Page.empty()); - final Response response = this.controller.getRolesOfScope(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getRolesOfScope(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -330,10 +335,10 @@ void testGetPermissionsOfScope() { Mockito .when(this.accessControlPermissionService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getPermissionsOfScope(request, UUID.randomUUID(), mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getPermissionsOfScope(request, UUID.randomUUID(), Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/UserControllerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/UserControllerTest.java index aab62cb3..84056492 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/UserControllerTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/UserControllerTest.java @@ -2,6 +2,11 @@ import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.helper.MockHelper; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDTO; +import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlDirectDTO; +import com.ditrit.letomodelizerapi.model.ai.AIConversationDTO; +import com.ditrit.letomodelizerapi.model.permission.PermissionDTO; +import com.ditrit.letomodelizerapi.model.user.UserDTO; import com.ditrit.letomodelizerapi.persistence.model.User; import com.ditrit.letomodelizerapi.service.AIService; import com.ditrit.letomodelizerapi.service.AccessControlService; @@ -9,7 +14,6 @@ import com.ditrit.letomodelizerapi.service.UserService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; -import jakarta.ws.rs.core.Response; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -21,6 +25,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import java.net.http.HttpHeaders; import java.net.http.HttpResponse; @@ -68,11 +73,11 @@ void testGetUsers() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.userService.findAll(Mockito.any(), Mockito.any())).thenReturn(new PageImpl<>(new ArrayList<>())); - final Response response = this.controller.getUsers(request, mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getUsers(request, Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -90,11 +95,11 @@ void testGetUserByLogin() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); - final Response response = this.controller.getUserByLogin(request, "test"); + final ResponseEntity response = this.controller.getUserByLogin(request, "test"); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -112,10 +117,10 @@ void testDeleteUserByLogin() { .thenReturn(session); Mockito.doNothing().when(userPermissionService).checkIsAdmin(Mockito.any(), Mockito.any()); Mockito.doNothing().when(userService).deleteByLogin("test"); - final Response response = this.controller.deleteUserByLogin(request, "test"); + final ResponseEntity response = this.controller.deleteUserByLogin(request, "test"); assertNotNull(response); - assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatus()); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); } @Test @@ -135,11 +140,11 @@ void testGetRolesOfUser() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getRolesOfUser(request, "test", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getRolesOfUser(request, "test", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -159,11 +164,11 @@ void testGetGroupsOfUser() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getGroupsOfUser(request, "test", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getGroupsOfUser(request, "test", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -183,11 +188,11 @@ void testGetPermissionsOfUser() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.userPermissionService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getPermissionsOfUser(request, "login", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getPermissionsOfUser(request, "login", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -211,11 +216,11 @@ void testGetPermissionsOfUserAnother() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.userPermissionService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getPermissionsOfUser(request, "login", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getPermissionsOfUser(request, "login", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -235,11 +240,11 @@ void testGetScopesOfUser() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.accessControlService.findAll(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getScopesOfUser(request, "test", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getScopesOfUser(request, "test", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -269,10 +274,10 @@ void testGetPicture() { .when(userService.getPicture(Mockito.any())) .thenReturn(picture); - Response response = userController.getPictureOfUser(request, "test"); + ResponseEntity response = userController.getPictureOfUser(request, "test"); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -292,11 +297,11 @@ void testGetAIConversationsOfUser() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.aiService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getAIConversationsOfUser(request, "login", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getAIConversationsOfUser(request, "login", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } @Test @@ -320,10 +325,10 @@ void testGetAIConversationsOfUserAnother() { Mockito.when(this.userService.findByLogin(Mockito.any())).thenReturn(new User()); Mockito.when(this.aiService.findAll(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(Page.empty()); - final Response response = this.controller.getAIConversationsOfUser(request, "login", mockUriInfo(), new QueryFilter()); + final ResponseEntity> response = this.controller.getAIConversationsOfUser(request, "login", Map.of(), new QueryFilter()); assertNotNull(response); - assertEquals(HttpStatus.OK.value(), response.getStatus()); - assertNotNull(response.getEntity()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandlerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandlerTest.java deleted file mode 100644 index 6023e4cb..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/ApiExceptionHandlerTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ApiException; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.ws.rs.core.Response; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@Tag("unit") -@DisplayName("Test class: ApiExceptionHandler") -class ApiExceptionHandlerTest { - @Test - @DisplayName("Test toResponse: should create wanted response.") - void testToResponse() throws JsonProcessingException { - ApiExceptionHandler handler = new ApiExceptionHandler(); - ApiException exception = new ApiException(ErrorType.WRONG_VALUE, null, null); - - Response response = handler.toResponse(exception); - assertNotNull(response); - assertEquals(exception.getStatus().value(), response.getStatus()); - assertEquals(new ObjectMapper().writeValueAsString(exception.getError()), response.getEntity()); - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandlerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandlerTest.java deleted file mode 100644 index 90254bf8..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/ConstraintViolationExceptionHandlerTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ErrorDTO; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.validation.ConstraintViolation; -import jakarta.validation.ConstraintViolationException; -import jakarta.validation.Path; -import jakarta.ws.rs.core.Response; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.http.HttpStatus; - -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@Tag("unit") -@DisplayName("Test class: ConstraintViolationExceptionHandler") -class ConstraintViolationExceptionHandlerTest { - - private final Path defaultPath = () -> { - Path.Node node1 = Mockito.mock(Path.Node.class); - Path.Node node2 = Mockito.mock(Path.Node.class); - - Mockito.when(node1.getName()).thenReturn("test1"); - Mockito.when(node2.getName()).thenReturn("test2"); - - return List.of(node1, node2).iterator(); - }; - - @Test - @DisplayName("Test toResponse: should return empty bad request response without ConstraintViolation.") - void testToResponseWithoutConstraintViolation() { - ConstraintViolationExceptionHandler handler = new ConstraintViolationExceptionHandler(); - ConstraintViolationException exception = new ConstraintViolationException(Collections.emptySet()); - - Response response = handler.toResponse(exception); - assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); - } - - @Test - void toResponseShouldReturnBadRequestOnEmptyValue() throws JsonProcessingException { - ConstraintViolationExceptionHandler handler = new ConstraintViolationExceptionHandler(); - ConstraintViolation violation = Mockito.mock(ConstraintViolation.class); - Mockito.when(violation.getPropertyPath()).thenReturn(defaultPath); - Set> set = new HashSet<>(); - set.add(violation); - ConstraintViolationException exception = new ConstraintViolationException(set); - ErrorDTO expectedError = new ErrorDTO(ErrorType.EMPTY_VALUE.getCode(), ErrorType.EMPTY_VALUE.getMessage(), "test2", null, null); - - Response response = handler.toResponse(exception); - assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); - assertEquals(new ObjectMapper().writeValueAsString(expectedError), response.getEntity()); - } - - @Test - void toResponseShouldReturnBadRequest() throws JsonProcessingException { - ConstraintViolationExceptionHandler handler = new ConstraintViolationExceptionHandler(); - ConstraintViolation violation = Mockito.mock(ConstraintViolation.class); - Mockito.when(violation.getPropertyPath()).thenReturn(defaultPath); - Mockito.when(violation.getInvalidValue()).thenReturn("test"); - Set> set = new HashSet<>(); - set.add(violation); - ConstraintViolationException exception = new ConstraintViolationException(set); - ErrorDTO expectedError = new ErrorDTO(ErrorType.WRONG_VALUE.getCode(), ErrorType.WRONG_VALUE.getMessage(), "test2", "test", null); - - Response response = handler.toResponse(exception); - assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); - assertEquals(new ObjectMapper().writeValueAsString(expectedError), response.getEntity()); - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandlerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandlerTest.java deleted file mode 100644 index 5c0940db..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/DataIntegrityViolationExceptionHandlerTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ErrorDTO; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.ws.rs.core.Response; -import org.hibernate.exception.ConstraintViolationException; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.http.HttpStatus; - -import java.sql.SQLException; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@Tag("unit") -@DisplayName("Test class: DataIntegrityViolationExceptionHandler") -class DataIntegrityViolationExceptionHandlerTest { - - @Test - @DisplayName("Test toResponse: should return empty bad request response with unknown violation.") - void testToResponseWithUnknownViolation() { - DataIntegrityViolationExceptionHandler handler = new DataIntegrityViolationExceptionHandler(); - - Response response = handler.toResponse(new DataIntegrityViolationException("test")); - assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); - } - - @Test - @DisplayName("Test toResponse: should return bad request response") - void testToResponse() throws JsonProcessingException { - DataIntegrityViolationExceptionHandler handler = new DataIntegrityViolationExceptionHandler(); - SQLException sqlException = new SQLException(); - ConstraintViolationException violation = new ConstraintViolationException("test sql", sqlException, "data"); - DataIntegrityViolationException exception = new DataIntegrityViolationException("test", violation); - ErrorDTO expectedError = new ErrorDTO(ErrorType.WRONG_VALUE.getCode(), ErrorType.WRONG_VALUE.getMessage(), "constraint", "data", null); - - Response response = handler.toResponse(exception); - assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); - assertEquals(new ObjectMapper().writeValueAsString(expectedError), response.getEntity()); - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandlerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandlerTest.java new file mode 100644 index 00000000..69e5368c --- /dev/null +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/handler/GlobalExceptionHandlerTest.java @@ -0,0 +1,129 @@ +package com.ditrit.letomodelizerapi.controller.handler; + +import com.ditrit.letomodelizerapi.model.error.ApiException; +import com.ditrit.letomodelizerapi.model.error.ErrorDTO; +import com.ditrit.letomodelizerapi.model.error.ErrorType; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Path; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.sql.SQLException; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@Tag("unit") +@DisplayName("Test class: GlobalExceptionHandler") +class GlobalExceptionHandlerTest { + + @Test + @DisplayName("Test handleApiException: should create wanted response.") + void testHandleApiException() throws JsonProcessingException { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + ApiException exception = new ApiException(ErrorType.WRONG_VALUE, null, null); + + ResponseEntity response = handler.handleApiException(exception); + assertNotNull(response); + assertEquals(exception.getStatus(), response.getStatusCode()); + assertEquals(new ObjectMapper().writeValueAsString(exception.getError()), response.getBody()); + } + + private final Path defaultPath = () -> { + Path.Node node1 = Mockito.mock(Path.Node.class); + Path.Node node2 = Mockito.mock(Path.Node.class); + + Mockito.when(node1.getName()).thenReturn("test1"); + Mockito.when(node2.getName()).thenReturn("test2"); + + return List.of(node1, node2).iterator(); + }; + + @Test + @DisplayName("Test handleConstraintViolationException: should return empty bad request response without ConstraintViolation.") + void testHandleConstraintViolationExceptionWithoutConstraintViolation() { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + ConstraintViolationException exception = new ConstraintViolationException(Collections.emptySet()); + + ResponseEntity response = handler.handleConstraintViolationException(exception); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + } + + @Test + @DisplayName("Test handleConstraintViolationException: should return empty bad request response with empty value.") + void testHandleConstraintViolationShouldReturnBadRequestOnEmptyValue() throws JsonProcessingException { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + ConstraintViolation violation = Mockito.mock(ConstraintViolation.class); + Mockito.when(violation.getPropertyPath()).thenReturn(defaultPath); + Set> set = new HashSet<>(); + set.add(violation); + ConstraintViolationException exception = new ConstraintViolationException(set); + ErrorDTO expectedError = new ErrorDTO(ErrorType.EMPTY_VALUE.getCode(), ErrorType.EMPTY_VALUE.getMessage(), "test2", null, null); + + ResponseEntity response = handler.handleConstraintViolationException(exception); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals(new ObjectMapper().writeValueAsString(expectedError), response.getBody()); + } + + @Test + @DisplayName("Test handleConstraintViolationException: should return empty bad request") + void voidHandleConstraintViolationShouldReturnBadRequest() throws JsonProcessingException { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + ConstraintViolation violation = Mockito.mock(ConstraintViolation.class); + Mockito.when(violation.getPropertyPath()).thenReturn(defaultPath); + Mockito.when(violation.getInvalidValue()).thenReturn("test"); + Set> set = new HashSet<>(); + set.add(violation); + ConstraintViolationException exception = new ConstraintViolationException(set); + ErrorDTO expectedError = new ErrorDTO(ErrorType.WRONG_VALUE.getCode(), ErrorType.WRONG_VALUE.getMessage(), "test2", "test", null); + + ResponseEntity response = handler.handleConstraintViolationException(exception); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals(new ObjectMapper().writeValueAsString(expectedError), response.getBody()); + } + + @Test + @DisplayName("Test handleDataIntegrityViolationException: should return empty bad request response with unknown violation.") + void testHandleDataIntegrityViolationExceptionWithUnknown() { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + + ResponseEntity response = handler.handleDataIntegrityViolationException(new DataIntegrityViolationException("test")); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + } + + @Test + @DisplayName("Test handleDataIntegrityViolationException: should return bad request response") + void testHandleDataIntegrityViolationException() throws JsonProcessingException { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + SQLException sqlException = new SQLException(); + org.hibernate.exception.ConstraintViolationException violation = new org.hibernate.exception.ConstraintViolationException("test sql", sqlException, "data"); + DataIntegrityViolationException exception = new DataIntegrityViolationException("test", violation); + ErrorDTO expectedError = new ErrorDTO(ErrorType.WRONG_VALUE.getCode(), ErrorType.WRONG_VALUE.getMessage(), "constraint", "data", null); + + ResponseEntity response = handler.handleDataIntegrityViolationException(exception); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals(new ObjectMapper().writeValueAsString(expectedError), response.getBody()); + } + + @Test + @DisplayName("Test handleIllegalArgumentException: should return valid response") + void testHandleIllegalArgumentException() { + GlobalExceptionHandler handler = new GlobalExceptionHandler(); + ResponseEntity response = handler.handleIllegalArgumentException(new IllegalArgumentException("test")); + + assertNotNull(response); + assertEquals(ErrorType.WRONG_VALUE.getStatus(), response.getStatusCode()); + } +} diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandlerTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandlerTest.java deleted file mode 100644 index 2ed2bdab..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/handler/IllegalArgumentExceptionHandlerTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.ditrit.letomodelizerapi.controller.handler; - -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import jakarta.ws.rs.core.Response; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@Tag("unit") -@DisplayName("Test class: IllegalArgumentExceptionHandler") -class IllegalArgumentExceptionHandlerTest { - - @Test - @DisplayName("Should return valid response") - void testToResponse() { - IllegalArgumentException exception = new IllegalArgumentException(); - Response response = new IllegalArgumentExceptionHandler().toResponse(exception); - - assertNotNull(response); - assertEquals(ErrorType.WRONG_VALUE.getStatus().value(), response.getStatus()); - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/controller/model/QueryFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/controller/model/QueryFilterTest.java index 5cc51534..a6cd5ee6 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/controller/model/QueryFilterTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/controller/model/QueryFilterTest.java @@ -1,68 +1,130 @@ package com.ditrit.letomodelizerapi.controller.model; +import org.junit.Test; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import static org.junit.jupiter.api.Assertions.*; @Tag("unit") @DisplayName("Test class: QueryFilter") -class QueryFilterTest { +public class QueryFilterTest { + @Test + @DisplayName("Test getComputedPage: should return valid page") + public void testGetComputedPage() { + QueryFilter queryFilter = new QueryFilter(); + + queryFilter.setPage(null); + assertEquals(0, queryFilter.getComputedPage()); + + queryFilter.setPage(-1); + assertEquals(0, queryFilter.getComputedPage()); + + queryFilter.setPage(2); + assertEquals(2, queryFilter.getComputedPage()); + } @Test - @DisplayName("Test getPagination: should return default pagination.") - void testGetPaginationDefault() { - QueryFilter filter = new QueryFilter(); - Pageable pageable = filter.getPagination(); + @DisplayName("Test getComputedPageSize: should return valid page size") + public void testGetComputedPageSize() { + QueryFilter queryFilter = new QueryFilter(); - assertNotNull(pageable); - assertNotNull(pageable.getSort()); - assertFalse(pageable.getSort().isSorted()); - assertEquals(0, pageable.getPageNumber()); - assertEquals(10, pageable.getPageSize()); + queryFilter.setCount(null); + assertEquals(10, queryFilter.getComputedPageSize()); + + queryFilter.setCount(-1); + assertEquals(1, queryFilter.getComputedPageSize()); + + queryFilter.setCount(201); + assertEquals(200, queryFilter.getComputedPageSize()); + + queryFilter.setCount(45); + assertEquals(45, queryFilter.getComputedPageSize()); } @Test - @DisplayName("Test getPagination: should return pagination with given sort.") - void testGetPaginationGivenSort() { - QueryFilter filter = new QueryFilter(); - filter.setSort("desc"); - filter.setOrder("id"); - Pageable pageable = filter.getPagination(); + @DisplayName("Test isAscendantSort: should return valid sort direction") + public void testIsAscendantSort() { + QueryFilter queryFilter = new QueryFilter(); - assertNotNull(pageable); - assertEquals(0, pageable.getPageNumber()); - assertEquals(10, pageable.getPageSize()); - assertNotNull(pageable.getSort()); - assertEquals("id: DESC", pageable.getSort().toString()); + queryFilter.setSort(null); + assertFalse(queryFilter.isAscendantSort()); - filter = new QueryFilter(); - filter.setSort("asc"); - filter.setOrder("id"); - pageable = filter.getPagination(); + queryFilter.setSort("desc"); + assertFalse(queryFilter.isAscendantSort()); + + queryFilter.setSort("test"); + assertFalse(queryFilter.isAscendantSort()); + + queryFilter.setSort("asc"); + assertTrue(queryFilter.isAscendantSort()); + + queryFilter.setSort("ASC"); + assertTrue(queryFilter.isAscendantSort()); + } + + @Test + @DisplayName("Test getDirection: should return valid sort direction") + public void testGetDirection() { + QueryFilter queryFilter = new QueryFilter(); + + queryFilter.setSort(null); + assertEquals(Sort.Direction.ASC, queryFilter.getDirection(true)); + queryFilter.setSort(""); + assertEquals(Sort.Direction.ASC, queryFilter.getDirection(true)); + queryFilter.setSort(" "); + assertEquals(Sort.Direction.ASC, queryFilter.getDirection(true)); + + queryFilter.setSort(null); + assertEquals(Sort.Direction.DESC, queryFilter.getDirection(false)); + queryFilter.setSort(""); + assertEquals(Sort.Direction.DESC, queryFilter.getDirection(false)); + queryFilter.setSort(" "); + assertEquals(Sort.Direction.DESC, queryFilter.getDirection(false)); + + queryFilter.setSort("asc"); + assertEquals(Sort.Direction.ASC, queryFilter.getDirection(true)); + assertEquals(Sort.Direction.ASC, queryFilter.getDirection(false)); + + queryFilter.setSort("desc"); + assertEquals(Sort.Direction.DESC, queryFilter.getDirection(true)); + assertEquals(Sort.Direction.DESC, queryFilter.getDirection(false)); + } + + @Test + @DisplayName("Test getPageable: should return Pageable with default sort") + public void testGetPageable() { + QueryFilter queryFilter = new QueryFilter(); + Pageable pageable = queryFilter.getPageable(true, "test1", "test2"); assertNotNull(pageable); assertEquals(0, pageable.getPageNumber()); assertEquals(10, pageable.getPageSize()); - assertNotNull(pageable.getSort()); - assertEquals("id: ASC", pageable.getSort().toString()); + assertEquals(2, pageable.getSort().toList().size()); + assertEquals("test1", pageable.getSort().toList().get(0).getProperty()); + assertEquals(Sort.Direction.ASC, pageable.getSort().toList().get(0).getDirection()); + assertEquals("test2", pageable.getSort().toList().get(1).getProperty()); + assertEquals(Sort.Direction.ASC, pageable.getSort().toList().get(1).getDirection()); } @Test - @DisplayName("Test getPagination: should return pagination with given limit.") - void testGetPaginationGivenLimit() { - QueryFilter filter = new QueryFilter(); - filter.setCount(100); - filter.setPage(50); - Pageable pageable = filter.getPagination(); + @DisplayName("Test getPageable: should return Pageable with wanted sort") + public void testGetPageableWithSort() { + QueryFilter queryFilter = new QueryFilter(); + queryFilter.setPage(1); + queryFilter.setCount(5); + queryFilter.setSort("desc"); + queryFilter.setOrder("order"); + Pageable pageable = queryFilter.getPageable(true, "test1", "test2"); assertNotNull(pageable); - assertNotNull(pageable.getSort()); - assertFalse(pageable.getSort().isSorted()); - assertEquals(50, pageable.getPageNumber()); - assertEquals(100, pageable.getPageSize()); + assertEquals(1, pageable.getPageNumber()); + assertEquals(5, pageable.getPageSize()); + assertEquals(1, pageable.getSort().toList().size()); + assertEquals("order", pageable.getSort().toList().getFirst().getProperty()); + assertEquals(Sort.Direction.DESC, pageable.getSort().toList().getFirst().getDirection()); } } diff --git a/src/test/java/com/ditrit/letomodelizerapi/cucumber/StepDefinitions.java b/src/test/java/com/ditrit/letomodelizerapi/cucumber/StepDefinitions.java index 1dbb994d..60422c51 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/cucumber/StepDefinitions.java +++ b/src/test/java/com/ditrit/letomodelizerapi/cucumber/StepDefinitions.java @@ -10,26 +10,26 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.Invocation; -import jakarta.ws.rs.client.WebTarget; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; import org.apache.commons.lang.text.StrSubstitutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.IOException; +import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.sql.Connection; @@ -48,7 +48,7 @@ public class StepDefinitions { private static final Logger LOGGER = LoggerFactory.getLogger(StepDefinitions.class); private static final HashMap globalContext; - private static final SSLContext sslcontext; + private static final RestTemplate restTemplate; private static final String baseURI = "https://localhost:8443/api"; @@ -56,23 +56,46 @@ public class StepDefinitions { static { globalContext = new HashMap<>(); globalContext.put("LIBRARY_HOST", "libraries"); + try { - sslcontext = SSLContext.getInstance("TLS"); + // Create SSL context to trust all certificates + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[]{new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {} - sslcontext.init(null, new TrustManager[]{new X509TrustManager() { - public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} - public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} - public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {} + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } }}, new java.security.SecureRandom()); - } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new RuntimeException(e); + + SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory() { + @Override + protected void prepareConnection(HttpURLConnection connection, String httpMethod) { + if (connection instanceof HttpsURLConnection) { + ((HttpsURLConnection) connection).setSSLSocketFactory(sslContext.getSocketFactory()); + ((HttpsURLConnection) connection).setHostnameVerifier((hostname, session) -> true); + } + try { + super.prepareConnection(connection, httpMethod); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }; + + restTemplate = new RestTemplate(requestFactory); + + } catch (Exception e) { + throw new RuntimeException("Failed to initialize RestTemplate with custom SSL", e); } } - private final Client client = ClientBuilder.newBuilder() - .sslContext(sslcontext) - .hostnameVerifier((s1, s2) -> true) - .build(); + public static RestTemplate getRestTemplate() { + return restTemplate; + } + private final ObjectMapper mapper = new ObjectMapper(); private int statusCode; private String body; @@ -195,22 +218,21 @@ public void requestWithJson(String endpoint, String method, DataTable table) { LOGGER.info(json.toString()); - this.requestFull(endpoint, method, Entity.json(json.toString()), MediaType.APPLICATION_JSON); + this.requestFull(endpoint, method, json.toString(), MediaType.APPLICATION_JSON); } - public void requestFull(String endpoint, String method, Entity body, String contentType) { + public void requestFull(String endpoint, String method, String body, MediaType contentType) { String uri = baseURI + replaceWithContext(endpoint); - WebTarget target = this.client.target(uri); - Invocation.Builder builder = target.request(); - builder.cookie("SESSION", globalContext.get("COOKIE_SESSION")); + HttpHeaders headers = new HttpHeaders(); + headers.add("Cookie", "SESSION=" + globalContext.get("COOKIE_SESSION")); if (contentType != null) { - builder.header("Content-Type", contentType); + headers.setContentType(contentType); } if (globalContext.containsKey("CSRF_HEADER")) { - builder.header(globalContext.get("CSRF_HEADER"), globalContext.get("CSRF_TOKEN")); + headers.add(globalContext.get("CSRF_HEADER"), globalContext.get("CSRF_TOKEN")); } LOGGER.info("{} request to {}", method, uri); @@ -219,25 +241,31 @@ public void requestFull(String endpoint, String method, Entity body, String c } else { LOGGER.info("With body: {}", body.toString()); } - Response response; - if (body != null) { - response = builder.build(method, body).invoke(); - } else { - response = builder.build(method).invoke(); + + HttpEntity requestEntity = new HttpEntity<>(body, headers); + HttpMethod httpMethod = HttpMethod.valueOf(method.toUpperCase()); + + ResponseEntity response; + try { + response = restTemplate.exchange(uri, httpMethod, requestEntity, String.class); + } catch (Exception e) { + LOGGER.error("Error while making HTTP request", e); + throw new RuntimeException("HTTP request failed", e); } - statusCode = response.getStatus(); + statusCode = response.getStatusCodeValue(); + MediaType responseType = response.getHeaders().getContentType(); LOGGER.info("Receive {} as status code", statusCode); - LOGGER.info("Receive {} as content type", response.getMediaType()); - if (statusCode != 204 && MediaType.valueOf(MediaType.APPLICATION_JSON).isCompatible(response.getMediaType())) { + LOGGER.info("Receive {} as content type", response.getHeaders().getContentType()); + if (statusCode != 204 && MediaType.APPLICATION_JSON.isCompatibleWith(responseType)) { try { - json = mapper.readTree(response.readEntity(String.class)); + json = mapper.readTree(response.getBody()); LOGGER.info("With body: {}", json); } catch (IOException e) { LOGGER.error("Can't read body", e); } } else { - this.body = response.readEntity(String.class); + this.body = response.getBody(); } } @@ -251,7 +279,7 @@ public String getToken() { return String.format("%s %s", globalContext.get("authenticationType"), Base64.getUrlEncoder().encodeToString(token.getBytes())); } - public Entity createBody(DataTable table) { + public String createBody(DataTable table) { if (table == null || table.isEmpty()) { return null; } @@ -270,10 +298,10 @@ public Entity createBody(DataTable table) { if ("BASE64".equals(type)) { String base64Value = Base64.getUrlEncoder().encodeToString(value.getBytes()); - return Entity.text(base64Value); + return base64Value; } - return Entity.text(value); + return value; } @Then("I expect \"{int}\" as status code") diff --git a/src/test/java/com/ditrit/letomodelizerapi/helper/MockHelper.java b/src/test/java/com/ditrit/letomodelizerapi/helper/MockHelper.java index 8d5f97d1..03d0fcb8 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/helper/MockHelper.java +++ b/src/test/java/com/ditrit/letomodelizerapi/helper/MockHelper.java @@ -1,9 +1,11 @@ package com.ditrit.letomodelizerapi.helper; import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.*; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.UriInfo; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Path; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import org.mockito.Mockito; import java.util.Collection; @@ -11,11 +13,6 @@ public abstract class MockHelper { - public UriInfo mockUriInfo() { - UriInfo mock = Mockito.mock(UriInfo.class); - Mockito.when(mock.getQueryParameters()).thenReturn(new MultivaluedHashMap<>()); - return mock; - } public EntityManager mockEntityManager(Class entityClass) { return mockEntityManager(entityClass, Mockito.mock(EntityManager.class)); } diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperatorTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperatorTest.java deleted file mode 100644 index 30b004e3..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/PredicateOperatorTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: PredicateOperator") -class PredicateOperatorTest { - - @Test - @DisplayName("Test isValid: should return true on valid operator") - void isValidTestValid() { - assertTrue(PredicateOperator.isValid("eq")); - assertTrue(PredicateOperator.isValid("LT")); - assertTrue(PredicateOperator.isValid("Gt")); - assertTrue(PredicateOperator.isValid("bT")); - } - - @Test - @DisplayName("Test isValid: should return false on invalid operator") - void isValidTestInvalid() { - assertFalse(PredicateOperator.isValid("=")); - assertFalse(PredicateOperator.isValid("<")); - assertFalse(PredicateOperator.isValid(">")); - assertFalse(PredicateOperator.isValid("<>")); - assertFalse(PredicateOperator.isValid(null)); - assertFalse(PredicateOperator.isValid("!=")); - assertFalse(PredicateOperator.isValid("><")); - assertFalse(PredicateOperator.isValid("!")); - assertFalse(PredicateOperator.isValid("bad")); - } - - @Test - void getTest() { - assertTrue(PredicateOperator.get("bad").isEmpty()); - Optional test = PredicateOperator.get(PredicateOperator.EQUALS.getValue()); - assertFalse(test.isEmpty()); - assertEquals(PredicateOperator.EQUALS, test.get()); - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelperTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelperTest.java deleted file mode 100644 index 2ef87f75..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/SpecificationHelperTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import com.ditrit.letomodelizerapi.persistence.specification.filter.*; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@Tag("unit") -@DisplayName("Test class: SpecificationHelper") -class SpecificationHelperTest extends MockHelper { - - @Test - @DisplayName("Test getFilters: Should return all related filters to the filter map.") - void testGetFilters() { - SpecificationHelper helper = new SpecificationHelper<>(Entity.class, Map.of( - "aNumber", "1", - "aString", "test", - "aDate", "null", - "aBoolean", "true", - "aToken", "a", - "aEnum", "b", - "aUUID", UUID.randomUUID().toString() - )); - - List filters = helper.getFilters(); - assertNotNull(filters); - assertEquals(7, filters.size()); - assertEquals(NumberPredicateFilter.class, filters.get(0).getClass()); - assertEquals(TextPredicateFilter.class, filters.get(1).getClass()); - assertEquals(BooleanPredicateFilter.class, filters.get(2).getClass()); - assertEquals(TokenPredicateFilter.class, filters.get(3).getClass()); - assertEquals(DatePredicateFilter.class, filters.get(4).getClass()); - assertEquals(EnumPredicateFilter.class, filters.get(5).getClass()); - assertEquals(UUIDPredicateFilter.class, filters.get(6).getClass()); - } - - @Test - @DisplayName("Test toPredicate: Should return non null predicate.") - void testToPredicate() { - EntityManager entityManager = mockEntityManager(Entity.class); - SpecificationHelper helper = new SpecificationHelper<>(Entity.class, Map.of( - "aNumber", "1" - )); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - assertNotNull(helper.toPredicate(root, query, builder)); - } - - class Entity { - @FilterType(type = FilterType.Type.NUMBER) - private Long aNumber; - @FilterType(type = FilterType.Type.TEXT) - private String aString; - @FilterType(type = FilterType.Type.BOOLEAN) - private boolean aBoolean; - @FilterType(type = FilterType.Type.TOKEN) - private String aToken; - @FilterType(type = FilterType.Type.DATE) - private Date aDate; - @FilterType(type = FilterType.Type.ENUM) - private String aEnum; - @FilterType(type = FilterType.Type.UUID) - private UUID aUUID; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilterTest.java deleted file mode 100644 index 8f53b611..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/BooleanPredicateFilterTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: BooleanPredicateFilter") -class BooleanPredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - BooleanPredicateFilter filter = new BooleanPredicateFilter(null, null); - filter.extract(); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - - filter = new BooleanPredicateFilter("test", "true"); - filter.extract(); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("true", filter.getValues()[0]); - assertFalse(filter.getIsNotOperator(0)); - - filter = new BooleanPredicateFilter("test", "not_true"); - filter.extract(); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("true", filter.getValues()[0]); - assertTrue(filter.getIsNotOperator(0)); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void getPredicateTest() { - EntityManager entityManager = this.mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - BooleanPredicateFilter filter = new BooleanPredicateFilter("bool", "test"); - assertTrue(filter.extract()); - - Predicate predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertFalse(filter.getIsNotOperator(0)); - - filter = new BooleanPredicateFilter("bool", "not_test"); - assertTrue(filter.extract()); - - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertTrue(filter.getIsNotOperator(0)); - } - - class Entity { - @FilterType(type = FilterType.Type.BOOLEAN) - private boolean bool; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilterTest.java deleted file mode 100644 index a9b97e64..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/DatePredicateFilterTest.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import com.ditrit.letomodelizerapi.model.error.ApiException; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import java.util.Date; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: DatePredicateFilter") -class DatePredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - DatePredicateFilter filter = new DatePredicateFilter(null, null); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - - filter = new DatePredicateFilter("test", "value"); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("value", filter.getValues()[0]); - } - - @Test - @DisplayName("Test extract: should verify extract date from value.") - void extractTest() { - assertFalse(new DatePredicateFilter(null, null).extract()); - - ApiException exception = null; - try { - new DatePredicateFilter("name", "bad").extract(); - } catch (ApiException e) { - exception = e; - } - assertNotNull(exception); - assertEquals(ErrorType.WRONG_FILTER_VALUE.getMessage(), exception.getError().getMessage()); - - DatePredicateFilter filter = new DatePredicateFilter(null, "2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - assertEquals("2019-01-01 00:00:00.000", filter.getValue(0)); - - filter = new DatePredicateFilter(null, "gt2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.SUPERIOR, filter.getOperator(0)); - assertEquals("2019-01-01 00:00:00.000", filter.getValue(0)); - - filter = new DatePredicateFilter(null, "lt2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.INFERIOR, filter.getOperator(0)); - assertEquals("2019-01-01 00:00:00.000", filter.getValue(0)); - - filter = new DatePredicateFilter(null, "2018-01-01 00:00:00.000bt2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.BETWEEN, filter.getOperator(0)); - assertEquals("2019-01-01 00:00:00.000", filter.getValue(0)); - - filter = new DatePredicateFilter(null, "null"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.NULL, filter.getOperator(0)); - assertEquals("null", filter.getValue(0)); - - filter = new DatePredicateFilter(null, "not_null"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.NULL, filter.getOperator(0)); - assertTrue(filter.getIsNotOperator(0)); - assertEquals("null", filter.getValue(0)); - - exception = null; - try { - new DatePredicateFilter(null, "bt2019-01-01 00:00:00.000").extract(); - } catch (ApiException e) { - exception = e; - } - assertNotNull(exception); - assertNotNull(exception.getError()); - assertEquals(ErrorType.EMPTY_VALUE.getMessage(), exception.getError().getMessage()); - } - - @Test - @DisplayName("Test extract: should set wanted operator.") - void getSpecificOperatorTest() { - ApiException exception = null; - try { - new DatePredicateFilter(null, "2019-01-01 00:00:00.000aa2019-01-01 00:00:00.000").extract(); - } catch (ApiException e) { - exception = e; - } - assertNotNull(exception); - assertNotNull(exception.getError()); - assertEquals(ErrorType.WRONG_FILTER_OPERATOR.getMessage(), exception.getError().getMessage()); - exception = null; - try { - new DatePredicateFilter(null, "not_2019-01-01 00:00:00.000").extract(); - } catch (ApiException e) { - exception = e; - } - assertNull(exception); - } - - @Test - @DisplayName("Test getDate: should return valid date.") - void getDateTest() { - final DatePredicateFilter filter = new DatePredicateFilter(null, null); - ApiException exception = null; - try { - filter.getDate(null); - } catch (final ApiException e) { - exception = e; - } - assertNotNull(exception); - - Date date = null; - exception = null; - try { - date = filter.getDate("2019-12-01 00:00:00.000"); - } catch (final ApiException e) { - exception = e; - } - - assertNull(exception); - assertNotNull(date); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void getPredicateTest() { - EntityManager entityManager = mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - DatePredicateFilter filter = new DatePredicateFilter("name", "2019-01-01 00:00:00.000|not_2018-01-01 00:00:00.000"); - assertTrue(filter.extract()); - Predicate predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - - filter = new DatePredicateFilter("date", "lt2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - - filter = new DatePredicateFilter("date", "gt2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - - filter = new DatePredicateFilter("date", "2019-01-01 00:00:00.000bt2019-01-02 00:00:00.000"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertEquals(1, filter.getValues().length); - assertEquals("2019-01-02 00:00:00.000", filter.getValue(0)); - - filter = new DatePredicateFilter("date", "NULL"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - - filter = new DatePredicateFilter("date", "NOT_NULL"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - - filter = new DatePredicateFilter("date", "NOT_2019-01-01 00:00:00.000"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - - filter = new DatePredicateFilter("date", "not_2019-01-01 00:00:00.000bt2019-01-02 00:00:00.000"); - assertTrue(filter.extract()); - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertEquals(1, filter.getValues().length); - assertEquals("2019-01-02 00:00:00.000", filter.getValue(0)); - } - - class Entity { - @FilterType(type = FilterType.Type.DATE) - private Date date; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilterTest.java deleted file mode 100644 index dd9821a5..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/EnumPredicateFilterTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: EnumPredicateFilter") -class EnumPredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - EnumPredicateFilter filter = new EnumPredicateFilter(null, null); - filter.extract(); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - - filter = new EnumPredicateFilter("test", "enum"); - filter.extract(); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("enum", filter.getValues()[0]); - assertFalse(filter.getIsNotOperator(0)); - - filter = new EnumPredicateFilter("test", "not_enum"); - filter.extract(); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("enum", filter.getValues()[0]); - assertTrue(filter.getIsNotOperator(0)); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void getPredicateTest() { - EntityManager entityManager = this.mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - EnumPredicateFilter filter = new EnumPredicateFilter("enum", "test"); - assertTrue(filter.extract()); - - Predicate predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertFalse(filter.getIsNotOperator(0)); - - filter = new EnumPredicateFilter("enum", "not_test"); - assertTrue(filter.extract()); - - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertTrue(filter.getIsNotOperator(0)); - } - - class Entity { - @FilterType(type = FilterType.Type.ENUM) - private String bool; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilterTest.java deleted file mode 100644 index b6ad5313..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/NumberPredicateFilterTest.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import com.ditrit.letomodelizerapi.model.error.ApiException; -import com.ditrit.letomodelizerapi.model.error.ErrorType; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: NumberPredicateFilter") -class NumberPredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - NumberPredicateFilter filter = new NumberPredicateFilter(null, null); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - - filter = new NumberPredicateFilter("test", "value"); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("value", filter.getValues()[0]); - } - - @Test - @DisplayName("Test extract: should verify extract number from value.") - void extractTest() { - NumberPredicateFilter filter = new NumberPredicateFilter(null, null); - assertFalse(filter.extract()); - - filter = new NumberPredicateFilter(null, "null"); - assertTrue(filter.extract()); - - filter = new NumberPredicateFilter(null, "not_null"); - assertTrue(filter.extract()); - - filter = new NumberPredicateFilter(null, "1"); - assertTrue(filter.extract()); - - filter = new NumberPredicateFilter(null, "1|1"); - assertTrue(filter.extract()); - - filter = new NumberPredicateFilter(null, "1|2|3|4|5"); - assertTrue(filter.extract()); - - filter = new NumberPredicateFilter(null, "not_1"); - assertTrue(filter.extract()); - - filter = new NumberPredicateFilter(null, "not_1|2|not_3|4|5|not_null"); - assertTrue(filter.extract()); - } - - @Test - @DisplayName("Test extract: should throw exception on invalid number.") - void testWithBadNumber() { - ApiException exception = null; - - try { - new NumberPredicateFilter("test", "a").extract(); - } catch (final ApiException hre) { - exception = hre; - } - - assertNotNull(exception); - assertEquals(ErrorType.WRONG_FILTER_VALUE.getMessage(), exception.getMessage()); - exception = null; - - try { - new NumberPredicateFilter("test", "9999999999999999999999999").extract(); - } catch (final ApiException hre) { - exception = hre; - } - - assertNotNull(exception); - assertEquals(ErrorType.WRONG_FILTER_VALUE.getMessage(), exception.getMessage()); - exception = null; - - try { - new NumberPredicateFilter("test", "notnot").extract(); - } catch (final ApiException hre) { - exception = hre; - } - - assertNotNull(exception); - assertEquals(ErrorType.WRONG_FILTER_VALUE.getMessage(), exception.getMessage()); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void testGetPredicate() { - EntityManager entityManager = mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - NumberPredicateFilter filter = new NumberPredicateFilter("number", "not_1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new NumberPredicateFilter("number", "1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new NumberPredicateFilter("number", "1|not_2"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new NumberPredicateFilter("number", "not_1|not_2"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new NumberPredicateFilter("number", "1|2"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new NumberPredicateFilter("number", "1|2|null"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - } - - class Entity { - @FilterType(type = FilterType.Type.NUMBER) - private Long number; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilterTest.java deleted file mode 100644 index ec9b618d..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/PredicateFilterTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import java.util.Date; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -class PredicateFilterTest extends MockHelper { - - @Test - void testConstructor() { - PredicateFilterFake filter = new PredicateFilterFake(null, null); - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - - filter = new PredicateFilterFake("text", "test"); - assertEquals("text", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("test", filter.getValues()[0]); - - assertTrue(PredicateOperator.get("bad").isEmpty()); - assertNotNull(filter.getOperators()); - } - - @Test - void testSetOperatorFromValue() { - PredicateFilterFake filter = new PredicateFilterFake("eq1", PredicateOperator.EQUALS.getValue()); - filter.extract(); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - assertFalse(filter.getIsNotOperator(0)); - - filter = new PredicateFilterFake(null, "not_null"); - filter.extract(); - assertEquals(PredicateOperator.NULL, filter.getOperator(0)); - assertTrue(filter.getIsNotOperator(0)); - - filter = new PredicateFilterFake(null, "null"); - filter.extract(); - assertEquals(PredicateOperator.NULL, filter.getOperator(0)); - assertFalse(filter.getIsNotOperator(0)); - - filter = new PredicateFilterFake(null, PredicateOperator.NULL.getValue()); - filter.extract(); - assertEquals(PredicateOperator.NULL, filter.getOperator(0)); - } - - @Test - void testExtract() { - PredicateFilterFake filter = new PredicateFilterFake(null, null); - assertFalse(filter.extract()); - - filter = new PredicateFilterFake(null, "not_"); - assertTrue(filter.extract()); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - assertTrue(filter.getIsNotOperator(0)); - assertEquals("", filter.getValue(0)); - } - - @Test - void getPredicateTest() { - EntityManager entityManager = mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - PredicateFilterFake filter = new PredicateFilterFake("text", "test"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new PredicateFilterFake("text", "not_null"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new PredicateFilterFake("text", "null"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new PredicateFilterFake("text", "not_1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new PredicateFilterFake("text", "1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - } - - private class PredicateFilterFake extends PredicateFilter { - - public PredicateFilterFake(final String name, final String value) { - super(name, value, FilterType.Type.TEXT); - } - } - - - class Entity { - @FilterType(type = FilterType.Type.NUMBER) - private Long number; - @FilterType(type = FilterType.Type.TEXT) - private String text; - @FilterType(type = FilterType.Type.BOOLEAN) - private boolean bool; - @FilterType(type = FilterType.Type.TOKEN) - private String token; - @FilterType(type = FilterType.Type.DATE) - private Date date; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilterTest.java deleted file mode 100644 index 7c8c0cd3..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TextPredicateFilterTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: TextPredicateFilter") -class TextPredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - TextPredicateFilter filter = new TextPredicateFilter(null, null); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - - filter = new TextPredicateFilter("test", "value"); - assertEquals("test", filter.getName()); - assertEquals(1, filter.getValues().length); - assertEquals("value", filter.getValues()[0]); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void testGetPredicate() { - EntityManager entityManager = mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - TextPredicateFilter filter = new TextPredicateFilter("text", "1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - - filter = new TextPredicateFilter("text", ""); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - - filter = new TextPredicateFilter("text", "%"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - - filter = new TextPredicateFilter("text", "lk_1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertFalse(filter.getIsNotOperator(0)); - assertEquals(PredicateOperator.LIKE, filter.getOperator(0)); - assertEquals("1", filter.getValue(0)); - } - - - @Test - @DisplayName("Test getPredicate: should return wanted 'not' predicate.") - void testGetPredicateNot() { - EntityManager entityManager = mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - TextPredicateFilter filter = new TextPredicateFilter("text", "not_1"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - - filter = new TextPredicateFilter("text", "not_"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - - filter = new TextPredicateFilter("text", "not_%"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - - filter = new TextPredicateFilter("text", "not_lk_test"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.LIKE, filter.getOperator(0)); - assertTrue(filter.getIsNotOperator(0)); - assertEquals("TEST", filter.getValue(0)); - - filter = new TextPredicateFilter("text", "not_lk_t*es*t"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.LIKE, filter.getOperator(0)); - assertTrue(filter.getIsNotOperator(0)); - assertEquals("T%ES%T", filter.getValue(0)); - } - - class Entity { - @FilterType(type = FilterType.Type.TEXT) - private String text; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilterTest.java deleted file mode 100644 index 5fcbead9..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/TokenPredicateFilterTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import com.ditrit.letomodelizerapi.persistence.specification.PredicateOperator; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: TokenPredicateFilter") -class TokenPredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - TokenPredicateFilter filter = new TokenPredicateFilter(null, null); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void testGetPredicate() { - EntityManager entityManager = mockEntityManager(Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(Entity.class); - final Root root = query.from(Entity.class); - - TokenPredicateFilter filter = new TokenPredicateFilter("token", "test"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - - filter = new TokenPredicateFilter("token", "not_test"); - assertTrue(filter.extract()); - assertNotNull(filter.getPredicate(builder, root, null)); - assertEquals(PredicateOperator.EQUALS, filter.getOperator(0)); - } - - class Entity { - @FilterType(type = FilterType.Type.TOKEN) - private String token; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilterTest.java b/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilterTest.java deleted file mode 100644 index e90315f5..00000000 --- a/src/test/java/com/ditrit/letomodelizerapi/persistence/specification/filter/UUIDPredicateFilterTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.ditrit.letomodelizerapi.persistence.specification.filter; - -import com.ditrit.letomodelizerapi.helper.MockHelper; -import jakarta.persistence.EntityManager; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.*; - -@Tag("unit") -@DisplayName("Test class: UUIDPredicateFilter") -class UUIDPredicateFilterTest extends MockHelper { - - @Test - @DisplayName("Test constructor: should set values from parameters.") - void constructorTest() { - UUIDPredicateFilter filter = new UUIDPredicateFilter(null, null); - - assertNull(filter.getName()); - assertEquals(0, filter.getValues().length); - } - - @Test - @DisplayName("Test getPredicate: should return wanted predicate.") - void getPredicateTest() { - EntityManager entityManager = this.mockEntityManager(BooleanPredicateFilterTest.Entity.class); - final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); - final CriteriaQuery query = builder.createQuery(BooleanPredicateFilterTest.Entity.class); - final Root root = query.from(UUIDPredicateFilterTest.Entity.class); - - UUIDPredicateFilter filter = new UUIDPredicateFilter("uuid", UUID.randomUUID().toString()); - assertTrue(filter.extract()); - - Predicate predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertFalse(filter.getIsNotOperator(0)); - - filter = new UUIDPredicateFilter("uuid", "not_" + UUID.randomUUID()); - assertTrue(filter.extract()); - - predicate = filter.getPredicate(builder, root, null); - assertNotNull(predicate); - assertTrue(filter.getIsNotOperator(0)); - } - - class Entity { - @FilterType(type = FilterType.Type.UUID) - private UUID uuid; - } -} diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImplTest.java index c41a985f..180568cd 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/AIConfigurationServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AIConfigurationRecord; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; @@ -52,7 +53,7 @@ void testFindAll() { Mockito.when(aiConfigurationRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(page); - var result = service.findAll(Map.of(), Pageable.ofSize(10)); + var result = service.findAll(Map.of(), new QueryFilter()); assertEquals(configuration, result.getContent().getFirst()); } diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/AISecretServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/AISecretServiceImplTest.java index 44d3880a..8ad65ba1 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/AISecretServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/AISecretServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AISecretRecord; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; @@ -70,7 +71,7 @@ void testFindAll() { Mockito.when(aiSecretRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(page); - var result = service.findAll(Map.of(), Pageable.ofSize(10)); + var result = service.findAll(Map.of(), new QueryFilter()); assertEquals(expectedSecret, result.getContent().getFirst()); } diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/AIServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/AIServiceImplTest.java index f95aa945..858921a6 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/AIServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/AIServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.ai.AIConversationRecord; import com.ditrit.letomodelizerapi.model.ai.AICreateFileRecord; import com.ditrit.letomodelizerapi.model.ai.AIMessageRecord; @@ -23,7 +24,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; @@ -410,7 +410,7 @@ void testFindAll() { User user = new User(); user.setId(UUID.randomUUID()); - assertEquals(Page.empty(), service.findAll(user, Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(user, Map.of(), new QueryFilter())); } @Test @@ -427,7 +427,7 @@ void testFindAllMessages() { User user = new User(); user.setId(UUID.randomUUID()); - assertEquals(Page.empty(), service.findAllMessages(user, UUID.randomUUID(), Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAllMessages(user, UUID.randomUUID(), Map.of(), new QueryFilter())); } @Test @@ -442,7 +442,7 @@ void testFindAllMessagesThrowException() { ApiException exception = null; try { - service.findAllMessages(user, UUID.randomUUID(), Map.of(), Pageable.ofSize(10)); + service.findAllMessages(user, UUID.randomUUID(), Map.of(), new QueryFilter()); } catch (ApiException e) { exception = e; } @@ -462,7 +462,7 @@ void testFindAllConversations() { .thenReturn(Page.empty()); AIServiceImpl service = newInstance(); - assertEquals(Page.empty(), service.findAllConversations(Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAllConversations(Map.of(), new QueryFilter())); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImplTest.java index 1592cc7d..bac4c9be 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlPermissionServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.persistence.model.AccessControlPermission; @@ -14,7 +15,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import java.util.Map; @@ -44,7 +44,7 @@ void testFindAll() { .when(accessControlPermissionViewRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(UUID.randomUUID(), Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(UUID.randomUUID(), Map.of(), new QueryFilter())); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImplTest.java index 8ebb4282..f08b768b 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/AccessControlServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlRecord; import com.ditrit.letomodelizerapi.model.accesscontrol.AccessControlType; import com.ditrit.letomodelizerapi.model.error.ApiException; @@ -23,7 +24,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import java.util.Map; @@ -67,7 +67,7 @@ void testFindAll() { .when(accessControlRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(AccessControlType.ROLE, Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(AccessControlType.ROLE, Map.of(), new QueryFilter())); } @Test @@ -80,7 +80,7 @@ void testFindAllOfUsers() { .when(userAccessControlViewRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(AccessControlType.ROLE, user, Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(AccessControlType.ROLE, user, Map.of(), new QueryFilter())); } @Test @@ -97,7 +97,7 @@ void testFindAllAccessControls() { .when(accessControlRepository.findOne(Mockito.any(Specification.class))) .thenReturn(Optional.of(accessControl)); - assertEquals(Page.empty(), service.findAllAccessControls(AccessControlType.ROLE, id, AccessControlType.ROLE, Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAllAccessControls(AccessControlType.ROLE, id, AccessControlType.ROLE, Map.of(), new QueryFilter())); } @Test @@ -115,7 +115,7 @@ void testFindAllChildren() { .when(accessControlTreeViewRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAllChildren(AccessControlType.ROLE, id, AccessControlType.GROUP, Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAllChildren(AccessControlType.ROLE, id, AccessControlType.GROUP, Map.of(), new QueryFilter())); } @Test @@ -132,7 +132,7 @@ void testFindAllUsers() { .when(userAccessControlViewRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAllUsers(AccessControlType.ROLE, UUID.randomUUID(), Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAllUsers(AccessControlType.ROLE, UUID.randomUUID(), Map.of(), new QueryFilter())); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/LibraryServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/LibraryServiceImplTest.java index e7c1e828..a17b092c 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/LibraryServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/LibraryServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.model.library.LibraryRecord; @@ -23,7 +24,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; @@ -667,7 +667,7 @@ void testFindAll() { Mockito.when(libraryRepository.findAll(Mockito.any(Specification.class), Mockito.any())).thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(Map.of(), PageRequest.of(1, 1))); + assertEquals(Page.empty(), service.findAll(Map.of(), new QueryFilter())); } @Test @@ -678,7 +678,7 @@ void testFindAllByUser() { Mockito.when(userLibraryViewRepository.findAll(Mockito.any(Specification.class), Mockito.any())).thenReturn(Page.empty()); User user = new User(); user.setId(UUID.randomUUID()); - assertEquals(Page.empty(), service.findAll(user, Map.of(), PageRequest.of(1, 1))); + assertEquals(Page.empty(), service.findAll(user, Map.of(), new QueryFilter())); } @Test @@ -688,7 +688,7 @@ void testFindAllTemplates() { Mockito.when(libraryTemplateRepository.findAll(Mockito.any(Specification.class), Mockito.any())).thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAllTemplates(Map.of(), PageRequest.of(1, 1))); + assertEquals(Page.empty(), service.findAllTemplates(Map.of(), new QueryFilter())); } @Test @@ -699,7 +699,7 @@ void testFindAllTemplatesByUser() { Mockito.when(userLibraryTemplateViewRepository.findAllByUserId(Mockito.any(), Mockito.any(Specification.class), Mockito.any())).thenReturn(Page.empty()); User user = new User(); user.setId(UUID.randomUUID()); - assertEquals(Page.empty(), service.findAllTemplates(user, Map.of(), PageRequest.of(1, 1))); + assertEquals(Page.empty(), service.findAllTemplates(user, Map.of(), new QueryFilter())); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/PermissionServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/PermissionServiceImplTest.java index 7790cf6a..e382ab7d 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/PermissionServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/PermissionServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.persistence.model.AccessControl; @@ -16,7 +17,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import java.util.Map; @@ -50,7 +50,7 @@ void testFindAll() { .when(permissionRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(Map.of(), new QueryFilter())); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImplTest.java index da5111cf..d924b0b9 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/UserPermissionServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.model.permission.ActionPermission; @@ -17,7 +18,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; @@ -71,7 +71,7 @@ void testFindAll() { .when(userPermissionRepository.findAll(Mockito.any(Specification.class), Mockito.any())) .thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(user, Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(user, Map.of(), new QueryFilter())); } @Test diff --git a/src/test/java/com/ditrit/letomodelizerapi/service/UserServiceImplTest.java b/src/test/java/com/ditrit/letomodelizerapi/service/UserServiceImplTest.java index 3ecd9d6e..3340e2c5 100644 --- a/src/test/java/com/ditrit/letomodelizerapi/service/UserServiceImplTest.java +++ b/src/test/java/com/ditrit/letomodelizerapi/service/UserServiceImplTest.java @@ -1,5 +1,6 @@ package com.ditrit.letomodelizerapi.service; +import com.ditrit.letomodelizerapi.controller.model.QueryFilter; import com.ditrit.letomodelizerapi.model.error.ApiException; import com.ditrit.letomodelizerapi.model.error.ErrorType; import com.ditrit.letomodelizerapi.model.user.UserRecord; @@ -16,7 +17,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import java.io.IOException; @@ -240,7 +240,7 @@ void testGetPicture() throws IOException, InterruptedException { @DisplayName("Test findAll: should retrieve all paginated users") void testFindAll() { Mockito.when(userRepository.findAll(Mockito.any(Specification.class), Mockito.any())).thenReturn(Page.empty()); - assertEquals(Page.empty(), service.findAll(Map.of(), Pageable.ofSize(10))); + assertEquals(Page.empty(), service.findAll(Map.of(), new QueryFilter())); } @Test