diff --git a/src/main/java/app/services/StatsService.java b/src/main/java/app/services/StatsService.java index 342346f..5bd2df8 100644 --- a/src/main/java/app/services/StatsService.java +++ b/src/main/java/app/services/StatsService.java @@ -5,10 +5,9 @@ import app.entities.other.SteamID; import app.entities.server.PlayOn; import app.entities.server.Server; import app.entities.server.players.RCONPlayer; -import app.services.io.GeoIP; +import app.services.io.readers.GeoIP; import app.utils.CryptedCookie; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import java.util.Map; @@ -16,7 +15,6 @@ import java.util.Map; @Service public class StatsService { Stats stats; - private CryptedCookie cryptedCookie; private GeoIP geoIP; diff --git a/src/main/java/app/services/io/GeoIP.java b/src/main/java/app/services/io/GeoIP.java deleted file mode 100644 index 9d27fd0..0000000 --- a/src/main/java/app/services/io/GeoIP.java +++ /dev/null @@ -1,35 +0,0 @@ -package app.services.io; - -import com.maxmind.geoip2.DatabaseReader; -import com.maxmind.geoip2.exception.GeoIp2Exception; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.Resource; -import org.springframework.stereotype.Component; - -import java.io.File; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -@Component -public class GeoIP { - private DatabaseReader databaseReader; - - @Autowired - public GeoIP(@Value("${backend.geoip_file}") String data) throws IOException { - databaseReader = new DatabaseReader.Builder(new File(data)).build(); - } - - public String GetCountry(String ip) throws UnknownHostException, GeoIp2Exception, IOException { - return databaseReader.country(InetAddress.getByName(ip)).getCountry().getName(); - } - - public String GetCountry(String ip, String replace) { - try { - return this.GetCountry(ip); - } catch (GeoIp2Exception | IOException e) { - return replace; - } - } -} diff --git a/src/main/java/app/services/io/ServersReader.java b/src/main/java/app/services/io/ServersReader.java deleted file mode 100644 index e47cee1..0000000 --- a/src/main/java/app/services/io/ServersReader.java +++ /dev/null @@ -1,43 +0,0 @@ -package app.services.io; - -import app.entities.server.Server; -import app.entities.Stats; -import app.updates.PlayersUpdater; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import java.io.File; -import java.io.IOException; -import java.util.Iterator; -import java.util.Map; - -@Component -public class ServersReader { - Stats stats; - ObjectMapper objectMapper; - - private final Logger logger = LoggerFactory.getLogger(ServersReader.class); - @Autowired - public ServersReader(Stats stats, @Value("${backend.servers_file}") String servers_path) { - this.stats = stats; - this.objectMapper = new ObjectMapper(); - - try { - logger.info("Read from: {}", servers_path); - JsonNode node = this.objectMapper.readTree(new File(servers_path)); - Iterator> iterator = node.fields(); - while (iterator.hasNext()) { - Map.Entry server = iterator.next(); - stats.getServers().put(server.getKey(), this.objectMapper.treeToValue(server.getValue(), Server.class)); - logger.info("{}\n{}",server.getKey() ,stats.getServers().get(server.getKey())); - } - } catch (IOException err) { - logger.error("Cannot read servers file: {}", servers_path); - } - } -} diff --git a/src/main/java/app/services/io/fileloader/GitFileLoader.java b/src/main/java/app/services/io/fileloader/GitFileLoader.java new file mode 100644 index 0000000..4897692 --- /dev/null +++ b/src/main/java/app/services/io/fileloader/GitFileLoader.java @@ -0,0 +1,55 @@ +package app.services.io.fileloader; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class GitFileLoader implements IFileLoader { + private final String token; + private final RestTemplate restTemplate; + + public GitFileLoader() { + this.token = System.getenv("GIT_TOKEN"); + this.restTemplate = new RestTemplate(); + if (!isEnabled()) { + logger.warn("{} is disable", getClass().getName()); + } + } + + private HttpEntity getEntity() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.set("Authorization", "token " + token); + return new HttpEntity<>("", httpHeaders); + } + + /* + url: https://{githost}/api/v1/repos/{user}/{repo}/raw/{file} + */ + @Override + public byte[] loadFile(String path) { + if (path == null || path.isEmpty()) return null; + logger.info("Load file using git: {}", path); + ResponseEntity response = restTemplate.exchange(path, HttpMethod.GET, getEntity(), byte[].class); + if (response.getStatusCode().is2xxSuccessful()) return response.getBody(); + else return null; + } + + @Override + public boolean isEnabled() { + return token != null && !token.isEmpty(); + } + + @Override + public int getPriority() { + return Integer.MIN_VALUE; + } + + @Override + public String getSuffix() { + return "_GIT"; + } +} diff --git a/src/main/java/app/services/io/fileloader/IFileLoader.java b/src/main/java/app/services/io/fileloader/IFileLoader.java new file mode 100644 index 0000000..e8a6ccd --- /dev/null +++ b/src/main/java/app/services/io/fileloader/IFileLoader.java @@ -0,0 +1,12 @@ +package app.services.io.fileloader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public interface IFileLoader { + Logger logger = LoggerFactory.getLogger(IFileLoader.class); + byte[] loadFile(String path); + boolean isEnabled(); + int getPriority(); + String getSuffix(); +} diff --git a/src/main/java/app/services/io/fileloader/LocalyFileLoader.java b/src/main/java/app/services/io/fileloader/LocalyFileLoader.java new file mode 100644 index 0000000..bb38303 --- /dev/null +++ b/src/main/java/app/services/io/fileloader/LocalyFileLoader.java @@ -0,0 +1,41 @@ +package app.services.io.fileloader; + +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +@Component +public class LocalyFileLoader implements IFileLoader { + + public LocalyFileLoader() {} + + @Override + public byte[] loadFile(String path) { + if (path == null || path.isEmpty()) return null; + if (!Files.exists(Path.of(path))) return null; + logger.info("Load file using disk: {}", path); + try { + return Files.readAllBytes(new File(path).toPath()); + } catch (IOException ioe) { + return null; + } + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public int getPriority() { + return Integer.MAX_VALUE; + } + + @Override + public String getSuffix() { + return ""; + } +} diff --git a/src/main/java/app/services/io/readers/BaseReader.java b/src/main/java/app/services/io/readers/BaseReader.java new file mode 100644 index 0000000..e887f04 --- /dev/null +++ b/src/main/java/app/services/io/readers/BaseReader.java @@ -0,0 +1,38 @@ +package app.services.io.readers; + +import app.services.io.fileloader.IFileLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; + +@Component +public abstract class BaseReader { + + protected final static Logger logger = LoggerFactory.getLogger(ServersReader.class); + public List fileLoaders; + + @Autowired + public BaseReader(List fileLoaders) { + this.fileLoaders = fileLoaders; + } + + public Object loadConfiguration(String environmentVar, Function reMap) { + return fileLoaders.stream() + .filter(IFileLoader::isEnabled) + .sorted(Comparator.comparingInt(IFileLoader::getPriority)) + .peek(l -> logger.info("Use {}", l.getClass().getName())) + .map(l -> l.loadFile(System.getenv(environmentVar + l.getSuffix()))) + .filter(Objects::nonNull) + .map(reMap) + .filter(Objects::nonNull) + .limit(1) + .findFirst() + .orElse(null); + } +} diff --git a/src/main/java/app/services/io/readers/GeoIP.java b/src/main/java/app/services/io/readers/GeoIP.java new file mode 100644 index 0000000..6ca9f40 --- /dev/null +++ b/src/main/java/app/services/io/readers/GeoIP.java @@ -0,0 +1,53 @@ +package app.services.io.readers; + +import app.services.io.fileloader.IFileLoader; +import com.maxmind.geoip2.DatabaseReader; +import com.maxmind.geoip2.exception.GeoIp2Exception; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; + +@Component +public class GeoIP extends BaseReader { + private final DatabaseReader databaseReader; + + @Autowired + public GeoIP(List fileLoaders) { + super(fileLoaders); + databaseReader = loadConfiguration(); + if (databaseReader == null) { + logger.error("GEOIP file is missing"); + System.exit(1); + } + } + + public String GetCountry(String ip) throws UnknownHostException, GeoIp2Exception, IOException { + return databaseReader.country(InetAddress.getByName(ip)).getCountry().getName(); + } + + public String GetCountry(String ip, String replace) { + try { + return this.GetCountry(ip); + } catch (GeoIp2Exception | IOException e) { + return replace; + } + } + + public DatabaseReader loadConfiguration() { + return (DatabaseReader) super.loadConfiguration( + "GEOIP_FILE", + b -> { + try { + return new DatabaseReader.Builder(new ByteArrayInputStream(b)).build(); + } catch (IOException e) { + return null; + } + } + ); + } +} diff --git a/src/main/java/app/services/io/readers/ServersReader.java b/src/main/java/app/services/io/readers/ServersReader.java new file mode 100644 index 0000000..52bff5b --- /dev/null +++ b/src/main/java/app/services/io/readers/ServersReader.java @@ -0,0 +1,47 @@ +package app.services.io.readers; + +import app.entities.server.Server; +import app.entities.Stats; +import app.services.io.fileloader.IFileLoader; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.*; + +@Component +public class ServersReader extends BaseReader { + Stats stats; + private final static ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + public ServersReader(Stats stats, List fileLoaders) { + super(fileLoaders); + this.stats = stats; + try { + Iterator> iterator = loadConfiguration().fields(); + while (iterator.hasNext()) { + Map.Entry server = iterator.next(); + stats.getServers().put(server.getKey(), objectMapper.treeToValue(server.getValue(), Server.class)); + logger.info("{}\n{}",server.getKey() ,stats.getServers().get(server.getKey())); + } + } catch (IOException err) { + logger.error("Cannot parse configuration", err); + System.exit(1); + } + } + + public JsonNode loadConfiguration() { + return (JsonNode) super.loadConfiguration( + "SERVERS_FILE", + b -> { + try { + return objectMapper.readTree(b); + } catch (IOException e) { + return null; + } + }); + } +} diff --git a/src/main/java/app/updates/CountriesUpdater.java b/src/main/java/app/updates/CountriesUpdater.java index 50a0831..a6a588e 100644 --- a/src/main/java/app/updates/CountriesUpdater.java +++ b/src/main/java/app/updates/CountriesUpdater.java @@ -1,7 +1,7 @@ package app.updates; import app.entities.server.Server; -import app.services.io.GeoIP; +import app.services.io.readers.GeoIP; import app.entities.Stats; import com.maxmind.geoip2.exception.GeoIp2Exception; import jakarta.annotation.PostConstruct; @@ -11,14 +11,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Component; import java.io.IOException; import java.net.UnknownHostException; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; import java.util.Map; @Component diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index bb706b2..85da286 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -24,8 +24,6 @@ org: enabled: true backend: - servers_file: ${SERVERS_FILE} - geoip_file: ${GEOIP_FILE} updates: unique_global: ${UNIQUE_GLOBAL} unique_server: ${UNIQUE_SERVER}