From 8c678f69ebb8f2f07701c0a535228d3ad74084ea Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 2 Feb 2018 22:28:31 -0500 Subject: [PATCH] cache service: split up into cache controller and service --- .../http/service/cache/CacheController.java | 252 ++++++++++++++++++ .../runelite/http/service/cache/CacheDAO.java | 2 +- .../http/service/cache/CacheService.java | 219 ++------------- .../http/service/xtea/XteaService.java | 17 +- 4 files changed, 284 insertions(+), 206 deletions(-) create mode 100644 http-service/src/main/java/net/runelite/http/service/cache/CacheController.java diff --git a/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java b/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java new file mode 100644 index 0000000000..ae11afff70 --- /dev/null +++ b/http-service/src/main/java/net/runelite/http/service/cache/CacheController.java @@ -0,0 +1,252 @@ +/* + * 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.cache; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import net.runelite.cache.ConfigType; +import net.runelite.cache.IndexType; +import net.runelite.cache.definitions.ItemDefinition; +import net.runelite.cache.definitions.NpcDefinition; +import net.runelite.cache.definitions.ObjectDefinition; +import net.runelite.cache.definitions.loaders.ItemLoader; +import net.runelite.cache.definitions.loaders.NpcLoader; +import net.runelite.cache.definitions.loaders.ObjectLoader; +import net.runelite.cache.fs.ArchiveFiles; +import net.runelite.cache.fs.FSFile; +import net.runelite.http.api.cache.Cache; +import net.runelite.http.api.cache.CacheArchive; +import net.runelite.http.api.cache.CacheIndex; +import net.runelite.http.service.util.exception.NotFoundException; +import net.runelite.http.service.cache.beans.ArchiveEntry; +import net.runelite.http.service.cache.beans.CacheEntry; +import net.runelite.http.service.cache.beans.IndexEntry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/cache") +@Slf4j +public class CacheController +{ + @Autowired + private CacheService cacheService; + + @RequestMapping("/") + public List listCaches() + { + return cacheService.listCaches().stream() + .map(entry -> new Cache(entry.getId(), entry.getRevision(), entry.getDate())) + .collect(Collectors.toList()); + } + + @RequestMapping("{cacheId}") + public List listIndexes(@PathVariable int cacheId) + { + CacheEntry cache = cacheService.findCache(cacheId); + if (cache == null) + { + throw new NotFoundException(); + } + + List indexes = cacheService.findIndexesForCache(cache); + + return indexes.stream() + .map(entry -> new CacheIndex(entry.getIndexId(), entry.getRevision())) + .collect(Collectors.toList()); + } + + @RequestMapping("{cacheId}/{indexId}") + public List listArchives(@PathVariable int cacheId, + @PathVariable int indexId) + { + CacheEntry cache = cacheService.findCache(cacheId); + if (cache == null) + { + throw new NotFoundException(); + } + + IndexEntry indexEntry = cacheService.findIndexForCache(cache, indexId); + if (indexEntry == null) + { + throw new NotFoundException(); + } + + List archives = cacheService.findArchivesForIndex(indexEntry); + + return archives.stream() + .map(archive -> new CacheArchive(archive.getArchiveId(), archive.getNameHash(), archive.getRevision())) + .collect(Collectors.toList()); + } + + @RequestMapping("{cacheId}/{indexId}/{archiveId}") + public CacheArchive getCacheArchive(@PathVariable int cacheId, + @PathVariable int indexId, + @PathVariable int archiveId) + { + CacheEntry cache = cacheService.findCache(cacheId); + if (cache == null) + { + throw new NotFoundException(); + } + + IndexEntry indexEntry = cacheService.findIndexForCache(cache, indexId); + if (indexEntry == null) + { + throw new NotFoundException(); + } + + ArchiveEntry archiveEntry = cacheService.findArchiveForIndex(indexEntry, archiveId); + if (archiveEntry == null) + { + throw new NotFoundException(); + } + + return new CacheArchive(archiveEntry.getArchiveId(), + archiveEntry.getNameHash(), archiveEntry.getRevision()); + } + + @RequestMapping("{cacheId}/{indexId}/{archiveId}/data") + public byte[] getArchiveData( + @PathVariable int cacheId, + @PathVariable int indexId, + @PathVariable int archiveId + ) + { + CacheEntry cache = cacheService.findCache(cacheId); + if (cache == null) + { + throw new NotFoundException(); + } + + IndexEntry indexEntry = cacheService.findIndexForCache(cache, indexId); + if (indexEntry == null) + { + throw new NotFoundException(); + } + + ArchiveEntry archiveEntry = cacheService.findArchiveForIndex(indexEntry, archiveId); + if (archiveEntry == null) + { + throw new NotFoundException(); + } + + return cacheService.getArchive(archiveEntry); + } + + private ArchiveEntry findConfig(ConfigType config) + { + CacheEntry cache = cacheService.findMostRecent(); + if (cache == null) + { + throw new NotFoundException(); + } + + IndexEntry indexEntry = cacheService.findIndexForCache(cache, IndexType.CONFIGS.getNumber()); + if (indexEntry == null) + { + throw new NotFoundException(); + } + + ArchiveEntry archiveEntry = cacheService.findArchiveForIndex(indexEntry, config.getId()); + if (archiveEntry == null) + { + throw new NotFoundException(); + } + + return archiveEntry; + } + + @RequestMapping("item/{itemId}") + public ItemDefinition getItem(@PathVariable int itemId) throws IOException + { + ArchiveEntry archiveEntry = findConfig(ConfigType.ITEM); + + ArchiveFiles archiveFiles = cacheService.getArchiveFiles(archiveEntry); + if (archiveFiles == null) + { + throw new NotFoundException(); + } + + FSFile file = archiveFiles.findFile(itemId); + if (file == null) + { + throw new NotFoundException(); + } + + ItemDefinition itemdef = new ItemLoader().load(itemId, file.getContents()); + return itemdef; + } + + @RequestMapping("object/{objectId}") + public ObjectDefinition getObject( + @PathVariable int objectId + ) throws IOException + { + ArchiveEntry archiveEntry = findConfig(ConfigType.OBJECT); + + ArchiveFiles archiveFiles = cacheService.getArchiveFiles(archiveEntry); + if (archiveFiles == null) + { + throw new NotFoundException(); + } + + FSFile file = archiveFiles.findFile(objectId); + if (file == null) + { + throw new NotFoundException(); + } + + ObjectDefinition objectdef = new ObjectLoader().load(objectId, file.getContents()); + return objectdef; + } + + @RequestMapping("npc/{npcId}") + public NpcDefinition getNpc( + @PathVariable int npcId + ) throws IOException + { + ArchiveEntry archiveEntry = findConfig(ConfigType.NPC); + + ArchiveFiles archiveFiles = cacheService.getArchiveFiles(archiveEntry); + if (archiveFiles == null) + { + throw new NotFoundException(); + } + + FSFile file = archiveFiles.findFile(npcId); + if (file == null) + { + throw new NotFoundException(); + } + + NpcDefinition npcdef = new NpcLoader().load(npcId, file.getContents()); + return npcdef; + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/cache/CacheDAO.java b/http-service/src/main/java/net/runelite/http/service/cache/CacheDAO.java index bbe5922430..d9d4286f6f 100644 --- a/http-service/src/main/java/net/runelite/http/service/cache/CacheDAO.java +++ b/http-service/src/main/java/net/runelite/http/service/cache/CacheDAO.java @@ -35,7 +35,7 @@ import org.sql2o.Connection; import org.sql2o.Query; import org.sql2o.ResultSetIterable; -public class CacheDAO +class CacheDAO { // cache prepared statements for high volume queries private Query associateArchive; diff --git a/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java b/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java index 39c4f3b124..eb06fd9069 100644 --- a/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java +++ b/http-service/src/main/java/net/runelite/http/service/cache/CacheService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Adam + * Copyright (c) 2017-2018, Adam * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,46 +42,29 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; -import net.runelite.cache.ConfigType; +import lombok.extern.slf4j.Slf4j; import net.runelite.cache.IndexType; -import net.runelite.cache.definitions.ItemDefinition; -import net.runelite.cache.definitions.NpcDefinition; -import net.runelite.cache.definitions.ObjectDefinition; -import net.runelite.cache.definitions.loaders.ItemLoader; -import net.runelite.cache.definitions.loaders.NpcLoader; -import net.runelite.cache.definitions.loaders.ObjectLoader; import net.runelite.cache.fs.ArchiveFiles; import net.runelite.cache.fs.Container; import net.runelite.cache.fs.FSFile; -import net.runelite.http.api.cache.Cache; -import net.runelite.http.api.cache.CacheArchive; -import net.runelite.http.api.cache.CacheIndex; -import net.runelite.http.service.util.exception.NotFoundException; import net.runelite.http.service.cache.beans.ArchiveEntry; import net.runelite.http.service.cache.beans.CacheEntry; import net.runelite.http.service.cache.beans.FileEntry; import net.runelite.http.service.cache.beans.IndexEntry; -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.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.stereotype.Service; import org.sql2o.Connection; import org.sql2o.ResultSetIterable; import org.sql2o.Sql2o; import org.xmlpull.v1.XmlPullParserException; -@RestController -@RequestMapping("/cache") +@Service +@Slf4j public class CacheService { - private static final Logger logger = LoggerFactory.getLogger(CacheService.class); - @Autowired @Qualifier("Runelite Cache SQL2O") private Sql2o sql2o; @@ -130,12 +113,12 @@ public class CacheService | IOException | InvalidKeyException | NoResponseException | XmlPullParserException | ErrorResponseException | InternalException | InvalidArgumentException ex) { - logger.warn(null, ex); + log.warn(null, ex); return null; } } - private ArchiveFiles getArchiveFiles(ArchiveEntry archiveEntry) throws IOException + public ArchiveFiles getArchiveFiles(ArchiveEntry archiveEntry) throws IOException { CacheDAO cacheDao = new CacheDAO(); @@ -169,228 +152,78 @@ public class CacheService } } - @RequestMapping("/") - public List listCaches() + public List listCaches() { - List caches; try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - caches = cacheDao.listCaches(con); + return cacheDao.listCaches(con); } - return caches.stream() - .map(entry -> new Cache(entry.getId(), entry.getRevision(), entry.getDate())) - .collect(Collectors.toList()); } - @RequestMapping("{cacheId}") - public List listIndexes(@PathVariable int cacheId) + public CacheEntry findCache(int cacheId) { - List indexes; - try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - CacheEntry cacheEntry = cacheDao.findCache(con, cacheId); - if (cacheEntry == null) - { - throw new NotFoundException(); - } - - indexes = cacheDao.findIndexesForCache(con, cacheEntry); + return cacheDao.findCache(con, cacheId); } - - return indexes.stream() - .map(entry -> new CacheIndex(entry.getIndexId(), entry.getRevision())) - .collect(Collectors.toList()); } - @RequestMapping("{cacheId}/{indexId}") - public List listArchives(@PathVariable int cacheId, - @PathVariable int indexId) + public CacheEntry findMostRecent() { - List archives = new ArrayList<>(); - try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - CacheEntry cacheEntry = cacheDao.findCache(con, cacheId); - if (cacheEntry == null) - { - throw new NotFoundException(); - } - - IndexEntry indexEntry = cacheDao.findIndexForCache(con, cacheEntry, indexId); - if (indexEntry == null) - { - throw new NotFoundException(); - } - - try (ResultSetIterable archiveEntries = cacheDao.findArchivesForIndex(con, indexEntry)) - { - Iterables.addAll(archives, archiveEntries); - } + return cacheDao.findMostRecent(con); } - - return archives.stream() - .map(archive -> new CacheArchive(archive.getArchiveId(), archive.getNameHash(), archive.getRevision())) - .collect(Collectors.toList()); } - @RequestMapping("{cacheId}/{indexId}/{archiveId}") - public CacheArchive getCacheArchive(@PathVariable int cacheId, - @PathVariable int indexId, - @PathVariable int archiveId) + public List findIndexesForCache(CacheEntry cacheEntry) { - ArchiveEntry archiveEntry; try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - CacheEntry cacheEntry = cacheDao.findCache(con, cacheId); - if (cacheEntry == null) - { - throw new NotFoundException(); - } - - IndexEntry indexEntry = cacheDao.findIndexForCache(con, cacheEntry, indexId); - if (indexEntry == null) - { - throw new NotFoundException(); - } - - archiveEntry = cacheDao.findArchiveForIndex(con, indexEntry, archiveId); + return cacheDao.findIndexesForCache(con, cacheEntry); } - - return new CacheArchive(archiveEntry.getArchiveId(), - archiveEntry.getNameHash(), archiveEntry.getRevision()); } - @RequestMapping("{cacheId}/{indexId}/{archiveId}/data") - public byte[] getArchiveData( - @PathVariable int cacheId, - @PathVariable int indexId, - @PathVariable int archiveId - ) + public IndexEntry findIndexForCache(CacheEntry cahceEntry, int indexId) { - ArchiveEntry archiveEntry; try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - CacheEntry cacheEntry = cacheDao.findCache(con, cacheId); - if (cacheEntry == null) - { - throw new NotFoundException(); - } - - IndexEntry indexEntry = cacheDao.findIndexForCache(con, cacheEntry, indexId); - if (indexEntry == null) - { - throw new NotFoundException(); - } - - archiveEntry = cacheDao.findArchiveForIndex(con, indexEntry, archiveId); + return cacheDao.findIndexForCache(con, cahceEntry, indexId); } - - return getArchive(archiveEntry); } - @RequestMapping("item/{itemId}") - public ItemDefinition getItem(@PathVariable int itemId) throws IOException + public List findArchivesForIndex(IndexEntry indexEntry) { - ArchiveEntry archiveEntry; try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - - CacheEntry cache = cacheDao.findMostRecent(con); - archiveEntry = cacheDao.findArchiveById(con, cache, IndexType.CONFIGS, ConfigType.ITEM.getId()); - if (archiveEntry == null) - { - throw new NotFoundException(); - } + ResultSetIterable archiveEntries = cacheDao.findArchivesForIndex(con, indexEntry); + List archives = new ArrayList<>(); + Iterables.addAll(archives, archiveEntries); + return archives; } - - ArchiveFiles archiveFiles = getArchiveFiles(archiveEntry); - if (archiveFiles == null) - { - throw new NotFoundException(); - } - - FSFile file = archiveFiles.findFile(itemId); - if (file == null) - { - throw new NotFoundException(); - } - - ItemDefinition itemdef = new ItemLoader().load(itemId, file.getContents()); - return itemdef; } - @RequestMapping("object/{objectId}") - public ObjectDefinition getObject( - @PathVariable int objectId - ) throws IOException + public ArchiveEntry findArchiveForIndex(IndexEntry indexEntry, int archiveId) { - ArchiveEntry archiveEntry; try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - - CacheEntry cache = cacheDao.findMostRecent(con); - archiveEntry = cacheDao.findArchiveById(con, cache, IndexType.CONFIGS, ConfigType.OBJECT.getId()); - if (archiveEntry == null) - { - throw new NotFoundException(); - } + return cacheDao.findArchiveForIndex(con, indexEntry, archiveId); } - - ArchiveFiles archiveFiles = getArchiveFiles(archiveEntry); - if (archiveFiles == null) - { - throw new NotFoundException(); - } - - FSFile file = archiveFiles.findFile(objectId); - if (file == null) - { - throw new NotFoundException(); - } - - ObjectDefinition objectdef = new ObjectLoader().load(objectId, file.getContents()); - return objectdef; } - @RequestMapping("npc/{npcId}") - public NpcDefinition getNpc( - @PathVariable int npcId - ) throws IOException + public ArchiveEntry findArchiveForTypeAndName(CacheEntry cache, IndexType index, int nameHash) { - ArchiveEntry archiveEntry; try (Connection con = sql2o.open()) { CacheDAO cacheDao = new CacheDAO(); - - CacheEntry cache = cacheDao.findMostRecent(con); - archiveEntry = cacheDao.findArchiveById(con, cache, IndexType.CONFIGS, ConfigType.NPC.getId()); - if (archiveEntry == null) - { - throw new NotFoundException(); - } + return cacheDao.findArchiveByName(con, cache, index, nameHash); } - - ArchiveFiles archiveFiles = getArchiveFiles(archiveEntry); - if (archiveFiles == null) - { - throw new NotFoundException(); - } - - FSFile file = archiveFiles.findFile(npcId); - if (file == null) - { - throw new NotFoundException(); - } - - NpcDefinition npcdef = new NpcLoader().load(npcId, file.getContents()); - return npcdef; } } 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 c6db5f47b1..116ffde877 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 @@ -32,7 +32,6 @@ import net.runelite.cache.fs.Container; import net.runelite.cache.util.Djb2; import net.runelite.http.api.xtea.XteaKey; import net.runelite.http.api.xtea.XteaRequest; -import net.runelite.http.service.cache.CacheDAO; import net.runelite.http.service.cache.CacheService; import net.runelite.http.service.cache.beans.ArchiveEntry; import net.runelite.http.service.cache.beans.CacheEntry; @@ -71,18 +70,15 @@ public class XteaService + ") ENGINE=InnoDB"; private final Sql2o sql2o; - private final Sql2o cacheSql2o; private final CacheService cacheService; @Autowired public XteaService( @Qualifier("Runelite SQL2O") Sql2o sql2o, - @Qualifier("Runelite Cache SQL2O") Sql2o cacheSql2o, CacheService cacheService ) { this.sql2o = sql2o; - this.cacheSql2o = cacheSql2o; this.cacheService = cacheService; try (Connection con = sql2o.beginTransaction()) @@ -105,11 +101,9 @@ public class XteaService @RequestMapping(method = POST) public void submit(@RequestBody XteaRequest xteaRequest) { - try (Connection con = sql2o.beginTransaction(); - Connection cacheCon = cacheSql2o.open()) + try (Connection con = sql2o.beginTransaction()) { - CacheDAO cacheDao = new CacheDAO(); - CacheEntry cache = cacheDao.findMostRecent(cacheCon); + CacheEntry cache = cacheService.findMostRecent(); if (cache == null) { @@ -141,7 +135,7 @@ public class XteaService continue; } - if (!checkKeys(cacheCon, cache, region, keys)) + if (!checkKeys(cache, region, keys)) { continue; } @@ -198,7 +192,7 @@ public class XteaService return entryToKey(entry); } - private boolean checkKeys(Connection con, CacheEntry cache, int regionId, int[] keys) + private boolean checkKeys(CacheEntry cache, int regionId, int[] keys) { int x = regionId >>> 8; int y = regionId & 0xFF; @@ -211,8 +205,7 @@ public class XteaService .toString(); int archiveNameHash = Djb2.hash(archiveName); - CacheDAO cacheDao = new CacheDAO(); - ArchiveEntry archiveEntry = cacheDao.findArchiveByName(con, cache, IndexType.MAPS, archiveNameHash); + ArchiveEntry archiveEntry = cacheService.findArchiveForTypeAndName(cache, IndexType.MAPS, archiveNameHash); if (archiveEntry == null) { throw new InternalServerErrorException("Unable to find archive for region");