diff --git a/http-service/pom.xml b/http-service/pom.xml index 6a91b4fb64..74012999c9 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -36,60 +36,39 @@ war - 9.3.6.v20151106 + 1.5.6.RELEASE + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring.boot.version} + provided + + + org.springframework.boot + spring-boot-devtools + ${spring.boot.version} + true + + net.runelite http-api ${project.version} - - javax.servlet - javax.servlet-api - 3.1.0 - provided - - - javax.websocket - javax.websocket-api - 1.1 - provided - - - - com.sparkjava - spark-core - 2.5.5 - - - - org.eclipse.jetty - jetty-server - - - org.eclipse.jetty - jetty-webapp - - - org.eclipse.jetty.websocket - websocket-server - - - org.eclipse.jetty.websocket - websocket-servlet - - - org.sql2o sql2o 1.5.4 - org.apache.commons commons-csv @@ -100,30 +79,23 @@ guava 21.0 - - com.google.inject - guice - 4.1.0 - - org.slf4j slf4j-api 1.7.12 - - com.commongroundpublishing - slf4j-servletcontext - 1.0.0 - runtime - - com.github.scribejava scribejava-apis 4.1.0 + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + junit junit @@ -136,43 +108,10 @@ 1.10.19 test - - - org.eclipse.jetty - jetty-server - ${jetty.version} - test - - - org.eclipse.jetty - jetty-webapp - ${jetty.version} - test - - - org.eclipse.jetty.websocket - websocket-server - ${jetty.version} - test - - - org.eclipse.jetty.websocket - websocket-servlet - ${jetty.version} - test - - - - com.google.inject.extensions - guice-testlib - 4.1.0 - test - - - org.slf4j - slf4j-simple - 1.7.12 + mysql + mysql-connector-java + 5.1.43 test @@ -187,6 +126,11 @@ runelite-${project.version} + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + org.apache.tomcat.maven tomcat7-maven-plugin diff --git a/http-service/src/main/java/net/runelite/http/service/Service.java b/http-service/src/main/java/net/runelite/http/service/Service.java deleted file mode 100644 index 2a024b0a8f..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/Service.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (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; - -import com.google.inject.Guice; -import com.google.inject.Inject; -import net.runelite.http.api.RuneliteAPI; -import net.runelite.http.service.account.AccountService; -import net.runelite.http.service.account.AuthFilter; -import net.runelite.http.service.config.ConfigService; -import net.runelite.http.service.examine.ExamineService; -import net.runelite.http.service.hiscore.HiscoreService; -import net.runelite.http.service.item.ItemService; -import net.runelite.http.service.updatecheck.UpdateCheckService; -import net.runelite.http.service.worlds.WorldsService; -import net.runelite.http.service.xtea.XteaService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import spark.Request; -import spark.Response; -import spark.servlet.SparkApplication; -import static spark.Spark.*; - -public class Service implements SparkApplication -{ - private static final Logger logger = LoggerFactory.getLogger(Service.class); - - private final JsonTransformer transformer = new JsonTransformer(); - - @Inject - private AuthFilter authFilter; - - @Inject - private AccountService accounts; - - @Inject - private ConfigService config; - - @Inject - private ExamineService examine; - - @Inject - private HiscoreService hiscores; - - @Inject - private ItemService item; - - @Inject - private UpdateCheckService updateCheck; - - @Inject - private WorldsService worlds; - - @Inject - private XteaService xtea; - - @Override - public void init() - { - Guice.createInjector(new ServiceModule(this)); - setupRoutes(); - } - - public void setupRoutes() - { - xtea.init(); - accounts.init(); - config.init(); - item.init(); - examine.init(); - - get("/version", (request, response) -> RuneliteAPI.getVersion()); - get("/update-check", updateCheck::check, transformer); - path("/hiscore", () -> - { - get("", hiscores::lookup, transformer); - get("/:skill", hiscores::singleSkillLookup, transformer); - }); - get("/worlds", worlds::listWorlds, transformer); - post("/xtea", xtea::submit); - get("/xtea/:rev", xtea::get, transformer); - path("/account", () -> - { - get("/login", accounts::login, transformer); - get("/callback", accounts::callback); - - before("/logout", authFilter); - get("/logout", accounts::logout); - - before("/session-check", authFilter); - get("/session-check", accounts::sessionCheck); - }); - before("/config", authFilter); - path("/config", () -> - { - // Just using before(authFilter); here doesn't work - before("/*", authFilter); - - get("", config::get, transformer); - put("/:key", config::setKey); - delete("/:key", config::unsetKey); - }); - path("/item", () -> - { - get("/search", item::search, transformer); - - get("/:id", item::getItem, transformer); - get("/:id/icon", item::getIcon); - get("/:id/icon/large", item::getIconLarge); - get("/:id/price", item::getPrice, transformer); - get("/:id/price/:time", item::getPrice, transformer); - }); - path("/examine", () -> - { - get("/npc/:id", examine::getNpc); - get("/object/:id", examine::getObject); - get("/item/:id", examine::getItem); - - post("/npc/:id", examine::submitNpc); - post("/object/:id", examine::submitObject); - post("/item/:id", examine::submitItem); - }); - - exception(Exception.class, this::handleException); - } - - private void handleException(Exception ex, Request request, Response response) - { - logger.warn("error processing request", ex); - response.status(500); - } - -} diff --git a/http-service/src/main/java/net/runelite/http/service/SparkServlet.java b/http-service/src/main/java/net/runelite/http/service/SparkServlet.java deleted file mode 100644 index dfebee11ca..0000000000 --- a/http-service/src/main/java/net/runelite/http/service/SparkServlet.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (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; - -import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import spark.globalstate.ServletFlag; -import spark.http.matching.MatcherFilter; -import spark.route.ServletRoutes; -import spark.servlet.SparkApplication; -import spark.staticfiles.StaticFilesConfiguration; - -public class SparkServlet extends HttpServlet -{ - private final SparkApplication service = new Service(); - - private final MatcherFilter matcherFilter; - - public SparkServlet() - { - ServletFlag.runFromServlet(); - - service.init(); - - matcherFilter = new MatcherFilter(ServletRoutes.get(), StaticFilesConfiguration.servletInstance, true, false); - } - - private void run(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - final String relativePath = req.getPathInfo(); - - HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(req) - { - @Override - public String getPathInfo() - { - return relativePath; - } - - @Override - public String getRequestURI() - { - return relativePath; - } - - }; - - FilterChain chain = (req2, resp2) -> - { - // Called if the matcherFilter ends up not setting a body - // something might have changed changed the error from 200 - if (resp.getStatus() == 200) - { - resp.setStatus(404); - } - }; - - matcherFilter.doFilter(requestWrapper, resp, chain); - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - run(req, resp); - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - run(req, resp); - } - - @Override - protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - run(req, resp); - } - - @Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException - { - run(req, resp); - } -} diff --git a/http-service/src/main/java/net/runelite/http/service/ServiceModule.java b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java similarity index 51% rename from http-service/src/main/java/net/runelite/http/service/ServiceModule.java rename to http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java index b7589027a0..1522aa2fd1 100644 --- a/http-service/src/main/java/net/runelite/http/service/ServiceModule.java +++ b/http-service/src/main/java/net/runelite/http/service/SpringBootWebApplication.java @@ -24,9 +24,6 @@ */ package net.runelite.http.service; -import com.google.inject.AbstractModule; -import com.google.inject.Provides; -import com.google.inject.name.Named; import java.time.Instant; import java.util.HashMap; import java.util.Map; @@ -34,99 +31,54 @@ import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; -import net.runelite.http.service.account.AccountService; -import net.runelite.http.service.account.AuthFilter; -import net.runelite.http.service.config.ConfigService; -import net.runelite.http.service.examine.ExamineService; -import net.runelite.http.service.hiscore.HiscoreService; -import net.runelite.http.service.item.ItemService; -import net.runelite.http.service.updatecheck.UpdateCheckService; -import net.runelite.http.service.worlds.WorldsService; -import net.runelite.http.service.xtea.XteaService; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; import org.sql2o.Sql2o; import org.sql2o.converters.Converter; import org.sql2o.quirks.NoQuirks; -public class ServiceModule extends AbstractModule +@SpringBootApplication +public class SpringBootWebApplication extends SpringBootServletInitializer { - private final Service service; - - public ServiceModule(Service service) - { - this.service = service; - } - private Context getContext() throws NamingException { Context initCtx = new InitialContext(); return (Context) initCtx.lookup("java:comp/env"); } - @Provides - @Named("Runelite JDBC") - DataSource provideDataSource() - { - try - { - return (DataSource) getContext().lookup("jdbc/runelite"); - } - catch (NamingException ex) - { - throw new RuntimeException(ex); - } - } - - @Provides - @Named("Runelite SQL2O") - Sql2o provideSql2o(@Named("Runelite JDBC") DataSource datasource) + @Bean("Runelite SQL2O") + Sql2o sql2o() throws NamingException { + DataSource dataSource = (DataSource) getContext().lookup("jdbc/runelite"); Map converters = new HashMap<>(); converters.put(Instant.class, new InstantConverter()); - return new Sql2o(datasource, new NoQuirks(converters)); + return new Sql2o(dataSource, new NoQuirks(converters)); + } - @Provides - @Named("OAuth Client ID") - String provideOAuthClientID() + @Bean("OAuth Client ID") + String oauthClientId() throws NamingException { - try - { - return (String) getContext().lookup("runelite-oauth-client-id"); - } - catch (NamingException ex) - { - throw new RuntimeException(ex); - } + return (String) getContext().lookup("runelite-oauth-client-id"); } - @Provides - @Named("OAuth Client Secret") - String provideOAuthClientSecret() + @Bean("OAuth Client Secret") + String oauthClientSecret() throws NamingException { - try - { - return (String) getContext().lookup("runelite-oauth-client-secret"); - } - catch (NamingException ex) - { - throw new RuntimeException(ex); - } + return (String) getContext().lookup("runelite-oauth-client-secret"); } @Override - protected void configure() + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - bind(Service.class).toInstance(service); + return application.sources(SpringBootWebApplication.class); + } - bind(AuthFilter.class); - - bind(AccountService.class); - bind(ConfigService.class); - bind(ExamineService.class); - bind(HiscoreService.class); - bind(ItemService.class); - bind(UpdateCheckService.class); - bind(WorldsService.class); - bind(XteaService.class); + public static void main(String[] args) + { + SpringApplication.run(SpringBootWebApplication.class, args); } } diff --git a/http-service/src/main/java/net/runelite/http/service/account/AccountService.java b/http-service/src/main/java/net/runelite/http/service/account/AccountService.java index 25b3285509..b31280f599 100644 --- a/http-service/src/main/java/net/runelite/http/service/account/AccountService.java +++ b/http-service/src/main/java/net/runelite/http/service/account/AccountService.java @@ -30,14 +30,15 @@ import com.github.scribejava.apis.GoogleApi20; import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.model.OAuth2AccessToken; import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.gson.Gson; -import com.google.inject.Inject; -import com.google.inject.name.Named; import java.io.IOException; import java.util.UUID; import java.util.concurrent.ExecutionException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import net.runelite.http.api.RuneliteAPI; import net.runelite.http.api.account.OAuthResponse; import net.runelite.http.api.ws.messages.LoginResponse; @@ -46,12 +47,17 @@ import net.runelite.http.service.ws.WSService; import net.runelite.http.service.ws.WSSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import org.sql2o.Connection; import org.sql2o.Sql2o; import org.sql2o.Sql2oException; -import spark.Request; -import spark.Response; +@RestController +@RequestMapping("/account") public class AccountService { private static final Logger logger = LoggerFactory.getLogger(AccountService.class); @@ -86,21 +92,21 @@ public class AccountService private final Sql2o sql2o; private final String oauthClientId; private final String oauthClientSecret; + private final AuthFilter auth; - @Inject + @Autowired public AccountService( - @Named("Runelite SQL2O") Sql2o sql2o, - @Named("OAuth Client ID") String oauthClientId, - @Named("OAuth Client Secret") String oauthClientSecret + @Qualifier("Runelite SQL2O") Sql2o sql2o, + @Qualifier("OAuth Client ID") String oauthClientId, + @Qualifier("OAuth Client Secret") String oauthClientSecret, + AuthFilter auth ) { this.sql2o = sql2o; this.oauthClientId = oauthClientId; this.oauthClientSecret = oauthClientSecret; - } + this.auth = auth; - public void init() - { try (Connection con = sql2o.open()) { con.createQuery(CREATE_SESSIONS) @@ -121,7 +127,8 @@ public class AccountService } } - public OAuthResponse login(Request request, Response response) + @RequestMapping("/login") + public OAuthResponse login() { UUID uuid = UUID.randomUUID(); @@ -143,24 +150,25 @@ public class AccountService lr.setOauthUrl(authorizationUrl); lr.setUid(uuid); - response.type("application/json"); return lr; } - public Object callback(Request request, Response response) throws IOException, InterruptedException, ExecutionException + @RequestMapping("/callback") + public Object callback( + HttpServletRequest request, + HttpServletResponse response, + @RequestParam String error, + @RequestParam String code, + @RequestParam State state + ) throws InterruptedException, ExecutionException, IOException { - String error = request.queryParams("error"); - if (error != null) { logger.info("Error in oauth callback: {}", error); return null; } - String authorizationCode = request.queryParams("code"); - State state = gson.fromJson(request.queryParams("state"), State.class); - - logger.info("Got authorization code {} for uuid {}", authorizationCode, state.getUuid()); + logger.info("Got authorization code {} for uuid {}", code, state.getUuid()); OAuth20Service service = new ServiceBuilder() .apiKey(oauthClientId) @@ -170,13 +178,13 @@ public class AccountService .state(gson.toJson(state)) .build(GoogleApi20.instance()); - OAuth2AccessToken accessToken = service.getAccessToken(authorizationCode); + OAuth2AccessToken accessToken = service.getAccessToken(code); // Access user info OAuthRequest orequest = new OAuthRequest(Verb.GET, USERINFO); service.signRequest(accessToken, orequest); - com.github.scribejava.core.model.Response oresponse = service.execute(orequest); + Response oresponse = service.execute(orequest); if (oresponse.getCode() / 100 != 2) { @@ -213,7 +221,7 @@ public class AccountService logger.info("Created session for user {}", userInfo.getEmail()); } - response.redirect(RL_REDIR); + response.sendRedirect(RL_REDIR); notifySession(state.getUuid(), userInfo.getEmail()); @@ -237,9 +245,15 @@ public class AccountService service.send(response); } - public Object logout(Request request, Response response) + @RequestMapping("/logout") + public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException { - SessionEntry session = request.session().attribute("session"); + SessionEntry session = auth.handle(request, response); + + if (session == null) + { + return; + } try (Connection con = sql2o.open()) { @@ -247,13 +261,11 @@ public class AccountService .addParameter("uuid", session.getUuid().toString()) .executeUpdate(); } - - return ""; } - public Object sessionCheck(Request request, Response response) + @RequestMapping("/session-check") + public void sessionCheck(HttpServletRequest request, HttpServletResponse response) throws IOException { - // Auth filter would kick this out before here - return ""; + auth.handle(request, response); } } diff --git a/http-service/src/main/java/net/runelite/http/service/account/AuthFilter.java b/http-service/src/main/java/net/runelite/http/service/account/AuthFilter.java index d4ab7a70e7..2e4e464774 100644 --- a/http-service/src/main/java/net/runelite/http/service/account/AuthFilter.java +++ b/http-service/src/main/java/net/runelite/http/service/account/AuthFilter.java @@ -24,39 +24,38 @@ */ package net.runelite.http.service.account; +import java.io.IOException; import net.runelite.http.service.account.beans.SessionEntry; -import com.google.inject.Inject; -import com.google.inject.name.Named; import java.sql.Timestamp; import java.time.Instant; import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import net.runelite.http.api.RuneliteAPI; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; import org.sql2o.Connection; import org.sql2o.Sql2o; -import spark.Filter; -import spark.Request; -import spark.Response; -import spark.Session; -import static spark.Spark.halt; -public class AuthFilter implements Filter +@Service +public class AuthFilter { private final Sql2o sql2o; - @Inject - public AuthFilter(@Named("Runelite SQL2O") Sql2o sql2o) + @Autowired + public AuthFilter(@Qualifier("Runelite SQL2O") Sql2o sql2o) { this.sql2o = sql2o; } - @Override - public void handle(Request request, Response response) throws Exception + public SessionEntry handle(HttpServletRequest request, HttpServletResponse response) throws IOException { - String runeliteAuth = request.headers(RuneliteAPI.RUNELITE_AUTH); + String runeliteAuth = request.getHeader(RuneliteAPI.RUNELITE_AUTH); if (runeliteAuth == null) { - halt(401, "Access denied"); - return; + response.sendError(401, "Access denied"); + return null; } UUID uuid = UUID.fromString(runeliteAuth); @@ -69,8 +68,8 @@ public class AuthFilter implements Filter if (sessionEntry == null) { - halt(401, "Access denied"); - return; + response.sendError(401, "Access denied"); + return null; } Instant now = Instant.now(); @@ -82,8 +81,7 @@ public class AuthFilter implements Filter sessionEntry.setLastUsed(now); - Session session = request.session(); - session.attribute("session", sessionEntry); + return sessionEntry; } } diff --git a/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java b/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java index ac704ec681..55bca790e1 100644 --- a/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java +++ b/http-service/src/main/java/net/runelite/http/service/config/ConfigService.java @@ -24,18 +24,28 @@ */ package net.runelite.http.service.config; -import com.google.inject.Inject; -import com.google.inject.name.Named; +import java.io.IOException; import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import net.runelite.http.api.config.ConfigEntry; import net.runelite.http.api.config.Configuration; +import net.runelite.http.service.account.AuthFilter; import net.runelite.http.service.account.beans.SessionEntry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import static org.springframework.web.bind.annotation.RequestMethod.DELETE; +import static org.springframework.web.bind.annotation.RequestMethod.PUT; +import org.springframework.web.bind.annotation.RestController; import org.sql2o.Connection; import org.sql2o.Sql2o; import org.sql2o.Sql2oException; -import spark.Request; -import spark.Response; +@RestController +@RequestMapping("/config") public class ConfigService { private static final String CREATE_CONFIG = "CREATE TABLE IF NOT EXISTS `config` (\n" @@ -49,15 +59,17 @@ public class ConfigService + " ADD CONSTRAINT `user_fk` FOREIGN KEY (`user`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;"; private final Sql2o sql2o; + private final AuthFilter auth; - @Inject - public ConfigService(@Named("Runelite SQL2O") Sql2o sql2o) + @Autowired + public ConfigService( + @Qualifier("Runelite SQL2O") Sql2o sql2o, + AuthFilter auth + ) { this.sql2o = sql2o; - } + this.auth = auth; - public void init() - { try (Connection con = sql2o.open()) { con.createQuery(CREATE_CONFIG) @@ -75,9 +87,15 @@ public class ConfigService } } - public Configuration get(Request request, Response response) + @RequestMapping + public Configuration get(HttpServletRequest request, HttpServletResponse response) throws IOException { - SessionEntry session = request.session().attribute("session"); + SessionEntry session = auth.handle(request, response); + + if (session == null) + { + return null; + } List config; @@ -88,38 +106,54 @@ public class ConfigService .executeAndFetch(ConfigEntry.class); } - response.type("application/json"); return new Configuration(config); } - public Object setKey(Request request, Response response) + @RequestMapping(path = "/{key}", method = PUT) + public void setKey( + HttpServletRequest request, + HttpServletResponse response, + @PathVariable String key, + @RequestBody String value + ) throws IOException { - SessionEntry session = request.session().attribute("session"); + SessionEntry session = auth.handle(request, response); + + if (session == null) + { + return; + } try (Connection con = sql2o.open()) { con.createQuery("insert into config (user, `key`, value) values (:user, :key, :value) on duplicate key update value = :value") .addParameter("user", session.getUser()) - .addParameter("key", request.params("key")) - .addParameter("value", request.body()) + .addParameter("key", key) + .addParameter("value", value) .executeUpdate(); } - - return ""; } - public Object unsetKey(Request request, Response response) + @RequestMapping(path = "/{key}", method = DELETE) + public void unsetKey( + HttpServletRequest request, + HttpServletResponse response, + @PathVariable String key + ) throws IOException { - SessionEntry session = request.session().attribute("session"); + SessionEntry session = auth.handle(request, response); + + if (session == null) + { + return; + } try (Connection con = sql2o.open()) { con.createQuery("delete from config where user = :user and `key` = :key") .addParameter("user", session.getUser()) - .addParameter("key", request.params("key")) + .addParameter("key", key) .executeUpdate(); } - - return ""; } } diff --git a/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java b/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java index 19eb78d362..246dad93f7 100644 --- a/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java +++ b/http-service/src/main/java/net/runelite/http/service/examine/ExamineService.java @@ -24,8 +24,6 @@ */ package net.runelite.http.service.examine; -import com.google.inject.Inject; -import com.google.inject.name.Named; import java.sql.Timestamp; import java.time.Instant; import static net.runelite.http.service.examine.ExamineType.ITEM; @@ -33,11 +31,18 @@ import static net.runelite.http.service.examine.ExamineType.NPC; import static net.runelite.http.service.examine.ExamineType.OBJECT; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import static org.springframework.web.bind.annotation.RequestMethod.POST; +import org.springframework.web.bind.annotation.RestController; import org.sql2o.Connection; import org.sql2o.Sql2o; -import spark.Request; -import spark.Response; +@RestController +@RequestMapping("/examine") public class ExamineService { private static final Logger logger = LoggerFactory.getLogger(ExamineService.class); @@ -53,14 +58,11 @@ public class ExamineService private final Sql2o sql2o; - @Inject - public ExamineService(@Named("Runelite SQL2O") Sql2o sql2o) + @Autowired + public ExamineService(@Qualifier("Runelite SQL2O") Sql2o sql2o) { this.sql2o = sql2o; - } - public void init() - { try (Connection con = sql2o.open()) { con.createQuery(CREATE_EXAMINE) @@ -68,49 +70,40 @@ public class ExamineService } } - public String getNpc(Request request, Response response) + @RequestMapping("/npc/{id}") + public String getNpc(@PathVariable int id) { - int id = Integer.parseInt(request.params("id")); return get(NPC, id); } - public String getObject(Request request, Response response) + @RequestMapping("/object/{id}") + public String getObject(@PathVariable int id) { - int id = Integer.parseInt(request.params("id")); return get(OBJECT, id); } - public String getItem(Request request, Response response) + @RequestMapping("/item/{id}") + public String getItem(@PathVariable int id) { - int id = Integer.parseInt(request.params("id")); return get(ITEM, id); } - public Object submitNpc(Request request, Response response) + @RequestMapping(path = "/npc/{id}", method = POST) + public void submitNpc(@PathVariable int id, @RequestBody String examine) { - int id = Integer.parseInt(request.params("id")); - String examine = request.body(); - insert(NPC, id, examine); - return ""; } - public Object submitObject(Request request, Response response) + @RequestMapping(path = "/object/{id}", method = POST) + public void submitObject(@PathVariable int id, @RequestBody String examine) { - int id = Integer.parseInt(request.params("id")); - String examine = request.body(); - insert(OBJECT, id, examine); - return ""; } - public Object submitItem(Request request, Response response) + @RequestMapping(path = "/item/{id}", method = POST) + public void submitItem(@PathVariable int id, @RequestBody String examine) { - int id = Integer.parseInt(request.params("id")); - String examine = request.body(); - insert(ITEM, id, examine); - return ""; } private String get(ExamineType type, int id) 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 e6f0ff7234..9d1e1591be 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 @@ -31,30 +31,42 @@ import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; import net.runelite.http.api.hiscore.Skill; import net.runelite.http.api.hiscore.HiscoreSkill; import okhttp3.HttpUrl; +import okhttp3.Request; +import okhttp3.Response; import okhttp3.ResponseBody; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; -import spark.Request; -import spark.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +@RestController +@RequestMapping("/hiscore") public class HiscoreService { + private static final Logger logger = LoggerFactory.getLogger(HiscoreService.class); + private static final HttpUrl RUNESCAPE_HISCORE_SERVICE = HttpUrl.parse("http://services.runescape.com/m=hiscore_oldschool/index_lite.ws"); private HttpUrl url = RUNESCAPE_HISCORE_SERVICE; - private HiscoreResultBuilder lookup(String username) throws IOException + private HiscoreResultBuilder lookupUsername(String username) throws IOException { HttpUrl hiscoreUrl = url.newBuilder() .addQueryParameter("player", username) .build(); - okhttp3.Request okrequest = new okhttp3.Request.Builder() + logger.info("Built URL {}", hiscoreUrl); + + Request okrequest = new Request.Builder() .url(hiscoreUrl) .build(); - okhttp3.Response okresponse = RuneliteAPI.CLIENT.newCall(okrequest).execute(); + Response okresponse = RuneliteAPI.CLIENT.newCall(okrequest).execute(); String responseStr; try (ResponseBody body = okresponse.body()) @@ -88,24 +100,20 @@ public class HiscoreService return hiscoreBuilder; } - public HiscoreResult lookup(Request request, Response response) throws IOException + @RequestMapping + public HiscoreResult lookup(@RequestParam String username) throws IOException { - String username = request.queryParams("username"); - HiscoreResultBuilder result = lookup(username); - - response.type("application/json"); + HiscoreResultBuilder result = lookupUsername(username); return result.build(); } - public SingleHiscoreSkillResult singleSkillLookup(Request request, Response response) throws IOException + @RequestMapping("/{skillName}") + public SingleHiscoreSkillResult singleSkillLookup(@PathVariable String skillName, @RequestParam String username) throws IOException { - String username = request.queryParams("username"); - String skillName = request.params("skill"); - HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase()); // RS api only supports looking up all stats - HiscoreResultBuilder result = lookup(username); + HiscoreResultBuilder result = lookupUsername(username); // Find the skill to return Skill requested = result.getSkill(skill.ordinal()); @@ -115,7 +123,6 @@ public class HiscoreService skillResult.setSkillName(skillName); skillResult.setSkill(requested); - response.type("application/json"); return skillResult; } diff --git a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java index 80bd60e314..b404478b8d 100644 --- a/http-service/src/main/java/net/runelite/http/service/item/ItemService.java +++ b/http-service/src/main/java/net/runelite/http/service/item/ItemService.java @@ -27,8 +27,6 @@ package net.runelite.http.service.item; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.gson.JsonParseException; -import com.google.inject.Inject; -import com.google.inject.name.Named; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -38,22 +36,31 @@ import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; import net.runelite.http.api.RuneliteAPI; import net.runelite.http.api.item.Item; import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemType; import net.runelite.http.api.item.SearchResult; import okhttp3.HttpUrl; +import okhttp3.Request; +import okhttp3.Response; import okhttp3.ResponseBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import org.sql2o.Connection; import org.sql2o.Query; import org.sql2o.Sql2o; import org.sql2o.Sql2oException; -import spark.Request; -import spark.Response; +@RestController +@RequestMapping("/item") public class ItemService { private static final Logger logger = LoggerFactory.getLogger(ItemService.class); @@ -94,14 +101,11 @@ public class ItemService .maximumSize(1024L) .build(); - @Inject - public ItemService(@Named("Runelite SQL2O") Sql2o sql2o) + @Autowired + public ItemService(@Qualifier("Runelite SQL2O") Sql2o sql2o) { this.sql2o = sql2o; - } - public void init() - { try (Connection con = sql2o.open()) { con.createQuery(CREATE_ITEMS) @@ -132,91 +136,79 @@ public class ItemService } } - public Item getItem(Request request, Response response) + @RequestMapping("/{itemId}") + public Item getItem(HttpServletResponse response, @PathVariable int itemId) { - int itemId = Integer.parseInt(request.params("id")); - ItemEntry item = getItem(itemId); if (item != null) { - response.type("application/json"); - response.header(RUNELITE_CACHE, "HIT"); + response.setHeader(RUNELITE_CACHE, "HIT"); return item.toItem(); } item = fetchItem(itemId); if (item != null) { - response.type("application/json"); - response.header(RUNELITE_CACHE, "MISS"); + response.setHeader(RUNELITE_CACHE, "MISS"); return item.toItem(); } return null; } - public byte[] getIcon(Request request, Response response) + @RequestMapping(path = "/{itemId}/icon", produces = "image/gif") + public byte[] getIcon(HttpServletResponse response, @PathVariable int itemId) { - int itemId = Integer.parseInt(request.params("id")); - ItemEntry item = getItem(itemId); if (item != null && item.getIcon() != null) { - response.type("image/gif"); - response.header(RUNELITE_CACHE, "HIT"); + response.setHeader(RUNELITE_CACHE, "HIT"); return item.getIcon(); } item = fetchItem(itemId); if (item != null) { - response.type("image/gif"); - response.header(RUNELITE_CACHE, "MISS"); + response.setHeader(RUNELITE_CACHE, "MISS"); return item.getIcon(); } return null; } - public byte[] getIconLarge(Request request, Response response) + @RequestMapping(path = "/{itemId}/icon/large", produces = "image/gif") + public byte[] getIconLarge(HttpServletResponse response, @PathVariable int itemId) { - int itemId = Integer.parseInt(request.params("id")); - ItemEntry item = getItem(itemId); if (item != null && item.getIcon_large() != null) { - response.type("image/gif"); - response.header(RUNELITE_CACHE, "HIT"); + response.setHeader(RUNELITE_CACHE, "HIT"); return item.getIcon_large(); } item = fetchItem(itemId); if (item != null) { - response.type("image/gif"); - response.header(RUNELITE_CACHE, "MISS"); + response.setHeader(RUNELITE_CACHE, "MISS"); return item.getIcon_large(); } return null; } - public ItemPrice getPrice(Request request, Response response) + @RequestMapping("/{itemId}/price") + public ItemPrice getPrice( + HttpServletResponse response, + @PathVariable int itemId, + @RequestParam(required = false) Instant time + ) { - int itemId = Integer.parseInt(request.params("id")); - String ptime = request.params("time"); - Instant time = null; Instant now = Instant.now(); boolean hit = true; - if (ptime != null) + if (time != null && time.isAfter(now)) { - time = Instant.ofEpochMilli(Long.parseLong(ptime)); - - if (time.isAfter(now)) - { - time = now; - } + time = now; } ItemEntry item = getItem(itemId); @@ -263,23 +255,20 @@ public class ItemService itemPrice.setPrice(priceEntry.getPrice()); itemPrice.setTime(priceEntry.getTime()); - response.type("application/json"); - response.header(RUNELITE_CACHE, hit ? "HIT" : "MISS"); + response.setHeader(RUNELITE_CACHE, hit ? "HIT" : "MISS"); return itemPrice; } - public SearchResult search(Request request, Response response) + @RequestMapping("/search") + public SearchResult search(HttpServletResponse response, @RequestParam String query) { - String query = request.queryParams("query"); - // rs api seems to require lowercase query = query.toLowerCase(); SearchResult searchResult = cachedSearches.getIfPresent(query); if (searchResult != null) { - response.type("application/json"); - response.header(RUNELITE_CACHE, "HIT"); + response.setHeader(RUNELITE_CACHE, "HIT"); return searchResult; } @@ -314,8 +303,7 @@ public class ItemService con.commit(); } - response.type("application/json"); - response.header(RUNELITE_CACHE, "MISS"); + response.setHeader(RUNELITE_CACHE, "MISS"); return searchResult; } catch (IOException ex) @@ -460,7 +448,7 @@ public class ItemService .addQueryParameter("item", "" + itemId) .build(); - okhttp3.Request request = new okhttp3.Request.Builder() + Request request = new Request.Builder() .url(itemUrl) .build(); @@ -476,7 +464,7 @@ public class ItemService .addPathSegment(itemId + ".json") .build(); - okhttp3.Request request = new okhttp3.Request.Builder() + Request request = new Request.Builder() .url(priceUrl) .build(); @@ -490,16 +478,16 @@ public class ItemService .addQueryParameter("alpha", query) .build(); - okhttp3.Request request = new okhttp3.Request.Builder() + Request request = new Request.Builder() .url(searchUrl) .build(); return fetchJson(request, RSSearch.class); } - private T fetchJson(okhttp3.Request request, Class clazz) throws IOException + private T fetchJson(Request request, Class clazz) throws IOException { - okhttp3.Response response = RuneliteAPI.CLIENT.newCall(request).execute(); + Response response = RuneliteAPI.CLIENT.newCall(request).execute(); if (!response.isSuccessful()) { @@ -521,11 +509,11 @@ public class ItemService { HttpUrl httpUrl = HttpUrl.parse(url); - okhttp3.Request request = new okhttp3.Request.Builder() + Request request = new Request.Builder() .url(httpUrl) .build(); - okhttp3.Response response = RuneliteAPI.CLIENT.newCall(request).execute(); + Response response = RuneliteAPI.CLIENT.newCall(request).execute(); if (!response.isSuccessful()) { diff --git a/http-service/src/main/java/net/runelite/http/service/updatecheck/UpdateCheckService.java b/http-service/src/main/java/net/runelite/http/service/updatecheck/UpdateCheckService.java index 89f4adf914..5328edde18 100644 --- a/http-service/src/main/java/net/runelite/http/service/updatecheck/UpdateCheckService.java +++ b/http-service/src/main/java/net/runelite/http/service/updatecheck/UpdateCheckService.java @@ -25,7 +25,6 @@ package net.runelite.http.service.updatecheck; import com.google.common.base.Suppliers; -import com.google.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -41,9 +40,12 @@ import net.runelite.http.api.worlds.WorldResult; import net.runelite.http.service.worlds.WorldsService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import spark.Request; -import spark.Response; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +@RestController +@RequestMapping("/update-check") public class UpdateCheckService { private static final Logger logger = LoggerFactory.getLogger(UpdateCheckService.class); @@ -58,15 +60,15 @@ public class UpdateCheckService private final WorldsService worldsService; private final Supplier updateAvailable = Suppliers.memoizeWithExpiration(this::checkUpdate, 1, TimeUnit.MINUTES); - @Inject + @Autowired public UpdateCheckService(WorldsService worldsService) { this.worldsService = worldsService; } - public Boolean check(Request request, Response response) + @RequestMapping + public Boolean check() { - response.type("application/json"); return updateAvailable.get(); } diff --git a/http-service/src/main/java/net/runelite/http/service/worlds/WorldsService.java b/http-service/src/main/java/net/runelite/http/service/worlds/WorldsService.java index 1c121d0bbc..9029c9b18d 100644 --- a/http-service/src/main/java/net/runelite/http/service/worlds/WorldsService.java +++ b/http-service/src/main/java/net/runelite/http/service/worlds/WorldsService.java @@ -32,30 +32,28 @@ import net.runelite.http.api.RuneliteAPI; import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.WorldResult; import okhttp3.HttpUrl; +import okhttp3.Request; +import okhttp3.Response; import okhttp3.ResponseBody; -import spark.Request; -import spark.Response; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +@RestController +@RequestMapping("/worlds") public class WorldsService { private static final HttpUrl WORLD_URL = HttpUrl.parse("http://www.runescape.com/g=oldscape/slr.ws?order=LPWM"); private HttpUrl url = WORLD_URL; - public WorldResult listWorlds(Request request, Response response) throws IOException - { - WorldResult result = listWorlds(); - response.type("application/json"); - return result; - } - + @RequestMapping public WorldResult listWorlds() throws IOException { - okhttp3.Request okrequest = new okhttp3.Request.Builder() + Request okrequest = new Request.Builder() .url(url) .build(); - okhttp3.Response okresponse = RuneliteAPI.CLIENT.newCall(okrequest).execute(); + Response okresponse = RuneliteAPI.CLIENT.newCall(okrequest).execute(); byte[] b; try (ResponseBody body = okresponse.body()) diff --git a/http-service/src/main/java/net/runelite/http/service/xtea/XteaService.java b/http-service/src/main/java/net/runelite/http/service/xtea/XteaService.java index a057b4da24..1cc03812e4 100644 --- a/http-service/src/main/java/net/runelite/http/service/xtea/XteaService.java +++ b/http-service/src/main/java/net/runelite/http/service/xtea/XteaService.java @@ -24,21 +24,25 @@ */ package net.runelite.http.service.xtea; -import com.google.gson.Gson; -import com.google.inject.Inject; -import com.google.inject.name.Named; import java.util.List; import java.util.stream.Collectors; import net.runelite.http.api.xtea.XteaKey; import net.runelite.http.api.xtea.XteaRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import static org.springframework.web.bind.annotation.RequestMethod.POST; +import org.springframework.web.bind.annotation.RestController; import org.sql2o.Connection; import org.sql2o.Query; import org.sql2o.Sql2o; -import spark.Request; -import spark.Response; +@RestController +@RequestMapping("/xtea") public class XteaService { private static final Logger logger = LoggerFactory.getLogger(XteaService.class); @@ -54,16 +58,12 @@ public class XteaService + ") ENGINE=InnoDB;"; private final Sql2o sql2o; - private final Gson gson = new Gson(); - @Inject - public XteaService(@Named("Runelite SQL2O") Sql2o sql2o) + @Autowired + public XteaService(@Qualifier("Runelite SQL2O") Sql2o sql2o) { this.sql2o = sql2o; - } - public void init() - { try (Connection con = sql2o.beginTransaction()) { con.createQuery(CREATE_SQL) @@ -71,10 +71,9 @@ public class XteaService } } - public Object submit(Request request, Response response) + @RequestMapping(method = POST) + public Object submit(@RequestBody XteaRequest xteaRequest) { - XteaRequest xteaRequest = gson.fromJson(request.body(), XteaRequest.class); - try (Connection con = sql2o.beginTransaction()) { Query query = con.createQuery("insert ignore into xtea (rev, region, key1, key2, key3, key4) values (:rev, :region, :key1, :key2, :key3, :key4)"); @@ -97,19 +96,15 @@ public class XteaService return ""; } - public List get(Request request, Response response) + @RequestMapping("/{revision}") + public List get(@PathVariable int revision) { - String revStr = request.params("rev"); - int revision = Integer.parseInt(revStr); - try (Connection con = sql2o.open()) { List entries = con.createQuery("select * from xtea where rev = :rev") .addParameter("rev", revision) .executeAndFetch(XteaEntry.class); - response.type("application/json"); - return entries.stream() .map(XteaService::entryToKey) .collect(Collectors.toList()); diff --git a/http-service/src/main/webapp/WEB-INF/web.xml b/http-service/src/main/webapp/WEB-INF/web.xml index 1abb728616..df6faa44b8 100644 --- a/http-service/src/main/webapp/WEB-INF/web.xml +++ b/http-service/src/main/webapp/WEB-INF/web.xml @@ -29,23 +29,4 @@ version="3.1"> Runelite API - - - SparkServlet - net.runelite.http.service.SparkServlet - - - - SparkServlet - /* - - - - com.commongroundpublishing.slf4j.impl.ServletContextLoggerSCL - - - - ServletContextLogger.LEVEL - INFO - \ No newline at end of file diff --git a/http-service/src/test/java/net/runelite/http/service/ServiceTest.java b/http-service/src/test/java/net/runelite/http/service/ServiceTest.java deleted file mode 100644 index 5afaa9c3b4..0000000000 --- a/http-service/src/test/java/net/runelite/http/service/ServiceTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (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; - -import com.commongroundpublishing.slf4j.impl.ServletContextLogger; -import com.google.gson.Gson; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.name.Named; -import com.google.inject.testing.fieldbinder.Bind; -import com.google.inject.testing.fieldbinder.BoundFieldModule; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import javax.servlet.ServletContext; -import net.runelite.http.api.hiscore.HiscoreResult; -import net.runelite.http.api.hiscore.Skill; -import net.runelite.http.service.hiscore.HiscoreService; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Answers; -import org.mockito.Matchers; -import org.mockito.Mock; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import org.mockito.MockitoAnnotations; -import org.sql2o.Sql2o; -import spark.Request; -import spark.Response; -import spark.Spark; - -public class ServiceTest -{ - private static final String URL_BASE = "http://localhost:4567"; - - private Service service; - - @Bind - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - @Named("Runelite SQL2O") - private Sql2o sql2o; - - @Bind - @Named("OAuth Client ID") - private String clientId = "test"; - - @Bind - @Named("OAuth Client Secret") - private String clientSecret = "test"; - - @Bind - @Mock - private HiscoreService hiscoreService; - - @Before - public void before() - { - // Init mocks first, else we're binding null objects - MockitoAnnotations.initMocks(this); - // Inject everything in the test object - Injector injector = Guice.createInjector(BoundFieldModule.of(this)); - injector.injectMembers(this); - - ServletContextLogger.setServletContext(mock(ServletContext.class)); - - service = injector.getInstance(Service.class); - service.setupRoutes(); - - Spark.awaitInitialization(); - } - - @After - public void after() - { - Spark.stop(); - } - - @Test - public void testInit() throws Exception - { - HiscoreResult result = new HiscoreResult(); - result.setAttack(new Skill(1, 99, 42)); - - when(hiscoreService.lookup(Matchers.any(Request.class), Matchers.any(Response.class))).thenReturn(result); - - URL url = new URL(URL_BASE + "/hiscore?username=zezima"); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.connect(); - - Gson gson = new Gson(); - HiscoreResult res = gson.fromJson(new InputStreamReader(connection.getInputStream()), HiscoreResult.class); - - Assert.assertEquals(result, res); - } - -} diff --git a/http-service/src/main/java/net/runelite/http/service/JsonTransformer.java b/http-service/src/test/java/net/runelite/http/service/SpringBootWebApplicationTest.java similarity index 58% rename from http-service/src/main/java/net/runelite/http/service/JsonTransformer.java rename to http-service/src/test/java/net/runelite/http/service/SpringBootWebApplicationTest.java index b78c1c3d25..317fac3261 100644 --- a/http-service/src/main/java/net/runelite/http/service/JsonTransformer.java +++ b/http-service/src/test/java/net/runelite/http/service/SpringBootWebApplicationTest.java @@ -24,23 +24,50 @@ */ package net.runelite.http.service; -import com.google.gson.Gson; -import spark.ResponseTransformer; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.sql2o.Sql2o; +import org.sql2o.converters.Converter; +import org.sql2o.quirks.NoQuirks; -public class JsonTransformer implements ResponseTransformer +@SpringBootApplication +public class SpringBootWebApplicationTest { - private final Gson gson = new Gson(); - - @Override - public String render(Object model) throws Exception + @Bean("Runelite SQL2O") + Sql2o sql2o() { - if (model == null) - { - // gson turns a null object into "null" which - // causes spark to return http 200 instead of 404 - return null; - } + Map converters = new HashMap<>(); + converters.put(Instant.class, new InstantConverter()); + return new Sql2o("jdbc:mysql://192.168.1.2/runelite", "adam", "", new NoQuirks(converters)); - return gson.toJson(model); + } + + @Bean("OAuth Client ID") + String oauthClientId() + { + return "moo"; + } + + @Bean("OAuth Client Secret") + String oauthClientSecret() + { + return "moo2"; + } + + @Test + @Ignore + public void test() throws InterruptedException + { + SpringApplication.run(SpringBootWebApplicationTest.class, new String[0]); + for (;;) + { + Thread.sleep(100L); + } } } 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 bf34a721fc..2fcf74bcbb 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 @@ -32,9 +32,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import static org.mockito.Mockito.mock; -import spark.Request; -import spark.Response; public class HiscoreServiceTest { @@ -94,10 +91,7 @@ public class HiscoreServiceTest HiscoreService hiscores = new HiscoreService(); hiscores.setUrl(server.url("/")); - Request request = mock(Request.class); - Response response = mock(Response.class); - - HiscoreResult result = hiscores.lookup(request, response); + HiscoreResult result = hiscores.lookup("zezima"); Assert.assertEquals(50, result.getAttack().getLevel()); Assert.assertEquals(159727L, result.getFishing().getExperience()); diff --git a/http-service/src/test/java/net/runelite/http/service/worlds/WorldsServiceTest.java b/http-service/src/test/java/net/runelite/http/service/worlds/WorldsServiceTest.java index 7eb1e1a8b0..8942e54958 100644 --- a/http-service/src/test/java/net/runelite/http/service/worlds/WorldsServiceTest.java +++ b/http-service/src/test/java/net/runelite/http/service/worlds/WorldsServiceTest.java @@ -34,7 +34,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import spark.utils.IOUtils; +import org.sql2o.tools.IOUtils; public class WorldsServiceTest {