diff --git a/src/main/java/ru/r2cloud/cloud/LeoSatDataClient.java b/src/main/java/ru/r2cloud/cloud/LeoSatDataClient.java index cd08a05f..8e8d29c7 100644 --- a/src/main/java/ru/r2cloud/cloud/LeoSatDataClient.java +++ b/src/main/java/ru/r2cloud/cloud/LeoSatDataClient.java @@ -332,6 +332,7 @@ private Tle readTle(JsonValue tle) { Tle result = new Tle(new String[] { line1, line2, line3 }); // assume downloaded TLE is always fresh result.setLastUpdateTime(clock.millis()); + result.setSource(hostname); return result; } diff --git a/src/main/java/ru/r2cloud/cloud/SatnogsClient.java b/src/main/java/ru/r2cloud/cloud/SatnogsClient.java index 60a52f1a..3629e800 100644 --- a/src/main/java/ru/r2cloud/cloud/SatnogsClient.java +++ b/src/main/java/ru/r2cloud/cloud/SatnogsClient.java @@ -160,6 +160,7 @@ private Tle readTle(String body) { // if satellite is new launch, then there is no other source for tle // readTle is called only for new launches result.setLastUpdateTime(clock.millis()); + result.setSource(hostname); return result; } diff --git a/src/main/java/ru/r2cloud/model/Tle.java b/src/main/java/ru/r2cloud/model/Tle.java index 1bcff5fe..4e7b3184 100644 --- a/src/main/java/ru/r2cloud/model/Tle.java +++ b/src/main/java/ru/r2cloud/model/Tle.java @@ -8,6 +8,7 @@ public class Tle { private final String[] raw; private long lastUpdateTime; + private String source; public Tle(String[] tle) { this.raw = tle; @@ -16,15 +17,23 @@ public Tle(String[] tle) { public String[] getRaw() { return raw; } - + public void setLastUpdateTime(long lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; } - + public long getLastUpdateTime() { return lastUpdateTime; } + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + @Override public int hashCode() { final int prime = 31; @@ -56,6 +65,10 @@ public JsonObject toJson() { if (raw.length > 2) { json.add("line3", raw[2]); } + json.add("updated", lastUpdateTime); + if (source != null) { + json.add("source", source); + } return json; } @@ -64,7 +77,10 @@ public static Tle fromJson(JsonObject json) { raw[0] = json.getString("line1", null); raw[1] = json.getString("line2", null); raw[2] = json.getString("line3", null); - return new Tle(raw); + Tle result = new Tle(raw); + result.setLastUpdateTime(json.getLong("updated", 0)); + result.setSource(json.getString("source", null)); + return result; } } diff --git a/src/main/java/ru/r2cloud/tle/CelestrakClient.java b/src/main/java/ru/r2cloud/tle/CelestrakClient.java index 8a4e9092..9d4c5e8a 100644 --- a/src/main/java/ru/r2cloud/tle/CelestrakClient.java +++ b/src/main/java/ru/r2cloud/tle/CelestrakClient.java @@ -65,7 +65,10 @@ private Map<String, Tle> downloadTle(String location) { break; } String noradId = line2.substring(2, 2 + 5).trim(); - result.put(noradId, new Tle(new String[] { curLine.trim(), line1, line2 })); + Tle value = new Tle(new String[] { curLine.trim(), line1, line2 }); + value.setLastUpdateTime(System.currentTimeMillis()); + value.setSource(obj.getHost()); + result.put(noradId, value); } } } diff --git a/src/main/java/ru/r2cloud/tle/TleDao.java b/src/main/java/ru/r2cloud/tle/TleDao.java index 522d4e54..d603598c 100644 --- a/src/main/java/ru/r2cloud/tle/TleDao.java +++ b/src/main/java/ru/r2cloud/tle/TleDao.java @@ -13,6 +13,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.eclipsesource.json.Json; +import com.eclipsesource.json.JsonArray; + import ru.r2cloud.model.Tle; import ru.r2cloud.util.Configuration; import ru.r2cloud.util.Util; @@ -63,7 +66,7 @@ private void index(Map<String, Tle> tleById) { cacheByName.clear(); putAll(tleById); } - + public void putAll(Map<String, Tle> tleById) { cache.putAll(tleById); for (Tle cur : tleById.values()) { @@ -82,17 +85,14 @@ public long getLastUpdateTime() { } private static void saveTle(Path file, Map<String, Tle> tle) { + JsonArray output = new JsonArray(); + for (Tle cur : tle.values()) { + output.add(cur.toJson()); + } // ensure temp and output are on the same filestore - Path tempOutput = file.getParent().resolve("tle.txt.tmp"); + Path tempOutput = file.getParent().resolve("tle.json.tmp"); try (BufferedWriter w = Files.newBufferedWriter(tempOutput)) { - for (Tle cur : tle.values()) { - w.append(cur.getRaw()[0]); - w.newLine(); - w.append(cur.getRaw()[1]); - w.newLine(); - w.append(cur.getRaw()[2]); - w.newLine(); - } + output.writeTo(w); } catch (IOException e) { Util.logIOException(LOG, "unable to save tle: " + file.toAbsolutePath(), e); return; @@ -110,23 +110,20 @@ private static Map<String, Tle> loadTle(Path file) { if (!Files.exists(file)) { return result; } + JsonArray output = null; try (BufferedReader in = Files.newBufferedReader(file)) { - // only first line matters - String curLine = null; - while ((curLine = in.readLine()) != null) { - String line1 = in.readLine(); - if (line1 == null) { - break; - } - String line2 = in.readLine(); - if (line2 == null) { - break; - } - String noradId = line2.substring(2, 2 + 5).trim(); - result.put(noradId, new Tle(new String[] { curLine.trim(), line1, line2 })); - } + output = Json.parse(in).asArray(); } catch (IOException e) { Util.logIOException(LOG, "unable to load tle from cache: " + file.toAbsolutePath(), e); + return result; + } + for (int i = 0; i < output.size(); i++) { + Tle cur = Tle.fromJson(output.get(i).asObject()); + if (cur == null) { + continue; + } + String noradId = cur.getRaw()[cur.getRaw().length - 1].substring(2, 2 + 5).trim(); + result.put(noradId, cur); } return result; } diff --git a/src/main/resources/config-common.properties b/src/main/resources/config-common.properties index e068d3cb..374ab20b 100644 --- a/src/main/resources/config-common.properties +++ b/src/main/resources/config-common.properties @@ -8,7 +8,7 @@ ddns.interval.seconds=300 #1 - Monday, 7 - Sunday tle.urls=http://r4uab.ru/satonline.txt,https://celestrak.org/NORAD/elements/gp.php?GROUP=satnogs&FORMAT=tle,https://celestrak.org/NORAD/elements/gp.php?GROUP=active&FORMAT=tle tle.timeout=60000 -tle.cacheFileLocation=./data/tle.txt +tle.cacheFileLocation=./data/tle.json housekeeping.periodMillis=3600000 housekeeping.tle.periodMillis=172800000 diff --git a/src/test/java/ru/r2cloud/tle/HousekeepingTest.java b/src/test/java/ru/r2cloud/tle/HousekeepingTest.java index c384915b..b98af4fc 100644 --- a/src/test/java/ru/r2cloud/tle/HousekeepingTest.java +++ b/src/test/java/ru/r2cloud/tle/HousekeepingTest.java @@ -130,7 +130,7 @@ public void start() throws Exception { } config = new TestConfiguration(tempFolder, FileSystems.getDefault()); - config.setProperty("tle.cacheFileLocation", new File(tempFolder.getRoot(), "tle.txt").getAbsolutePath()); + config.setProperty("tle.cacheFileLocation", new File(tempFolder.getRoot(), "tle.json").getAbsolutePath()); config.setProperty("satellites.leosatdata.location", new File(tempFolder.getRoot(), "leosatdata.json").getAbsolutePath()); config.setProperty("satellites.leosatdata.new.location", new File(tempFolder.getRoot(), "leosatdata.new.json").getAbsolutePath()); config.setProperty("satellites.satnogs.location", new File(tempFolder.getRoot(), "satnogs.json").getAbsolutePath()); diff --git a/src/test/java/ru/r2cloud/tle/TleDaoTest.java b/src/test/java/ru/r2cloud/tle/TleDaoTest.java index b318430a..bbb7b2eb 100644 --- a/src/test/java/ru/r2cloud/tle/TleDaoTest.java +++ b/src/test/java/ru/r2cloud/tle/TleDaoTest.java @@ -69,7 +69,7 @@ public void testSaveLoadAndFail() { public void start() throws Exception { fs = new MockFileSystem(FileSystems.getDefault()); config = new TestConfiguration(tempFolder, fs); - fileLocation = new File(tempFolder.getRoot(), "tle.txt").getAbsolutePath(); + fileLocation = new File(tempFolder.getRoot(), "tle.json").getAbsolutePath(); config.setProperty("tle.cacheFileLocation", fileLocation); dao = new TleDao(config); }