make API more robust

Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
2024-08-16 23:32:17 +02:00
parent d2dd2fb129
commit 28965a9623
7 changed files with 49 additions and 10 deletions

View File

@@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -1,14 +1,23 @@
package dev.mars3142.fhq.timezone_service.config;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
@Configuration
@EnableCaching
public class AppConfig {
@Bean
public RestClient restClient() {
return RestClient.create();
}
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}

View File

@@ -0,0 +1,5 @@
package dev.mars3142.fhq.timezone_service.timezone.domain.entities.response;
public record IpifyResponse(String ip) {
}

View File

@@ -1,7 +1,9 @@
package dev.mars3142.fhq.timezone_service.timezone.domain.entities.response;
public record WorldTimeApiIpResponse(String utc_offset, String timezone, int day_of_week, int day_of_year, String datetime,
public record WorldTimeApiIpResponse(String utc_offset, String timezone, int day_of_week, int day_of_year,
String datetime,
String utc_datetime, int unixtime, int raw_offset, int week_number, boolean dst,
String abbreviation, int dst_offset, String dst_from, String dst_until, String client_ip) {
String abbreviation, int dst_offset, String dst_from, String dst_until,
String client_ip) {
}

View File

@@ -6,7 +6,9 @@ import java.util.List;
public interface TimeZoneService {
WorldTimeApiIpResponse getTimeZoneInfoByIp();
String getExternalIp(String ip);
WorldTimeApiIpResponse getTimeZoneInfoByIp(String ip);
TimeApiTimezoneZoneResponse getTimeZoneInfo(String timezone);

View File

@@ -1,6 +1,7 @@
package dev.mars3142.fhq.timezone_service.timezone.service.impl;
import dev.mars3142.fhq.timezone_service.exceptions.NotFoundException;
import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.IpifyResponse;
import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.TimeApiTimezoneZoneResponse;
import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.WorldTimeApiIpResponse;
import dev.mars3142.fhq.timezone_service.timezone.service.TimeZoneService;
@@ -13,6 +14,7 @@ import java.util.Objects;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
@@ -24,15 +26,30 @@ public class TimeZoneServiceImpl implements TimeZoneService {
private final RestClient restClient;
@Override
public WorldTimeApiIpResponse getTimeZoneInfoByIp() {
public String getExternalIp(String ip) {
if (ip.equals("127.0.0.1")) {
val response = restClient
.get()
.uri("https://api.ipify.org?format=json")
.retrieve()
.body(IpifyResponse.class);
return Objects.requireNonNull(response).ip();
}
return ip;
}
@Override
@Cacheable(value = "TZInfoByIp", key = "{#ip}")
public WorldTimeApiIpResponse getTimeZoneInfoByIp(String ip) {
return restClient
.get()
.uri("https://worldtimeapi.org/api/ip")
.uri("https://worldtimeapi.org/api/ip/" + ip)
.retrieve()
.body(WorldTimeApiIpResponse.class);
}
@Override
@Cacheable(value = "TZInfo", key = "{#timezone}")
public TimeApiTimezoneZoneResponse getTimeZoneInfo(String timezone) {
return restClient
.get()
@@ -50,6 +67,7 @@ public class TimeZoneServiceImpl implements TimeZoneService {
}
@Override
@Cacheable(value = "posixTZ", key = "{#timezone}")
public String getPosixTimeZone(String timezone) {
val filename = Path.of("/usr/share/zoneinfo/" + timezone);
if (!filename.toFile().exists()) {
@@ -65,6 +83,7 @@ public class TimeZoneServiceImpl implements TimeZoneService {
}
@Override
@Cacheable(value = "locations", key = "{#area}")
public List<String> getLocations(String area) {
val directory = new File("/usr/share/zoneinfo/" + area);
if (!directory.exists()) {

View File

@@ -3,6 +3,7 @@ package dev.mars3142.fhq.timezone_service.timezone.web.controllers;
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 jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.web.bind.annotation.GetMapping;
@@ -18,8 +19,9 @@ public class TimeZoneController {
private final TimeZoneService timeZoneService;
@GetMapping
public TimeZoneResponse getTimeZone() {
val timezoneInfo = timeZoneService.getTimeZoneInfoByIp();
public TimeZoneResponse getTimeZone(HttpServletRequest request) {
val ip = timeZoneService.getExternalIp(request.getRemoteAddr());
val timezoneInfo = timeZoneService.getTimeZoneInfoByIp(ip);
val posix = timeZoneService.getPosixTimeZone(timezoneInfo.timezone());
return new TimeZoneResponse(timezoneInfo.timezone(), timezoneInfo.abbreviation(), posix);
}