From 89b8bc52ca28d445d52747bc34ef7cbc477a80f6 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Fri, 14 Sep 2018 21:31:50 +0200 Subject: [PATCH] Make HiscoreClient call the OSRS hiscore API directly --- http-api/pom.xml | 5 + .../http/api/hiscore/HiscoreClient.java | 144 ++++++++++-------- .../api}/hiscore/HiscoreResultBuilder.java | 2 +- http-service/pom.xml | 5 - .../service/hiscore/HiscoreController.java | 7 +- .../http/service/hiscore/HiscoreService.java | 95 ++---------- .../http/service/xp/XpTrackerService.java | 4 +- .../service/hiscore/HiscoreServiceTest.java | 2 +- .../service/hiscore/HiscoreTestService.java | 13 +- 9 files changed, 111 insertions(+), 166 deletions(-) rename {http-service/src/main/java/net/runelite/http/service => http-api/src/main/java/net/runelite/http/api}/hiscore/HiscoreResultBuilder.java (98%) diff --git a/http-api/pom.xml b/http-api/pom.xml index 34c805b0ca..cf4c608c36 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -53,6 +53,11 @@ lombok provided + + org.apache.commons + commons-csv + 1.4 + junit diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java index d1d0d25113..65197775fd 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java @@ -24,51 +24,28 @@ */ package net.runelite.http.api.hiscore; -import com.google.gson.JsonParseException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import lombok.extern.slf4j.Slf4j; import net.runelite.http.api.RuneLiteAPI; import okhttp3.HttpUrl; import okhttp3.Request; import okhttp3.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +@Slf4j public class HiscoreClient { - private static final Logger logger = LoggerFactory.getLogger(HiscoreClient.class); - public HiscoreResult lookup(String username, HiscoreEndpoint endpoint) throws IOException { - HttpUrl.Builder builder = RuneLiteAPI.getApiBase().newBuilder() - .addPathSegment("hiscore") - .addPathSegment(endpoint.name().toLowerCase()) - .addQueryParameter("username", username); + return lookup(username, endpoint.getHiscoreURL()); + } - HttpUrl url = builder.build(); - - logger.debug("Built URI: {}", url); - - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) - { - if (!response.isSuccessful()) - { - logger.debug("unsuccessful lookup for {}", username); - return null; - } - - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), HiscoreResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + public HiscoreResult lookup(String username, HttpUrl endpoint) throws IOException + { + HiscoreResultBuilder resultBuilder = lookupUsername(username, endpoint); + return resultBuilder.build(); } public HiscoreResult lookup(String username) throws IOException @@ -78,39 +55,82 @@ public class HiscoreClient public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill, HiscoreEndpoint endpoint) throws IOException { - HttpUrl.Builder builder = RuneLiteAPI.getApiBase().newBuilder() - .addPathSegment("hiscore") - .addPathSegment(endpoint.name()) - .addPathSegment(skill.toString().toLowerCase()) - .addQueryParameter("username", username); + HiscoreResultBuilder resultBuilder = lookupUsername(username, endpoint.getHiscoreURL()); + HiscoreResult result = resultBuilder.build(); - HttpUrl url = builder.build(); - - logger.debug("Built URI: {}", url); - - Request request = new Request.Builder() - .url(url) - .build(); - - try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) - { - if (!response.isSuccessful()) - { - logger.debug("unsuccessful lookup for {}", username); - return null; - } - - InputStream in = response.body().byteStream(); - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), SingleHiscoreSkillResult.class); - } - catch (JsonParseException ex) - { - throw new IOException(ex); - } + Skill requested = result.getSkill(skill); + SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); + skillResult.setPlayer(username); + skillResult.setSkillName(skill.getName()); + skillResult.setSkill(requested); + return skillResult; } public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException { return lookup(username, skill, HiscoreEndpoint.NORMAL); } + + private HiscoreResultBuilder lookupUsername(String username, HttpUrl hiscoreUrl) throws IOException + { + HttpUrl url = hiscoreUrl.newBuilder() + .addQueryParameter("player", username) + .build(); + + log.debug("Built URL {}", url); + + Request okrequest = new Request.Builder() + .url(url) + .build(); + + String responseStr; + + try (Response okresponse = RuneLiteAPI.CLIENT.newCall(okrequest).execute()) + { + if (!okresponse.isSuccessful()) + { + switch (okresponse.code()) + { + case 404: + throw new IllegalArgumentException(); + default: + throw new IOException("Error retrieving data from Jagex Hiscores: " + okresponse.message()); + } + } + + responseStr = okresponse.body().string(); + } + + CSVParser parser = CSVParser.parse(responseStr, CSVFormat.DEFAULT); + + HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder(); + hiscoreBuilder.setPlayer(username); + + int count = 0; + + for (CSVRecord record : parser.getRecords()) + { + if (count++ >= HiscoreSkill.values().length) + { + log.warn("Jagex Hiscore API returned unexpected data"); + break; // rest is other things? + } + + // rank, level, experience + int rank = Integer.parseInt(record.get(0)); + int level = Integer.parseInt(record.get(1)); + + // items that are not skills do not have an experience parameter + long experience = -1; + if (record.size() == 3) + { + experience = Long.parseLong(record.get(2)); + } + + Skill skill = new Skill(rank, level, experience); + hiscoreBuilder.setNextSkill(skill); + } + + return hiscoreBuilder; + } } diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java similarity index 98% rename from http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java rename to http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java index cefe39b471..3b25da419b 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreResultBuilder.java @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package net.runelite.http.service.hiscore; +package net.runelite.http.api.hiscore; import java.util.ArrayList; import java.util.List; diff --git a/http-service/pom.xml b/http-service/pom.xml index cdf12a27b6..84e5c48b9f 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -83,11 +83,6 @@ sql2o 1.5.4 - - org.apache.commons - commons-csv - 1.4 - com.google.guava guava diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java index 203c72daeb..d144b7db79 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java +++ b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreController.java @@ -53,8 +53,7 @@ public class HiscoreController @RequestMapping("/{endpoint}") public HiscoreResult lookup(@PathVariable HiscoreEndpoint endpoint, @RequestParam String username) throws ExecutionException { - HiscoreResultBuilder resultBuilder = hiscoreService.lookupUsername(username, endpoint); - HiscoreResult result = resultBuilder.build(); + HiscoreResult result = hiscoreService.lookupUsername(username, endpoint); // Submit to xp tracker? switch (endpoint) @@ -75,10 +74,10 @@ public class HiscoreController HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase()); // RS api only supports looking up all stats - HiscoreResultBuilder result = hiscoreService.lookupUsername(username, endpoint); + HiscoreResult result = hiscoreService.lookupUsername(username, endpoint); // Find the skill to return - Skill requested = result.getSkill(skill.ordinal()); + Skill requested = result.getSkill(skill); SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); skillResult.setPlayer(username); diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java index 8487e1ad38..d212c142bb 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java +++ b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java @@ -24,6 +24,7 @@ */ package net.runelite.http.service.hiscore; +import com.google.common.annotations.VisibleForTesting; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -31,104 +32,38 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; +import net.runelite.http.api.hiscore.HiscoreClient; import net.runelite.http.api.hiscore.HiscoreEndpoint; -import net.runelite.http.api.hiscore.HiscoreSkill; -import net.runelite.http.api.hiscore.Skill; -import net.runelite.http.service.util.exception.InternalServerErrorException; -import net.runelite.http.service.util.exception.NotFoundException; +import net.runelite.http.api.hiscore.HiscoreResult; import okhttp3.HttpUrl; -import okhttp3.Request; -import okhttp3.Response; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVRecord; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @Service @Slf4j public class HiscoreService { - private final LoadingCache hiscoreCache = CacheBuilder.newBuilder() + private final HiscoreClient hiscoreClient = new HiscoreClient(); + private final LoadingCache hiscoreCache = CacheBuilder.newBuilder() .maximumSize(128) .expireAfterWrite(1, TimeUnit.MINUTES) .build( - new CacheLoader() + new CacheLoader() { @Override - public HiscoreResultBuilder load(HiscoreKey key) throws IOException + public HiscoreResult load(HiscoreKey key) throws IOException { - return lookupUsername(key.getUsername(), key.getEndpoint().getHiscoreURL()); + return hiscoreClient.lookup(key.getUsername(), key.getEndpoint()); } }); - public HiscoreResultBuilder lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException + @VisibleForTesting + HiscoreResult lookupUsername(String username, HttpUrl httpUrl) throws IOException + { + return hiscoreClient.lookup(username, httpUrl); + } + + public HiscoreResult lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException { return hiscoreCache.get(new HiscoreKey(username, endpoint)); } - - HiscoreResultBuilder lookupUsername(String username, HttpUrl hiscoreUrl) throws IOException - { - HttpUrl url = hiscoreUrl.newBuilder() - .addQueryParameter("player", username) - .build(); - - log.debug("Built URL {}", url); - - Request okrequest = new Request.Builder() - .url(url) - .build(); - - String responseStr; - - try (Response okresponse = RuneLiteAPI.CLIENT.newCall(okrequest).execute()) - { - if (!okresponse.isSuccessful()) - { - switch (HttpStatus.valueOf(okresponse.code())) - { - case NOT_FOUND: - throw new NotFoundException(); - default: - throw new InternalServerErrorException("Error retrieving data from Jagex Hiscores: " + okresponse.message()); - } - } - - responseStr = okresponse.body().string(); - } - - CSVParser parser = CSVParser.parse(responseStr, CSVFormat.DEFAULT); - - HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder(); - hiscoreBuilder.setPlayer(username); - - int count = 0; - - for (CSVRecord record : parser.getRecords()) - { - if (count++ >= HiscoreSkill.values().length) - { - log.warn("Jagex Hiscore API returned unexpected data"); - break; // rest is other things? - } - - // rank, level, experience - int rank = Integer.parseInt(record.get(0)); - int level = Integer.parseInt(record.get(1)); - - // items that are not skills do not have an experience parameter - long experience = -1; - if (record.size() == 3) - { - experience = Long.parseLong(record.get(2)); - } - - Skill skill = new Skill(rank, level, experience); - hiscoreBuilder.setNextSkill(skill); - } - - return hiscoreBuilder; - } - } diff --git a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java index 7e6fe4271a..6fe3ce4bc2 100644 --- a/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java +++ b/http-service/src/main/java/net/runelite/http/service/xp/XpTrackerService.java @@ -30,7 +30,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.http.api.hiscore.HiscoreEndpoint; import net.runelite.http.api.hiscore.HiscoreResult; import net.runelite.http.api.xp.XpData; -import net.runelite.http.service.hiscore.HiscoreResultBuilder; import net.runelite.http.service.hiscore.HiscoreService; import net.runelite.http.service.xp.beans.PlayerEntity; import net.runelite.http.service.xp.beans.XpEntity; @@ -53,8 +52,7 @@ public class XpTrackerService public void update(String username) throws ExecutionException { - HiscoreResultBuilder hiscoreResultBuilder = hiscoreService.lookupUsername(username, HiscoreEndpoint.NORMAL); - HiscoreResult hiscoreResult = hiscoreResultBuilder.build(); + HiscoreResult hiscoreResult = hiscoreService.lookupUsername(username, HiscoreEndpoint.NORMAL); update(username, hiscoreResult); } diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java index 152707a5ca..a9b127c6d4 100644 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java +++ b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java @@ -91,7 +91,7 @@ public class HiscoreServiceTest { HiscoreTestService hiscores = new HiscoreTestService(server.url("/")); - HiscoreResult result = hiscores.lookupUsername("zezima", HiscoreEndpoint.NORMAL).build(); + HiscoreResult result = hiscores.lookupUsername("zezima", HiscoreEndpoint.NORMAL.getHiscoreURL()); Assert.assertEquals(50, result.getAttack().getLevel()); Assert.assertEquals(159727L, result.getFishing().getExperience()); diff --git a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java index c5a35964d0..654d0792ee 100644 --- a/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java +++ b/http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreTestService.java @@ -27,7 +27,7 @@ package net.runelite.http.service.hiscore; import java.io.IOException; import java.util.concurrent.ExecutionException; -import net.runelite.http.api.hiscore.HiscoreEndpoint; +import net.runelite.http.api.hiscore.HiscoreResult; import okhttp3.HttpUrl; class HiscoreTestService extends HiscoreService @@ -40,15 +40,8 @@ class HiscoreTestService extends HiscoreService } @Override - public HiscoreResultBuilder lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException + public HiscoreResult lookupUsername(String username, HttpUrl endpoint) throws IOException { - try - { - return super.lookupUsername(username, testUrl); - } - catch (IOException e) - { - throw new ExecutionException(e); - } + return super.lookupUsername(username, testUrl); } }