From a184f4a038599c3cf217e84acf838ea32e7d5597 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Wed, 30 Oct 2024 12:02:30 +0100 Subject: [PATCH] remove hal+json and add pageable Signed-off-by: Peter Siegmund --- pom.xml | 8 +-- .../controllers/TimezoneController.java | 26 ++++---- .../model/response/LocationResponse.java | 17 ------ .../model/response/TimezoneResponse.java | 3 +- .../timezone/service/TimezoneService.java | 5 +- .../service/impl/TimezoneServiceImpl.java | 59 +++++++++++++------ .../service/impl/TimezoneServiceImplTest.java | 2 +- 7 files changed, 64 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/LocationResponse.java diff --git a/pom.xml b/pom.xml index 70ad326..f2f1949 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,10 @@ spring-boot-starter-test test + + org.springframework.data + spring-data-commons + org.springframework.modulith spring-modulith-starter-test @@ -82,10 +86,6 @@ org.springframework.cloud spring-cloud-starter-netflix-eureka-client - - org.springframework.boot - spring-boot-starter-hateoas - com.github.ben-manes.caffeine caffeine diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/controllers/TimezoneController.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/controllers/TimezoneController.java index 2d3d2de..24d75a8 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/controllers/TimezoneController.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/controllers/TimezoneController.java @@ -1,19 +1,18 @@ package dev.mars3142.fhq.timezone_service.timezone.controllers; -import static org.springframework.beans.support.PagedListHolder.DEFAULT_PAGE_SIZE; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; - -import dev.mars3142.fhq.timezone_service.timezone.domain.model.response.LocationResponse; import dev.mars3142.fhq.timezone_service.timezone.domain.model.response.TimezoneResponse; import dev.mars3142.fhq.timezone_service.timezone.service.TimezoneService; import lombok.RequiredArgsConstructor; import lombok.val; -import org.springdoc.core.converters.models.Pageable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort.Direction; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -35,18 +34,20 @@ public class TimezoneController { val response = new TimezoneResponse(); response.setTimezone(timezoneInfo.timezone()); response.setPosix_tz(posix); - response.add(linkTo(TimezoneController.class).slash(ip).withSelfRel()); return response; } @GetMapping("{area}") @ResponseStatus(HttpStatus.OK) - public LocationResponse getLocations(@PathVariable String area) { - val locations = timeZoneService.getLocations(area); - val result = new LocationResponse(); - result.setLocations(locations); - result.add(linkTo(TimezoneController.class).slash(area).withSelfRel()); - return result; + public Page getLocations(@PathVariable String area, + @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize, + @RequestParam(value = "page", required = false, defaultValue = "0") int page, + @RequestParam(value = "direction", required = false) String direction) { + var pageRequest = PageRequest.of(page, pageSize); + if (direction != null && !direction.isEmpty()) { + pageRequest = PageRequest.of(page, pageSize, Direction.fromString(direction), "location"); + } + return timeZoneService.getPagedLocations(area, pageRequest); } @GetMapping("{area}/{location}") @@ -57,7 +58,6 @@ public class TimezoneController { val response = new TimezoneResponse(); response.setTimezone(timezone); response.setPosix_tz(posix); - response.add(linkTo(TimezoneController.class).slash(area).slash(location).withSelfRel()); return response; } } diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/LocationResponse.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/LocationResponse.java deleted file mode 100644 index 040ee60..0000000 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/LocationResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.mars3142.fhq.timezone_service.timezone.domain.model.response; - -import java.util.List; -import lombok.Getter; -import org.springframework.hateoas.RepresentationModel; - -@Getter -public class LocationResponse extends RepresentationModel { - - private int count; - private List locations; - - public void setLocations(List locations) { - this.count = locations.size(); - this.locations = locations; - } -} diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/TimezoneResponse.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/TimezoneResponse.java index 026d48f..b5329f6 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/TimezoneResponse.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/domain/model/response/TimezoneResponse.java @@ -2,11 +2,10 @@ package dev.mars3142.fhq.timezone_service.timezone.domain.model.response; import lombok.Getter; import lombok.Setter; -import org.springframework.hateoas.RepresentationModel; @Getter @Setter -public class TimezoneResponse extends RepresentationModel { +public class TimezoneResponse { private String timezone; private String posix_tz; diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/TimezoneService.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/TimezoneService.java index 6b0556b..b22f0b5 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/TimezoneService.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/TimezoneService.java @@ -2,7 +2,8 @@ package dev.mars3142.fhq.timezone_service.timezone.service; import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.IPApiResponse; import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.TimeApiTimezoneZoneResponse; -import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; public interface TimezoneService { @@ -14,5 +15,5 @@ public interface TimezoneService { String getPosixTimeZone(String timezone); - List getLocations(String area); + Page getPagedLocations(String area, PageRequest pageRequest); } diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImpl.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImpl.java index a1519c1..e9de16c 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImpl.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImpl.java @@ -15,6 +15,9 @@ import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; @@ -48,18 +51,18 @@ public class TimezoneServiceImpl implements TimezoneService { @Override @Cacheable(value = "TZInfoByIp", key = "{#ip}") public IPApiResponse getTimeZoneInfoByIp(String ip) { - return restClient - .get() - .uri(builder -> builder - .scheme("http") - .host("ip-api.com") - .path("json/" + ip) - .build()) - .retrieve() - .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { - throw new NotFoundException(); - }) - .body(IPApiResponse.class); + return restClient + .get() + .uri(builder -> builder + .scheme("http") + .host("ip-api.com") + .path("json/" + ip) + .build()) + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { + throw new NotFoundException(); + }) + .body(IPApiResponse.class); } @Override @@ -97,19 +100,41 @@ public class TimezoneServiceImpl implements TimezoneService { } @Override - @Cacheable(value = "locations", key = "{#area}") - public List getLocations(String area) { + @Cacheable(value = "locations", key = "{#area, #pageRequest}") + public Page getPagedLocations(String area, PageRequest pageRequest) { val directory = new File("/usr/share/zoneinfo/" + area); if (!directory.exists()) { throw new NotFoundException(); } - return Stream.of(Objects.requireNonNull(directory.listFiles())) + return toPage(Stream.of(Objects.requireNonNull(directory.listFiles())) .filter(file -> !file.isDirectory()) .map(file -> { val path = file.getPath().split("/"); return path[path.length - 2] + "/" + path[path.length - 1]; }) - .sorted() - .toList(); + .toList(), pageRequest); + } + + Page toPage(List list, PageRequest pageRequest) { + val pageSize = pageRequest.getPageSize(); + val pageNumber = pageRequest.getPageNumber(); + val totalPages = list.size() / pageSize; + + int max = pageNumber >= totalPages ? list.size() : pageSize * (pageNumber + 1); + int min = pageNumber > totalPages ? max : pageSize * pageNumber; + + var content = list.stream().sorted((left, right) -> { + if (!pageRequest.getSort().isSorted()) { + return 0; + } + + if (Objects.requireNonNull(pageRequest.getSort().getOrderFor("location")).isAscending()) { + return left.compareTo(right); + } else { + return right.compareTo(left); + } + } + ); + return new PageImpl<>(content.toList().subList(min, max), pageRequest, list.size()); } } diff --git a/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImplTest.java b/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImplTest.java index a5186f2..2f35f0b 100644 --- a/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImplTest.java +++ b/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimezoneServiceImplTest.java @@ -59,6 +59,6 @@ class TimezoneServiceImplTest { } @Test - void getLocations() { + void getPagedLocations() { } }