diff --git a/src/main/java/ru/soune/nocopy/service/geo/GeoCountryService.java b/src/main/java/ru/soune/nocopy/service/geo/GeoCountryService.java index b88ad6d..13ef5dd 100644 --- a/src/main/java/ru/soune/nocopy/service/geo/GeoCountryService.java +++ b/src/main/java/ru/soune/nocopy/service/geo/GeoCountryService.java @@ -2,50 +2,61 @@ package ru.soune.nocopy.service.geo; import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.model.CountryResponse; +import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; -import java.io.IOException; import java.net.InetAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; @Service @Slf4j public class GeoCountryService { + private DatabaseReader dbReader; - private final DatabaseReader dbReader; + private final Map cache = new ConcurrentHashMap<>(); - public GeoCountryService() throws IOException { - Resource resource = new ClassPathResource("geo/GeoLite2-Country.mmdb"); - this.dbReader = new DatabaseReader.Builder(resource.getInputStream()).build(); + @PostConstruct + public void init() { + try { + var resource = new ClassPathResource("geo/GeoLite2-Country.mmdb"); + this.dbReader = new DatabaseReader.Builder(resource.getInputStream()).build(); + log.info("Geo DB loaded"); + } catch (Exception e) { + log.error("Failed to load Geo DB", e); + throw new RuntimeException(e); + } } - public String getCountry(String input) { + public String getCountry(String url) { + if (url == null || url.isBlank()) { + return null; + } + + String host = extractHost(url); + if (cache.containsKey(host)) { + return cache.get(host); + } + try { - String domain = extractDomain(input); - - InetAddress ip = InetAddress.getByName(domain); - + InetAddress ip = InetAddress.getByName(host); CountryResponse response = dbReader.country(ip); + String country = response.getCountry().getIsoCode(); - return response.getCountry().getIsoCode(); + cache.put(host, country); + return country; } catch (Exception e) { - log.error("Failed for input: {}", input, e); - return "UNKNOWN"; + log.debug("Cannot determine country for: {}", host); + cache.put(host, null); + return null; } } - private String extractDomain(String input) { - if (input == null || input.isEmpty()) { - throw new IllegalArgumentException("Input is empty"); - } - - String cleaned = input.replaceAll("^https?://", ""); - cleaned = cleaned.split("/")[0]; - cleaned = cleaned.split(":")[0]; - - return cleaned; + private String extractHost(String url) { + String cleaned = url.replaceFirst("^https?://", ""); + return cleaned.split("[/:]")[0]; } }