From b4e0e7fe6ad545063be4784166511f675d70b2db Mon Sep 17 00:00:00 2001 From: Tisawesomeness Date: Tue, 13 Sep 2022 10:07:30 -0400 Subject: [PATCH] Well then --- .../namehistorian/MojangLookup.java | 18 --- .../namehistorian/MojangLookupImpl.java | 46 -------- .../namehistorian/NameHistorian.java | 66 +---------- .../namehistorian/MojangLookupTest.java | 39 ------- .../namehistorian/NameHistorianTest.java | 104 +----------------- .../testutil/MojangLookupMock.java | 41 ------- 6 files changed, 5 insertions(+), 309 deletions(-) delete mode 100644 nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookup.java delete mode 100644 nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookupImpl.java delete mode 100644 nh-core/src/test/java/com/tisawesomeness/namehistorian/MojangLookupTest.java delete mode 100644 nh-core/src/test/java/com/tisawesomeness/namehistorian/testutil/MojangLookupMock.java diff --git a/nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookup.java b/nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookup.java deleted file mode 100644 index 8394a55..0000000 --- a/nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookup.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.tisawesomeness.namehistorian; - -import java.io.IOException; -import java.util.*; - -public interface MojangLookup { - - /** - * Fetches the list of name changes from the Mojang API. This method will block until the request is complete. - * BEWARE: this may error or return empty when Mojang disables the API endpoint on September 13th! - * - * @param uuid The UUID of the player - * @return A list of name changes, oldest to newest, or empty if the UUID could not be found - * @throws IOException If an I/O error occurs or the API returns something other than 200 or 204 - */ - List fetchNameChanges(UUID uuid) throws IOException; - -} diff --git a/nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookupImpl.java b/nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookupImpl.java deleted file mode 100644 index c26bc87..0000000 --- a/nh-core/src/main/java/com/tisawesomeness/namehistorian/MojangLookupImpl.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.tisawesomeness.namehistorian; - -import com.google.gson.Gson; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.*; - -public final class MojangLookupImpl implements MojangLookup { - - private static final int CONNECT_TIMEOUT = 5000; - private static final int READ_TIMEOUT = 5000; - private static final Gson GSON = new Gson(); - - @Override - public List fetchNameChanges(UUID uuid) throws IOException { - URL url = new URL("https://api.mojang.com/user/profiles/" + uuid + "/names"); - Optional isrOpt = MojangLookupImpl.get(url); - if (!isrOpt.isPresent()) { - return Collections.emptyList(); - } - try (InputStreamReader isr = isrOpt.get()) { - return Arrays.asList(MojangLookupImpl.GSON.fromJson(isr, NameChange[].class)); - } - } - - private static Optional get(URL url) throws IOException { - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - con.setConnectTimeout(CONNECT_TIMEOUT); - con.setReadTimeout(READ_TIMEOUT); - con.setInstanceFollowRedirects(false); - con.connect(); - int responseCode = con.getResponseCode(); - if (responseCode == 200) { - return Optional.of(new InputStreamReader(con.getInputStream())); - } else if (responseCode == 204) { - return Optional.empty(); - } else { - throw new IOException("HTTP " + responseCode); - } - } - -} diff --git a/nh-core/src/main/java/com/tisawesomeness/namehistorian/NameHistorian.java b/nh-core/src/main/java/com/tisawesomeness/namehistorian/NameHistorian.java index ed1cdc7..6ba2c97 100644 --- a/nh-core/src/main/java/com/tisawesomeness/namehistorian/NameHistorian.java +++ b/nh-core/src/main/java/com/tisawesomeness/namehistorian/NameHistorian.java @@ -6,11 +6,13 @@ import javax.annotation.Nullable; import javax.sql.DataSource; -import java.io.IOException; import java.nio.file.Path; import java.sql.*; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; public final class NameHistorian { @@ -42,12 +44,8 @@ public final class NameHistorian { " `detected_time`,\n" + " `last_seen_time`\n" + ") VALUES (?, ?, ?, ?, ?);"; - private static final String DELETE_ALL_HISTORY_SQL = "" + - "DELETE FROM `name_history`\n" + - "WHERE `uuid` = ?;"; private final DataSource source; - private final MojangLookup lookup; /** * Initializes NameHistorian by connecting to a SQLite database. @@ -58,9 +56,6 @@ public final class NameHistorian { * @throws IllegalStateException if the database is not at the correct version */ public NameHistorian(Path databasePath) throws SQLException { - this(databasePath, new MojangLookupImpl()); - } - NameHistorian(Path databasePath, MojangLookup lookup) throws SQLException { SQLiteDataSource ds = new SQLiteConnectionPoolDataSource(); ds.setUrl("jdbc:sqlite:" + databasePath.toFile().getAbsolutePath()); source = ds; @@ -69,8 +64,6 @@ public NameHistorian(Path databasePath) throws SQLException { if (getVersion() != VERSION) { throw new IllegalStateException("Database version is not " + VERSION); } - - this.lookup = lookup; } private int getVersion() throws SQLException { @@ -180,9 +173,6 @@ private void recordNewName(Connection con, NameRecord nr) throws SQLException { */ public List getNameHistory(UUID uuid) throws SQLException { @Cleanup Connection con = source.getConnection(); - return retrieveNameHistory(con, uuid); - } - private List retrieveNameHistory(Connection con, UUID uuid) throws SQLException { @Cleanup PreparedStatement st = con.prepareStatement(READ_ALL_HISTORY_SQL); st.setString(1, uuid.toString()); @Cleanup ResultSet rs = st.executeQuery(); @@ -193,54 +183,6 @@ private List retrieveNameHistory(Connection con, UUID uuid) throws S return list; } - /** - * Requests the player's name history from the Mojang API and saves it to the database. - * This will overwrite the player's existing name history. - * BEWARE: this may error when Mojang disables the API endpoint on September 13th! - * @param uuid The UUID of the player to look up - * @return True on success, false if history cannot be looked up - * @throws IOException see {@link MojangLookup#fetchNameChanges(UUID)} - * @throws SQLException on database error - */ - public boolean saveMojangHistory(UUID uuid) throws IOException, SQLException { - List history = lookup.fetchNameChanges(uuid); - if (history.isEmpty()) { - return false; - } - List records = new ArrayList<>(); - Instant now = Instant.now(); - - for (int i = 0; i < history.size(); i++) { - NameChange change = history.get(i); - - NameChange next = i + 1 < history.size() ? history.get(i + 1) : null; - Instant firstSeen; - if (!change.isOriginal()) { - firstSeen = change.getChangeTime(); - } else if (next != null) { - firstSeen = next.getChangeTime(); - } else { - firstSeen = now; - } - Instant lastSeen = next != null ? next.getChangeTime() : now; - - records.add(new NameRecord(uuid, change.getName(), firstSeen, now, lastSeen)); - } - - asTransaction(con -> { - deleteHistory(con, uuid); - for (NameRecord nr : records) { - recordNewName(con, nr); - } - }); - return true; - } - private void deleteHistory(Connection con, UUID uuid) throws SQLException { - @Cleanup PreparedStatement st = con.prepareStatement(DELETE_ALL_HISTORY_SQL); - st.setString(1, uuid.toString()); - st.executeUpdate(); - } - private NameDBRecord readDBRecord(ResultSet rs, UUID uuid) throws SQLException { return new NameDBRecord( rs.getInt("id"), diff --git a/nh-core/src/test/java/com/tisawesomeness/namehistorian/MojangLookupTest.java b/nh-core/src/test/java/com/tisawesomeness/namehistorian/MojangLookupTest.java deleted file mode 100644 index 3ce1ea3..0000000 --- a/nh-core/src/test/java/com/tisawesomeness/namehistorian/MojangLookupTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.tisawesomeness.namehistorian; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; - -public class MojangLookupTest { - - private static final UUID TIS_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3af"); - private static final long TIS_TIMESTAMP = 1438695830000L; - private static final UUID JEB_UUID = UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6"); - private static final UUID INVALID_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3ae"); - - @Test - @Disabled("Will break on September 13th!") - public void testFetchNameChanges() throws IOException { - assertThat(new MojangLookupImpl().fetchNameChanges(TIS_UUID)).containsExactly( - new NameChange("tis_awesomeness", 0), - new NameChange("Tis_awesomeness", TIS_TIMESTAMP) - ); - } - @Test - @Disabled("Will break on September 13th!") - public void testFetchNameChanges2() throws IOException { - assertThat(new MojangLookupImpl().fetchNameChanges(JEB_UUID)).containsExactly( - new NameChange("jeb_", 0) - ); - } - @Test - @Disabled("Will break on September 13th!") - public void testFetchNameChangesDNE() throws IOException { - assertThat(new MojangLookupImpl().fetchNameChanges(INVALID_UUID)).isEmpty(); - } - -} diff --git a/nh-core/src/test/java/com/tisawesomeness/namehistorian/NameHistorianTest.java b/nh-core/src/test/java/com/tisawesomeness/namehistorian/NameHistorianTest.java index 7b6a1d2..da2b1f0 100644 --- a/nh-core/src/test/java/com/tisawesomeness/namehistorian/NameHistorianTest.java +++ b/nh-core/src/test/java/com/tisawesomeness/namehistorian/NameHistorianTest.java @@ -1,7 +1,5 @@ package com.tisawesomeness.namehistorian; -import com.tisawesomeness.namehistorian.testutil.MojangLookupMock; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -13,20 +11,14 @@ import java.time.Duration; import java.time.Instant; import java.util.Arrays; -import java.util.List; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; public class NameHistorianTest { private static final UUID TIS_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3af"); - private static final Instant TIS_TIME = Instant.ofEpochMilli(1438695830000L); private static final UUID JEB_UUID = UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6"); - private static final UUID DUMMY_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3a0"); - private static final UUID INVALID_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3ae"); - private static final UUID THROWING_UUID = UUID.fromString("e6489b79-7a9f-49e2-980e-265a05dbc3af"); private static final Duration GRACE_PERIOD = Duration.ofMinutes(1); private NameHistorian historian; @@ -36,7 +28,7 @@ public void setUp() throws SQLException, IOException { Files.createDirectories(parent); Path dbPath = parent.resolve("test.db"); Files.deleteIfExists(dbPath); - historian = new NameHistorian(dbPath, new MojangLookupMock()); + historian = new NameHistorian(dbPath); } @Test @@ -94,98 +86,4 @@ public void testBulkRecord() throws SQLException { .containsExactly("test2"); } - @Test - public void testSaveHistory() throws SQLException, IOException { - assertThat(historian.saveMojangHistory(TIS_UUID)).isTrue(); - - List history = historian.getNameHistory(TIS_UUID); - checkHistory(history); - } - - @Test - public void testSaveHistoryAlreadyExists() throws SQLException, IOException { - historian.recordName(TIS_UUID, "Tis_awesomeness"); - assertThat(historian.saveMojangHistory(TIS_UUID)).isTrue(); - - List history = historian.getNameHistory(TIS_UUID); - checkHistory(history); - } - - @Test - public void testSaveHistoryPreviouslyExists() throws SQLException, IOException { - NameRecord nr = new NameRecord(TIS_UUID, "tis_awesomeness", TIS_TIME.minusSeconds(10), Instant.now(), TIS_TIME.minusSeconds(5)); - historian.recordName(nr); - assertThat(historian.saveMojangHistory(TIS_UUID)).isTrue(); - - List history = historian.getNameHistory(TIS_UUID); - checkHistory(history); - } - - @Test - public void testSaveHistoryDuplicate() throws SQLException, IOException { - assertThat(historian.saveMojangHistory(TIS_UUID)).isTrue(); - assertThat(historian.saveMojangHistory(TIS_UUID)).isTrue(); - - List history = historian.getNameHistory(TIS_UUID); - checkHistory(history); - } - - private static void checkHistory(List history) { - assertThat(history).hasSize(2); - - NameRecord latest = history.get(0); - assertThat(latest) - .extracting(NameRecord::getUsername, NameRecord::getUuid, NameRecord::getFirstSeenTime) - .containsExactly("Tis_awesomeness", TIS_UUID, TIS_TIME); - assertThat(Arrays.asList(latest.getDetectedTime(), latest.getLastSeenTime())) - .allSatisfy(t -> assertThat(t).isBetween(Instant.now().minus(GRACE_PERIOD), Instant.now())); - - NameRecord original = history.get(1); - assertThat(original) - .extracting(NameRecord::getUsername, NameRecord::getUuid, NameRecord::getFirstSeenTime, NameRecord::getLastSeenTime) - .containsExactly("tis_awesomeness", TIS_UUID, NameHistorianTest.TIS_TIME, TIS_TIME); - assertThat(original.getDetectedTime()) - .isBetween(Instant.now().minus(GRACE_PERIOD), Instant.now()); - } - - @Test - public void testSaveHistory1() throws IOException, SQLException { - assertThat(historian.saveMojangHistory(JEB_UUID)).isTrue(); - List history = historian.getNameHistory(JEB_UUID); - - assertThat(history).hasSize(1); - - NameRecord original = history.get(0); - assertThat(original) - .extracting(NameRecord::getUsername, NameRecord::getUuid) - .containsExactly("jeb_", JEB_UUID); - assertThat(Arrays.asList(original.getFirstSeenTime(), original.getDetectedTime(), original.getLastSeenTime())) - .allSatisfy(t -> assertThat(t).isBetween(Instant.now().minus(GRACE_PERIOD), Instant.now())); - } - - @Test - public void testSaveHistory2() throws IOException, SQLException { - assertThat(historian.saveMojangHistory(DUMMY_UUID)).isTrue(); - List history = historian.getNameHistory(DUMMY_UUID); - - assertThat(history).hasSize(3); - - NameRecord middle = history.get(1); - assertThat(middle) - .extracting(NameRecord::getUsername, NameRecord::getUuid, NameRecord::getFirstSeenTime, NameRecord::getLastSeenTime) - .containsExactly("dummy2", DUMMY_UUID, TIS_TIME.plusSeconds(1), TIS_TIME.plusSeconds(2)); - assertThat(middle.getDetectedTime()) - .isBetween(Instant.now().minus(GRACE_PERIOD), Instant.now()); - } - - @Test - public void testSaveHistoryInvalid() throws SQLException, IOException { - assertThat(historian.saveMojangHistory(INVALID_UUID)).isFalse(); - } - @Test - public void testSaveHistoryIOE() { - assertThatThrownBy(() -> historian.saveMojangHistory(THROWING_UUID)) - .isInstanceOf(IOException.class); - } - } diff --git a/nh-core/src/test/java/com/tisawesomeness/namehistorian/testutil/MojangLookupMock.java b/nh-core/src/test/java/com/tisawesomeness/namehistorian/testutil/MojangLookupMock.java deleted file mode 100644 index 98df29c..0000000 --- a/nh-core/src/test/java/com/tisawesomeness/namehistorian/testutil/MojangLookupMock.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.tisawesomeness.namehistorian.testutil; - -import com.tisawesomeness.namehistorian.MojangLookup; -import com.tisawesomeness.namehistorian.NameChange; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -public class MojangLookupMock implements MojangLookup { - - private static final UUID TIS_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3af"); - private static final long TIS_TIMESTAMP = 1438695830000L; - private static final UUID JEB_UUID = UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6"); - private static final UUID DUMMY_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3a0"); - private static final UUID INVALID_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3ae"); - - @Override - public List fetchNameChanges(UUID uuid) throws IOException { - if (uuid.equals(TIS_UUID)) { - return Arrays.asList( - new NameChange("tis_awesomeness", 0), - new NameChange("Tis_awesomeness", TIS_TIMESTAMP) - ); - } else if (uuid.equals(JEB_UUID)) { - return Collections.singletonList(new NameChange("jeb_", 0)); - } else if (uuid.equals(DUMMY_UUID)) { - return Arrays.asList( - new NameChange("dummy", TIS_TIMESTAMP), - new NameChange("dummy2", TIS_TIMESTAMP + 1000), - new NameChange("dummy3", TIS_TIMESTAMP + 2000) - ); - } else if (uuid.equals(INVALID_UUID)) { - return Collections.emptyList(); - } - throw new IOException("Unexpected UUID: " + uuid); - } - -}