Skip to content

Commit

Permalink
Refactor the turtle service
Browse files Browse the repository at this point in the history
It's now possible to have clients for the turtle service. This is implemented in a generic way (services can have "slave services").

This is needed to be able to provide turtle support for various services (chat, gxs tunnels, file transfers, ...).
  • Loading branch information
zapek committed Mar 6, 2024
1 parent 3182975 commit cb2aa79
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 10 deletions.
16 changes: 16 additions & 0 deletions app/src/main/java/io/xeres/app/xrs/service/RsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ public void init(NetworkReadyEvent event)
{
initialized = true;
initialize();
addSlavesIfNeeded();
}
}

private void addSlavesIfNeeded()
{
if (RsServiceMaster.class.isAssignableFrom(getClass()))
{
//noinspection rawtypes,unchecked
rsServiceRegistry.getSlaves(this).forEach(rsServiceSlave -> ((RsServiceMaster) this).addRsSlave(rsServiceSlave));
}
}

Expand Down Expand Up @@ -144,4 +154,10 @@ public int compareTo(RsService o)
{
return Integer.compare(getInitPriority().ordinal(), o.getInitPriority().ordinal());
}

@Override
public String toString()
{
return getServiceType().getName();
}
}
37 changes: 37 additions & 0 deletions app/src/main/java/io/xeres/app/xrs/service/RsServiceMaster.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.xrs.service;

/**
* This interface allows to implement dependencies between services, that is, one master service
* has a list of clients that it can handle. Each master service or client needs to implement this interface
* which can of course be extended.
*
* @see RsServiceSlave
*/
public interface RsServiceMaster<T>
{
/**
* Adds a slave service to a master service. The master service is responsible to handle them.
*
* @param slave the slave service to add to the master
*/
void addRsSlave(T slave);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import static org.apache.commons.collections4.ListUtils.emptyIfNull;

@Component
public class RsServiceRegistry
{
Expand All @@ -43,6 +45,7 @@ public class RsServiceRegistry

private final Set<String> enabledServiceClasses = new HashSet<>();
private final Map<Integer, RsService> services = new HashMap<>();
private final Map<Integer, List<RsServiceSlave>> masterServices = new HashMap<>();

private final Map<Integer, Map<Integer, Class<? extends Item>>> itemClassesWaiting = new HashMap<>();
private final Map<Integer, Class<? extends Item>> itemClassesGxsWaiting = new HashMap<>();
Expand Down Expand Up @@ -102,7 +105,7 @@ else if (DynamicServiceType.class.isAssignableFrom(itemClass))
}
else
{
itemClassesWaiting.computeIfAbsent(item.getServiceType(), k -> new HashMap<>()).put(item.getSubType(), itemClass);
itemClassesWaiting.computeIfAbsent(item.getServiceType(), v -> new HashMap<>()).put(item.getSubType(), itemClass);
}
}
catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e)
Expand Down Expand Up @@ -140,6 +143,13 @@ public boolean registerService(RsService rsService)

services.put(serviceType, rsService);

if (RsServiceSlave.class.isAssignableFrom(rsService.getClass()))
{
var master = ((RsServiceSlave) rsService).isRsSlaveOf();

masterServices.computeIfAbsent(master.getServiceType().getType(), v -> new ArrayList<>()).add((RsServiceSlave) rsService);
}

if (GxsRsService.class.isAssignableFrom(rsService.getClass()))
{
itemClassesGxsWaiting.forEach((subType, itemClass) -> itemClasses.put(serviceType << 16 | subType, itemClass));
Expand All @@ -155,6 +165,15 @@ public boolean registerService(RsService rsService)
return true;
}

List<RsServiceSlave> getSlaves(RsService rsService)
{
if (!RsServiceMaster.class.isAssignableFrom(rsService.getClass()))
{
throw new IllegalArgumentException("Master service " + rsService + " doesn't implement RsServiceMaster interface");
}
return emptyIfNull(masterServices.get(rsService.getServiceType().getType()));
}

public Item buildIncomingItem(int version, int service, int subtype)
{
if (version == 2)
Expand Down
35 changes: 35 additions & 0 deletions app/src/main/java/io/xeres/app/xrs/service/RsServiceSlave.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.xrs.service;

/**
* This interface allows to mark a service as a slave of some master.
*
* @see RsServiceMaster
*/
public interface RsServiceSlave
{
/**
* Registers this service as a slave of another service.
*
* @return the master service this service is slave of
*/
RsService isRsSlaveOf();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.xrs.service.filetransfer;

import io.xeres.app.net.peer.PeerConnection;
import io.xeres.app.service.file.FileService;
import io.xeres.app.xrs.item.Item;
import io.xeres.app.xrs.service.RsService;
import io.xeres.app.xrs.service.RsServiceRegistry;
import io.xeres.app.xrs.service.RsServiceType;
import io.xeres.app.xrs.service.turtle.TurtleRsClient;
import io.xeres.common.id.Sha1Sum;
import org.springframework.stereotype.Component;

import static io.xeres.app.xrs.service.RsServiceType.FILE_TRANSFER;

@Component
public class FileTransferRsService extends RsService implements TurtleRsClient
{
private final FileService fileService;

public FileTransferRsService(RsServiceRegistry rsServiceRegistry, FileService fileService)
{
super(rsServiceRegistry);
this.fileService = fileService;
}

@Override
public RsServiceType getServiceType()
{
return FILE_TRANSFER;
}

@Override
public RsService isRsSlaveOf()
{
return this;
}

@Override
public void handleItem(PeerConnection sender, Item item)
{
// XXX
}

@Override
public boolean handleTunnelRequest(PeerConnection sender, Sha1Sum hash)
{
var file = fileService.findFile(hash);
if (file.isPresent())
{
// XXX: don't forget to handle encrypted hashes, files currently being swarmed and tons of other things
// XXX: sender might not necessarily be needed (it's for the permissions)
return true;
}
return false;
}

@Override
public void receiveTurtleData()
{

}

@Override
public boolean receiveSearchRequest()
{
return false;
}

@Override
public void receiveSearchResult()
{

}

@Override
public void addVirtualPeer()
{

}

@Override
public void removeVirtualPeer()
{

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@ private short incrementDepth(int id, short depth)
}
return depth;
}

public int getBias()
{
return bias;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.xrs.service.turtle;

import io.xeres.app.net.peer.PeerConnection;
import io.xeres.app.xrs.service.RsServiceSlave;
import io.xeres.common.id.Sha1Sum;

public interface TurtleRsClient extends RsServiceSlave
{
/**
* @param sender
* @param hash
* @return true if found
*/
boolean handleTunnelRequest(PeerConnection sender, Sha1Sum hash);

void receiveTurtleData(); // XXX: args

boolean receiveSearchRequest(); // XXX: args

void receiveSearchResult(); // XXX: args

void addVirtualPeer(); // XXX: args

void removeVirtualPeer(); // XXX: args
}
Loading

0 comments on commit cb2aa79

Please sign in to comment.