hook up persistence service

This commit is contained in:
Zlatin Balevsky
2019-05-25 15:48:19 +01:00
parent 36e1e82fa3
commit 42ddd321ea
4 changed files with 40 additions and 16 deletions

View File

@@ -19,6 +19,7 @@ import com.muwire.core.files.FileManager
import com.muwire.core.files.FileSharedEvent
import com.muwire.core.files.FileUnsharedEvent
import com.muwire.core.files.HasherService
import com.muwire.core.files.PersisterService
import com.muwire.core.hostcache.CacheClient
import com.muwire.core.hostcache.HostCache
import com.muwire.core.hostcache.HostDiscoveredEvent
@@ -181,6 +182,10 @@ class Core {
eventBus.register(FileUnsharedEvent.class, fileManager)
eventBus.register(SearchEvent.class, fileManager)
log.info "initializing persistence service"
PersisterService persisterService = new PersisterService(new File(home, "files.json"), eventBus, 5000, fileManager)
persisterService.start()
// ... at the end, sleep or execute script
if (args.length == 0) {

View File

@@ -11,7 +11,7 @@ class FileManager {
final EventBus eventBus
final Map<byte[], Set<SharedFile>> rootToFiles = new HashMap<>()
final Map<File, SharedFile> fileToSharedFile = new HashMap<>()
final Map<File, SharedFile> fileToSharedFile = Collections.synchronizedMap(new HashMap<>())
final Map<String, Set<File>> nameToFiles = new HashMap<>()
final SearchIndex index = new SearchIndex()
@@ -79,8 +79,9 @@ class FileManager {
}
Map<File, SharedFile> getSharedFiles() {
// TODO: figure out locking
fileToSharedFile
synchronized(fileToSharedFile) {
return new HashMap<>(fileToSharedFile)
}
}
void onSearchEvent(SearchEvent e) {

View File

@@ -1,5 +1,6 @@
package com.muwire.core.files
import java.util.logging.Level
import java.util.stream.Collectors
import com.muwire.core.DownloadedFile
@@ -7,25 +8,28 @@ import com.muwire.core.EventBus
import com.muwire.core.InfoHash
import com.muwire.core.Service
import com.muwire.core.SharedFile
import com.muwire.core.util.DataUtil
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import net.i2p.data.Base32
import groovy.util.logging.Log
import net.i2p.data.Base64
import net.i2p.data.Destination
@Log
class PersisterService extends Service {
final File location
final EventBus listener
final int interval
final Timer timer
final def fileSource
final FileManager fileManager
PersisterService(File location, EventBus listener, int interval, def fileSource) {
PersisterService(File location, EventBus listener, int interval, FileManager fileManager) {
this.location = location
this.listener = listener
this.interval = interval
this.fileSource = fileSource
this.fileManager = fileManager
timer = new Timer("file persister", true)
}
@@ -45,12 +49,14 @@ class PersisterService extends Service {
if (it.trim().length() > 0) {
def parsed = slurper.parseText it
def event = fromJson parsed
if (event != null)
if (event != null) {
log.fine("loaded file $event.loadedFile.file")
listener.publish event
}
}
}
} catch (IllegalArgumentException|NumberFormatException e) {
// abort loading
log.log(Level.WARNING, "couldn't load files",e)
}
}
timer.schedule({persistFiles()} as TimerTask, 0, interval)
@@ -63,7 +69,7 @@ class PersisterService extends Service {
if (!(json.hashList instanceof List))
throw new IllegalArgumentException()
def file = new File(json.file)
def file = new File(DataUtil.readi18nString(Base64.decode(json.file)))
file = file.getCanonicalFile()
if (!file.exists() || file.isDirectory())
return null
@@ -74,7 +80,7 @@ class PersisterService extends Service {
List hashList = (List) json.hashList
ByteArrayOutputStream baos = new ByteArrayOutputStream()
hashList.each {
byte [] hash = Base32.decode it.toString()
byte [] hash = Base64.decode it.toString()
if (hash == null)
throw new IllegalArgumentException()
baos.write hash
@@ -82,7 +88,7 @@ class PersisterService extends Service {
byte[] hashListBytes = baos.toByteArray()
InfoHash ih = InfoHash.fromHashList(hashListBytes)
byte [] root = Base32.decode(json.infoHash.toString())
byte [] root = Base64.decode(json.infoHash.toString())
if (root == null)
throw new IllegalArgumentException()
if (!Arrays.equals(root, ih.getRoot()))
@@ -102,7 +108,7 @@ class PersisterService extends Service {
private void persistFiles() {
location.delete()
def sharedFiles = fileSource.getSharedFiles()
def sharedFiles = fileManager.getSharedFiles()
location.withPrintWriter { writer ->
sharedFiles.each { k, v ->
def json = toJson(k,v)
@@ -114,15 +120,15 @@ class PersisterService extends Service {
private def toJson(File f, SharedFile sf) {
def json = [:]
json.file = f.getCanonicalFile().toString()
json.file = Base64.encode DataUtil.encodei18nString(f.getCanonicalFile().toString())
json.length = f.length()
InfoHash ih = sf.getInfoHash()
json.infoHash = Base32.encode ih.getRoot()
json.infoHash = Base64.encode ih.getRoot()
byte [] tmp = new byte [32]
json.hashList = []
for (int i = 0;i < ih.getHashList().length / 32; i++) {
System.arraycopy(ih.getHashList(), i * 32, tmp, 0, 32)
json.hashList.add Base32.encode(tmp)
json.hashList.add Base64.encode(tmp)
}
if (sf instanceof DownloadedFile) {

View File

@@ -49,4 +49,16 @@ class DataUtil {
System.arraycopy(encoded, 2, string, 0, length)
new String(string, StandardCharsets.UTF_8)
}
static byte[] encodei18nString(String string) {
byte [] utf8 = string.getBytes(StandardCharsets.UTF_8)
if (utf8.length > Short.MAX_VALUE)
throw new IllegalArgumentException("String in utf8 too long $utf8.length")
def baos = new ByteArrayOutputStream()
def daos = new DataOutputStream(baos)
daos.writeShort((short) utf8.length)
daos.write(utf8)
daos.close()
baos.toByteArray()
}
}