Refactoring tracker + server
parent
d1d7993864
commit
275eb165b1
@ -0,0 +1,82 @@
|
||||
package tools;
|
||||
import tools.LogLevel;
|
||||
import protocolP2P.ProtocolP2PPacket;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.RequestResponseCode;
|
||||
|
||||
public abstract class ServeErrors {
|
||||
|
||||
/** Implementation of writeLog
|
||||
* @param text Text to log
|
||||
* @param logLevel level of logging
|
||||
*/
|
||||
protected abstract void writeLog(String text, LogLevel logLevel);
|
||||
|
||||
/** Implementation of writeLog
|
||||
* @param e exception to log
|
||||
* @param logLevel level of logging
|
||||
*/
|
||||
protected abstract void writeLog(Exception e, LogLevel logLevel);
|
||||
|
||||
/** Create packets
|
||||
* @param payload Payload
|
||||
*/
|
||||
protected abstract < T extends Payload > ProtocolP2PPacket<?> createProtocolP2PPacket(T payload);
|
||||
|
||||
/** Send a NotATracker error message.
|
||||
* @param pd Request received
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void sendNotATracker(T pd) {
|
||||
try {
|
||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.NOT_A_TRACKER)));
|
||||
} catch (Exception e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Send an internal error message.
|
||||
* @param pd Request received
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void sendInternalError(T pd) {
|
||||
writeLog("Internal Error", LogLevel.Warning);
|
||||
try {
|
||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.INTERNAL_ERROR)));
|
||||
} catch (Exception e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Send a not found message.
|
||||
* @param pd Request received
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void sendNotFound(T pd) {
|
||||
try {
|
||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.NOT_FOUND)));
|
||||
} catch (Exception e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Send an empty directory message.
|
||||
* @param pd Request received
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void sendEmptyDirectory(T pd) {
|
||||
try {
|
||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.EMPTY_DIRECTORY)));
|
||||
} catch (Exception e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Send an empty file message.
|
||||
* @param pd Request received
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void sendEmptyFile(T pd) {
|
||||
try {
|
||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.EMPTY_FILE)));
|
||||
} catch (Exception e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package tracker;
|
||||
import tools.ServeErrors;
|
||||
import tools.HostItem;
|
||||
import tools.Logger;
|
||||
import tools.LogLevel;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import protocolP2P.ProtocolP2PPacket;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.DiscoverRequest;
|
||||
import protocolP2P.DiscoverResponse;
|
||||
import protocolP2P.FileList;
|
||||
import protocolP2P.Unregister;
|
||||
import protocolP2P.Register;
|
||||
import protocolP2P.RequestResponseCode;
|
||||
import localException.InternalError;
|
||||
import remoteException.EmptyDirectory;
|
||||
import exception.LocalException;
|
||||
|
||||
public abstract class TrackerManagement extends ServeErrors implements Runnable {
|
||||
protected HostItem tracker;
|
||||
protected Logger logger;
|
||||
protected List<HostItem> hostList = new ArrayList<>();
|
||||
protected Map<String, List<HostItem>> fileList = new HashMap<>();
|
||||
protected volatile boolean stop;
|
||||
|
||||
/** Constructor
|
||||
* @param tracker Tracker HostItem
|
||||
* @param logger Logger
|
||||
*/
|
||||
public TrackerManagement(HostItem tracker, Logger logger) {
|
||||
stop = false;
|
||||
this.tracker = tracker;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/** Handle Discover request
|
||||
* @param pd Received request
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void handleDiscover(T pd) throws InternalError {
|
||||
Payload p = pd.getPayload();
|
||||
assert p instanceof DiscoverRequest : "payload must be an instance of DiscoverRequest";
|
||||
if (!(p instanceof DiscoverRequest)) {
|
||||
sendInternalError(pd);
|
||||
} else {
|
||||
String filename = ((DiscoverRequest)p).getFilename();
|
||||
try {
|
||||
pd.sendResponse(createProtocolP2PPacket(new DiscoverResponse(filename, fileList.getOrDefault(filename, hostList))));
|
||||
} catch (Exception e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle List Responses
|
||||
* @param pd Received response
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected <T extends ProtocolP2PPacket<?> > void handleListResponse(T pd, HostItem host) throws InternalError {
|
||||
Payload p = pd.getPayload();
|
||||
assert p instanceof FileList: "payload must be an instance of FileList";
|
||||
if (!(p instanceof FileList)) {
|
||||
throw new InternalError();
|
||||
} else {
|
||||
String[] f = ((FileList)p).getFileList();
|
||||
for (String file: f) {
|
||||
List<HostItem> h = fileList.get(file);
|
||||
if (h != null) {
|
||||
if (!h.contains(host)) {
|
||||
h.add(host);
|
||||
}
|
||||
} else {
|
||||
List<HostItem> emptyH = new ArrayList<>();
|
||||
emptyH.add(host);
|
||||
fileList.put(file, emptyH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle Unregistering
|
||||
* @param pd Request received
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void handleUnregister(T pd) throws InternalError {
|
||||
Payload p = pd.getPayload();
|
||||
assert p instanceof Unregister : "payload must be an instance of Unregister";
|
||||
if (!(p instanceof Unregister)) {
|
||||
sendInternalError(pd);
|
||||
throw new InternalError();
|
||||
}
|
||||
HostItem host = ((Unregister)p).getHostItem();
|
||||
writeLog("Received UNREGISTER from host " + pd.getHostItem() + ". Removing host " + host, LogLevel.Action);
|
||||
hostList.remove(host);
|
||||
for(String f: fileList.keySet()) {
|
||||
fileList.get(f).remove(host);
|
||||
if(fileList.get(f).isEmpty()) {
|
||||
fileList.remove(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Getter for HostItem socket
|
||||
* @param hostItem HostItem
|
||||
*/
|
||||
protected abstract Object getHostItemSocket(HostItem hostItem);
|
||||
|
||||
/** Close HostItem socket
|
||||
* @param hostItem HostItem
|
||||
*/
|
||||
protected abstract void closeHostItemSocket(HostItem hostItem);
|
||||
|
||||
/** Handle Registering
|
||||
* @param pd Received request
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected < T extends ProtocolP2PPacket<?> > void handleRegister(T pd) throws InternalError {
|
||||
Payload p = pd.getPayload();
|
||||
assert p instanceof Register : "payload must be an instance of Register";
|
||||
if (!(p instanceof Register)) {
|
||||
throw new InternalError();
|
||||
}
|
||||
// add host to known host list
|
||||
HostItem host = ((Register)p).getHostItem();
|
||||
if (!hostList.contains(host)) {
|
||||
hostList.add(host);
|
||||
}
|
||||
// send a list request
|
||||
try {
|
||||
ProtocolP2PPacket<?> pLReq = createProtocolP2PPacket(new Payload(RequestResponseCode.LIST_REQUEST));
|
||||
pLReq.sendRequest(getHostItemSocket(host));
|
||||
writeLog("Received REGISTER from host " + pd.getHostItem() + ". Adding host " + host + " to list. Sending List request", LogLevel.Action);
|
||||
handleListResponse(pLReq.receiveResponse(), host);
|
||||
writeLog("Received LIST RESPONSE from host " + pd.getHostItem(), LogLevel.Action);
|
||||
closeHostItemSocket(host);
|
||||
} catch (EmptyDirectory e) {
|
||||
writeLog("Empty Directory", LogLevel.Debug);
|
||||
hostList.remove(host);
|
||||
writeLog("Received EMPTY DIRECTORY from host " + pd.getHostItem() + ". Aborting.", LogLevel.Action);
|
||||
} catch (Exception e) {
|
||||
// remove from list because list request could not be send
|
||||
hostList.remove(host);
|
||||
writeLog("Aborting the add of host " + host, LogLevel.Action);
|
||||
writeLog(e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Handle requests
|
||||
* @throws LocalException
|
||||
*/
|
||||
protected <T extends ProtocolP2PPacket<?> > void handleRequest(T pd) throws LocalException {
|
||||
Payload p = pd.getPayload();
|
||||
switch (p.getRequestResponseCode()) {
|
||||
case LOAD_REQUEST:
|
||||
writeLog("Received LOAD_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
||||
sendNotFound(pd);
|
||||
break;
|
||||
case LIST_REQUEST:
|
||||
writeLog("Received LIST_REQUEST from host " + pd.getHostItem() + ", sending EMPTY_DIRECTORY", LogLevel.Action);
|
||||
sendEmptyDirectory(pd);
|
||||
break;
|
||||
case HASH_REQUEST:
|
||||
writeLog("Received HASH_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
||||
sendNotFound(pd);
|
||||
break;
|
||||
case REGISTER:
|
||||
writeLog("Received REGISTER from host " + pd.getHostItem(), LogLevel.Debug);
|
||||
handleRegister(pd);
|
||||
break;
|
||||
case UNREGISTER:
|
||||
writeLog("Received UNREGISTER from host " + pd.getHostItem(), LogLevel.Debug);
|
||||
handleUnregister(pd);
|
||||
break;
|
||||
case DISCOVER_REQUEST:
|
||||
writeLog("Received DISCOVER REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||
handleDiscover(pd);
|
||||
break;
|
||||
default:
|
||||
writeLog("Received grabbage from host " + pd.getHostItem(), LogLevel.Action);
|
||||
sendInternalError(pd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Stop the thread */
|
||||
public void setStop() {
|
||||
stop = true;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue