Refactoring tracker + server
This commit is contained in:
parent
d1d7993864
commit
275eb165b1
@ -3,6 +3,7 @@ import serverP2P.FileWatcher;
|
|||||||
import tools.Logger;
|
import tools.Logger;
|
||||||
import tools.LogLevel;
|
import tools.LogLevel;
|
||||||
import tools.HostItem;
|
import tools.HostItem;
|
||||||
|
import tools.ServeErrors;
|
||||||
import protocolP2P.ProtocolP2PPacket;
|
import protocolP2P.ProtocolP2PPacket;
|
||||||
import protocolP2P.Payload;
|
import protocolP2P.Payload;
|
||||||
import protocolP2P.RequestResponseCode;
|
import protocolP2P.RequestResponseCode;
|
||||||
@ -19,6 +20,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import exception.LocalException;
|
||||||
|
|
||||||
/** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol.
|
/** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol.
|
||||||
* @author Louis Royer
|
* @author Louis Royer
|
||||||
@ -26,7 +28,7 @@ import java.io.IOException;
|
|||||||
* @author JS Auge
|
* @author JS Auge
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public abstract class ServerManagement implements Runnable {
|
public abstract class ServerManagement extends ServeErrors implements Runnable {
|
||||||
|
|
||||||
protected volatile boolean stop;
|
protected volatile boolean stop;
|
||||||
protected FileWatcher fileListWatcher;
|
protected FileWatcher fileListWatcher;
|
||||||
@ -37,6 +39,7 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
public ServerManagement(String baseDirectory, HostItem server, HostItem tracker, Logger logger) {
|
public ServerManagement(String baseDirectory, HostItem server, HostItem tracker, Logger logger) {
|
||||||
|
super();
|
||||||
assert baseDirectory != null : "baseDirectory is null";
|
assert baseDirectory != null : "baseDirectory is null";
|
||||||
assert server != null : "server is null";
|
assert server != null : "server is null";
|
||||||
assert tracker != null : "tracker is null";
|
assert tracker != null : "tracker is null";
|
||||||
@ -61,23 +64,6 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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 response to list request
|
/** Send response to list request
|
||||||
* @param pd Request received
|
* @param pd Request received
|
||||||
*/
|
*/
|
||||||
@ -86,7 +72,7 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
String[] fileList = fileListWatcher.getFileList();
|
String[] fileList = fileListWatcher.getFileList();
|
||||||
if (fileList.length == 0) {
|
if (fileList.length == 0) {
|
||||||
writeLog("Sending EMPTY_DIRECTORY to host " + pd.getHostItem(), LogLevel.Action);
|
writeLog("Sending EMPTY_DIRECTORY to host " + pd.getHostItem(), LogLevel.Action);
|
||||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.EMPTY_DIRECTORY)));
|
sendEmptyDirectory(pd);
|
||||||
} else {
|
} else {
|
||||||
writeLog("Sending LIST_RESPONSE to host " + pd.getHostItem(), LogLevel.Action);
|
writeLog("Sending LIST_RESPONSE to host " + pd.getHostItem(), LogLevel.Action);
|
||||||
pd.sendResponse(createProtocolP2PPacket((Payload)(new FileList(fileList))));
|
pd.sendResponse(createProtocolP2PPacket((Payload)(new FileList(fileList))));
|
||||||
@ -96,28 +82,7 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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 hash response to hash request
|
/** Send hash response to hash request
|
||||||
* @param pd Request received
|
* @param pd Request received
|
||||||
@ -150,7 +115,7 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
} else {
|
} else {
|
||||||
// file not found
|
// file not found
|
||||||
try {
|
try {
|
||||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.NOT_FOUND)));
|
sendNotFound(pd);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
writeLog(e, LogLevel.Error);
|
writeLog(e, LogLevel.Error);
|
||||||
}
|
}
|
||||||
@ -186,7 +151,7 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
if (Arrays.binarySearch(fileList, filename) >= 0) {
|
if (Arrays.binarySearch(fileList, filename) >= 0) {
|
||||||
try {
|
try {
|
||||||
if (load.length == 0) {
|
if (load.length == 0) {
|
||||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.EMPTY_FILE)));
|
sendEmptyFile(pd);
|
||||||
} else {
|
} else {
|
||||||
pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, fullLoad.length, offset, load))));
|
pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, fullLoad.length, offset, load))));
|
||||||
}
|
}
|
||||||
@ -204,7 +169,7 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
pd.sendResponse(createProtocolP2PPacket(new Payload(RequestResponseCode.NOT_FOUND)));
|
sendNotFound(pd);
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
writeLog(e2, LogLevel.Debug);
|
writeLog(e2, LogLevel.Debug);
|
||||||
}
|
}
|
||||||
@ -230,4 +195,40 @@ public abstract class ServerManagement implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Handle request.
|
||||||
|
* @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(), LogLevel.Action);
|
||||||
|
sendLoadResponse(pd);
|
||||||
|
break;
|
||||||
|
case LIST_REQUEST:
|
||||||
|
writeLog("Received LIST_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendListResponse(pd);
|
||||||
|
break;
|
||||||
|
case HASH_REQUEST:
|
||||||
|
writeLog("Received HASH_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendHashResponse(pd);
|
||||||
|
break;
|
||||||
|
case DISCOVER_REQUEST:
|
||||||
|
writeLog("Received DISCOVER_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendNotATracker(pd);
|
||||||
|
break;
|
||||||
|
case UNREGISTER:
|
||||||
|
writeLog("Received UNREGISTER from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendNotATracker(pd);
|
||||||
|
break;
|
||||||
|
case REGISTER:
|
||||||
|
writeLog("Received REGISTER from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendNotATracker(pd);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
writeLog("Received grabbage from host " + pd.getHostItem(), LogLevel.Action);
|
||||||
|
sendInternalError(pd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import localException.SizeError;
|
|||||||
import localException.TransmissionError;
|
import localException.TransmissionError;
|
||||||
import localException.VersionError;
|
import localException.VersionError;
|
||||||
import localException.SocketClosed;
|
import localException.SocketClosed;
|
||||||
|
import exception.LocalException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import tools.Logger;
|
import tools.Logger;
|
||||||
import tools.LogLevel;
|
import tools.LogLevel;
|
||||||
@ -110,7 +111,7 @@ public class ServerManagementTCP extends ServerManagement {
|
|||||||
boolean end = false;
|
boolean end = false;
|
||||||
logger.writeTCP("[" + addr + "] New connection", LogLevel.Action);
|
logger.writeTCP("[" + addr + "] New connection", LogLevel.Action);
|
||||||
do {
|
do {
|
||||||
end = handleRequest();
|
end = handleClientRequest();
|
||||||
} while(!end);
|
} while(!end);
|
||||||
logger.writeTCP("[" + addr + "] End of connection", LogLevel.Action);
|
logger.writeTCP("[" + addr + "] End of connection", LogLevel.Action);
|
||||||
}
|
}
|
||||||
@ -119,49 +120,16 @@ public class ServerManagementTCP extends ServerManagement {
|
|||||||
* @param s Socket used to read request and send response
|
* @param s Socket used to read request and send response
|
||||||
* @return true if cannot expect another request (ie, socket is closed)
|
* @return true if cannot expect another request (ie, socket is closed)
|
||||||
*/
|
*/
|
||||||
private boolean handleRequest() {
|
private boolean handleClientRequest() {
|
||||||
try {
|
try {
|
||||||
ProtocolP2PPacketTCP<?> pd = new ProtocolP2PPacketTCP<>((Object)addr.getTCPSocket());
|
ProtocolP2PPacketTCP<?> pd = new ProtocolP2PPacketTCP<>((Object)addr.getTCPSocket());
|
||||||
Payload p = pd.getPayload();
|
handleRequest(pd);
|
||||||
switch (p.getRequestResponseCode()) {
|
|
||||||
case LOAD_REQUEST:
|
|
||||||
logger.writeTCP(addr + "LOAD_REQUEST", LogLevel.Action);
|
|
||||||
sendLoadResponse(pd);
|
|
||||||
break;
|
|
||||||
case LIST_REQUEST:
|
|
||||||
logger.writeTCP(addr + "LIST_REQUEST", LogLevel.Action);
|
|
||||||
sendListResponse(pd);
|
|
||||||
break;
|
|
||||||
case HASH_REQUEST:
|
|
||||||
logger.writeTCP(addr + "HASH_REQUEST", LogLevel.Action);
|
|
||||||
sendHashResponse(pd);
|
|
||||||
break;
|
|
||||||
case DISCOVER_REQUEST:
|
|
||||||
logger.writeTCP(addr + "DISCOVER_REQUEST", LogLevel.Action);
|
|
||||||
sendNotATracker(pd);
|
|
||||||
break;
|
|
||||||
case UNREGISTER:
|
|
||||||
logger.writeTCP(addr + "UNREGISTER", LogLevel.Action);
|
|
||||||
sendNotATracker(pd);
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
logger.writeTCP(addr + "REGISTER", LogLevel.Action);
|
|
||||||
sendNotATracker(pd);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.writeTCP(addr + "Received grabbage", LogLevel.Action);
|
|
||||||
sendInternalError(pd);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return true;
|
return true;
|
||||||
} catch (SocketClosed e) {
|
} catch (SocketClosed e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (TransmissionError e) {}
|
catch (LocalException e) {}
|
||||||
catch (ProtocolError e) {}
|
|
||||||
catch (VersionError e) {}
|
|
||||||
catch (InternalError e) {}
|
|
||||||
catch (SizeError e) {}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import localException.SizeError;
|
|||||||
import localException.TransmissionError;
|
import localException.TransmissionError;
|
||||||
import localException.VersionError;
|
import localException.VersionError;
|
||||||
import localException.SocketClosed;
|
import localException.SocketClosed;
|
||||||
|
import exception.LocalException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import tools.Logger;
|
import tools.Logger;
|
||||||
import tools.LogLevel;
|
import tools.LogLevel;
|
||||||
@ -77,35 +78,9 @@ public class ServerManagementUDP extends ServerManagement {
|
|||||||
while(!stop) {
|
while(!stop) {
|
||||||
try {
|
try {
|
||||||
ProtocolP2PPacketUDP<?> pd = new ProtocolP2PPacketUDP<>((Object)socket);
|
ProtocolP2PPacketUDP<?> pd = new ProtocolP2PPacketUDP<>((Object)socket);
|
||||||
Payload p = pd.getPayload();
|
handleRequest(pd);
|
||||||
switch (p.getRequestResponseCode()) {
|
|
||||||
case LOAD_REQUEST:
|
|
||||||
sendLoadResponse(pd);
|
|
||||||
break;
|
|
||||||
case LIST_REQUEST:
|
|
||||||
logger.writeUDP("Received LIST_REQUEST", LogLevel.Action);
|
|
||||||
sendListResponse(pd);
|
|
||||||
break;
|
|
||||||
case HASH_REQUEST:
|
|
||||||
logger.writeUDP("Received HASH_REQUEST", LogLevel.Action);
|
|
||||||
sendHashResponse(pd);
|
|
||||||
break;
|
|
||||||
case DISCOVER_REQUEST:
|
|
||||||
case UNREGISTER:
|
|
||||||
case REGISTER:
|
|
||||||
logger.writeUDP("Received Tracker request", LogLevel.Action);
|
|
||||||
sendNotATracker(pd);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sendInternalError(pd);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
} catch (SocketClosed e) {
|
} catch (LocalException e) {
|
||||||
} catch (TransmissionError e) {
|
|
||||||
} catch (ProtocolError e) {
|
|
||||||
} catch (VersionError e) {
|
|
||||||
} catch (InternalError e) {
|
|
||||||
} catch (SizeError e) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileListWatcher.setStop();
|
fileListWatcher.setStop();
|
||||||
|
82
src/tools/ServeErrors.java
Normal file
82
src/tools/ServeErrors.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
194
src/tracker/TrackerManagement.java
Normal file
194
src/tracker/TrackerManagement.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -25,6 +25,7 @@ import remoteException.EmptyDirectory;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import localException.SocketClosed;
|
import localException.SocketClosed;
|
||||||
|
import tracker.TrackerManagement;
|
||||||
|
|
||||||
|
|
||||||
/** Tracker management implementation with tcp
|
/** Tracker management implementation with tcp
|
||||||
@ -33,21 +34,15 @@ import localException.SocketClosed;
|
|||||||
* @author JS Auge
|
* @author JS Auge
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class TrackerManagementTCP implements Runnable {
|
public class TrackerManagementTCP extends TrackerManagement {
|
||||||
|
|
||||||
private HostItem tracker;
|
|
||||||
private Logger logger;
|
|
||||||
private ServerSocket socket;
|
private ServerSocket socket;
|
||||||
private List<HostItem> hostList = new ArrayList<>();
|
|
||||||
private Map<String, List<HostItem>> fileList = new HashMap<>();
|
|
||||||
|
|
||||||
/** Constructor with port and logger.
|
/** Constructor with port and logger.
|
||||||
* @param port Port used to listen.
|
* @param port Port used to listen.
|
||||||
* @param logger Logger object
|
* @param logger Logger object
|
||||||
*/
|
*/
|
||||||
public TrackerManagementTCP(int port, Logger logger) {
|
public TrackerManagementTCP(int port, Logger logger) {
|
||||||
tracker = new HostItem("localhost", port);
|
super(new HostItem("localhost", port), logger);
|
||||||
this.logger = logger;
|
|
||||||
try {
|
try {
|
||||||
socket = new ServerSocket(tracker.getPort(), 10, tracker.getInetAddress());
|
socket = new ServerSocket(tracker.getPort(), 10, tracker.getInetAddress());
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
@ -63,7 +58,7 @@ public class TrackerManagementTCP implements Runnable {
|
|||||||
*/
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
logger.writeTCP("Tracker sucessfully started", LogLevel.Info);
|
logger.writeTCP("Tracker sucessfully started", LogLevel.Info);
|
||||||
do {
|
while (!stop) {
|
||||||
try {
|
try {
|
||||||
Socket s = socket.accept();
|
Socket s = socket.accept();
|
||||||
ClientHandler c = new ClientHandler(s);
|
ClientHandler c = new ClientHandler(s);
|
||||||
@ -71,7 +66,7 @@ public class TrackerManagementTCP implements Runnable {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.writeTCP("Error while accepting new connection", LogLevel.Warning);
|
logger.writeTCP("Error while accepting new connection", LogLevel.Warning);
|
||||||
}
|
}
|
||||||
} while(true);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,7 +88,7 @@ public class TrackerManagementTCP implements Runnable {
|
|||||||
boolean end = false;
|
boolean end = false;
|
||||||
logger.writeTCP("[ " + addr + "] New connection", LogLevel.Action);
|
logger.writeTCP("[ " + addr + "] New connection", LogLevel.Action);
|
||||||
do {
|
do {
|
||||||
end = handleRequest();
|
end = handleClientRequest();
|
||||||
} while(!end);
|
} while(!end);
|
||||||
logger.writeTCP("[ " + addr + "] End of connection", LogLevel.Action);
|
logger.writeTCP("[ " + addr + "] End of connection", LogLevel.Action);
|
||||||
}
|
}
|
||||||
@ -102,39 +97,10 @@ public class TrackerManagementTCP implements Runnable {
|
|||||||
* @param s Socket used to read request and send response
|
* @param s Socket used to read request and send response
|
||||||
* @return true if cannot expect another request (ie, socket is closed)
|
* @return true if cannot expect another request (ie, socket is closed)
|
||||||
*/
|
*/
|
||||||
private boolean handleRequest() {
|
private boolean handleClientRequest() {
|
||||||
try {
|
try {
|
||||||
ProtocolP2PPacketTCP<?> pd = new ProtocolP2PPacketTCP<>((Object)addr.getTCPSocket());
|
ProtocolP2PPacketTCP<?> pd = new ProtocolP2PPacketTCP<>((Object)addr.getTCPSocket());
|
||||||
Payload p = pd.getPayload();
|
handleRequest(pd);
|
||||||
switch (p.getRequestResponseCode()) {
|
|
||||||
case LOAD_REQUEST:
|
|
||||||
logger.writeTCP("Received LOAD_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
|
||||||
sendNotFound(pd);
|
|
||||||
break;
|
|
||||||
case LIST_REQUEST:
|
|
||||||
logger.writeTCP("Received LIST_REQUEST from host " + pd.getHostItem() + ", sending EMPTY_DIRECTORY", LogLevel.Action);
|
|
||||||
sendEmptyDirectory(pd);
|
|
||||||
break;
|
|
||||||
case HASH_REQUEST:
|
|
||||||
logger.writeTCP("Received HASH_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
|
||||||
sendNotFound(pd);
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
logger.writeTCP("Received REGISTER from host " + pd.getHostItem(), LogLevel.Debug);
|
|
||||||
handleRegister(pd);
|
|
||||||
break;
|
|
||||||
case UNREGISTER:
|
|
||||||
logger.writeTCP("Received UNREGISTER from host " + pd.getHostItem(), LogLevel.Debug);
|
|
||||||
handleUnregister(pd);
|
|
||||||
break;
|
|
||||||
case DISCOVER_REQUEST:
|
|
||||||
handleDiscover(pd);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.writeTCP("Received grabbage from host " + pd.getHostItem(), LogLevel.Action);
|
|
||||||
sendInternalError(pd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.writeTCP(e, LogLevel.Warning);
|
logger.writeTCP(e, LogLevel.Warning);
|
||||||
return true;
|
return true;
|
||||||
@ -146,142 +112,43 @@ public class TrackerManagementTCP implements Runnable {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/** Send a not found message.
|
|
||||||
* @param pd ProtocolP2PPacketTCP to respond
|
|
||||||
*/
|
|
||||||
private void sendNotFound(ProtocolP2PPacketTCP<?> pd) {
|
|
||||||
try {
|
|
||||||
pd.sendResponse((ProtocolP2PPacket<?>)new ProtocolP2PPacketTCP<>(new Payload(RequestResponseCode.NOT_FOUND)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeTCP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Send an empty directory message.
|
/** Implementation of writeLog
|
||||||
* @param pd ProtocolP2PPacketTCP to respond
|
* @param text Text to log
|
||||||
*/
|
* @param logLevel level of logging
|
||||||
private void sendEmptyDirectory(ProtocolP2PPacketTCP<?> pd) {
|
*/
|
||||||
try {
|
protected void writeLog(String text, LogLevel logLevel) {
|
||||||
pd.sendResponse((ProtocolP2PPacket<?>)new ProtocolP2PPacketTCP<>(new Payload(RequestResponseCode.EMPTY_DIRECTORY)));
|
logger.writeTCP(text, logLevel);
|
||||||
} catch (Exception e) {
|
}
|
||||||
logger.writeTCP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Send an internal error message.
|
/** Implementation of writeLog
|
||||||
* @param pd ProtocolP2PPacketTCP to respond
|
* @param e exception to log
|
||||||
*/
|
* @param logLevel level of logging
|
||||||
private void sendInternalError(ProtocolP2PPacketTCP<?> pd) {
|
*/
|
||||||
logger.writeTCP("Internal Error", LogLevel.Warning);
|
protected void writeLog(Exception e, LogLevel logLevel) {
|
||||||
try {
|
logger.writeTCP(e, logLevel);
|
||||||
pd.sendResponse((ProtocolP2PPacket<?>)new ProtocolP2PPacketTCP<>(new Payload(RequestResponseCode.INTERNAL_ERROR)));
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeTCP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle Registering
|
/** Create packets
|
||||||
* @param pd ProtocolP2PPacketTCP to respond
|
* @param payload Payload
|
||||||
* @throws InternalError
|
*/
|
||||||
*/
|
protected < T extends Payload > ProtocolP2PPacket<T> createProtocolP2PPacket(T payload) {
|
||||||
private void handleRegister(ProtocolP2PPacketTCP<?> pd) throws InternalError {
|
return (ProtocolP2PPacket<T>)new ProtocolP2PPacketTCP<T>(payload);
|
||||||
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<Payload> pLReq = (ProtocolP2PPacket<Payload>) new ProtocolP2PPacketTCP<Payload>(new Payload(RequestResponseCode.LIST_REQUEST));
|
|
||||||
pLReq.sendRequest((Object)host.getTCPSocket());
|
|
||||||
logger.writeTCP("Received REGISTER from host " + pd.getHostItem() + ". Adding host " + host + " to list. Sending List request", LogLevel.Action);
|
|
||||||
handleListResponse((ProtocolP2PPacketTCP)pLReq.receiveResponse(), host);
|
|
||||||
logger.writeTCP("Received LIST RESPONSE from host " + pd.getHostItem(), LogLevel.Action);
|
|
||||||
host.closeTCPSocket();
|
|
||||||
} catch (EmptyDirectory e) {
|
|
||||||
logger.writeTCP("Empty Directory", LogLevel.Debug);
|
|
||||||
hostList.remove(host);
|
|
||||||
logger.writeTCP("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);
|
|
||||||
logger.writeTCP("Aborting the add of host " + host, LogLevel.Action);
|
|
||||||
logger.writeTCP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle Unregistering
|
|
||||||
* @param pd ProtocolP2PPacketTCP to respond
|
/** Getter for HostItem socket
|
||||||
* @throws InternalError
|
* @param hostItem HostItem
|
||||||
*/
|
*/
|
||||||
private void handleUnregister(ProtocolP2PPacketTCP<?> pd) throws InternalError {
|
protected Object getHostItemSocket(HostItem hostItem) {
|
||||||
Payload p = pd.getPayload();
|
return (Object)hostItem.getTCPSocket();
|
||||||
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();
|
|
||||||
logger.writeTCP("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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle Discover request
|
/** Close HostItem socket
|
||||||
* @param pd ProtocolP2PPacketTCP to respond
|
* @param hostItem HostItem
|
||||||
* @throws InternalError
|
*/
|
||||||
*/
|
protected void closeHostItemSocket(HostItem hostItem) {
|
||||||
private void handleDiscover(ProtocolP2PPacketTCP<?> pd) throws InternalError {
|
hostItem.closeTCPSocket();
|
||||||
logger.writeTCP("Received DISCOVER REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
|
||||||
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(new ProtocolP2PPacketTCP<DiscoverResponse>(new DiscoverResponse(filename, fileList.getOrDefault(filename, hostList))));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeTCP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle List Responses
|
|
||||||
* @param pd ProtocolP2PPacketTCP response
|
|
||||||
* @throws InternalError
|
|
||||||
*/
|
|
||||||
private void handleListResponse(ProtocolP2PPacketTCP<?> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import localException.InternalError;
|
|||||||
import remoteException.EmptyDirectory;
|
import remoteException.EmptyDirectory;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import tracker.TrackerManagement;
|
||||||
|
|
||||||
/** Tracker management implementation with udp
|
/** Tracker management implementation with udp
|
||||||
* @author Louis Royer
|
* @author Louis Royer
|
||||||
@ -30,21 +31,14 @@ import java.net.UnknownHostException;
|
|||||||
* @author JS Auge
|
* @author JS Auge
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class TrackerManagementUDP implements Runnable {
|
public class TrackerManagementUDP extends TrackerManagement {
|
||||||
|
|
||||||
private HostItem tracker;
|
|
||||||
private Logger logger;
|
|
||||||
private DatagramSocket socket;
|
private DatagramSocket socket;
|
||||||
private List<HostItem> hostList = new ArrayList<>();
|
|
||||||
private Map<String, List<HostItem>> fileList = new HashMap<>();
|
|
||||||
|
|
||||||
/** Constructor with port and logger.
|
/** Constructor with port and logger.
|
||||||
* @param port Port used to listen.
|
* @param port Port used to listen.
|
||||||
* @param logger Logger object
|
* @param logger Logger object
|
||||||
*/
|
*/
|
||||||
public TrackerManagementUDP(int port, Logger logger) {
|
public TrackerManagementUDP(int port, Logger logger) {
|
||||||
tracker = new HostItem("localhost", port);
|
super(new HostItem("localhost", port), logger);
|
||||||
this.logger = logger;
|
|
||||||
try {
|
try {
|
||||||
socket = new DatagramSocket(tracker.getPort(), tracker.getInetAddress());
|
socket = new DatagramSocket(tracker.getPort(), tracker.getInetAddress());
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
@ -57,39 +51,10 @@ public class TrackerManagementUDP implements Runnable {
|
|||||||
*/
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
logger.writeUDP("Tracker successfully started", LogLevel.Info);
|
logger.writeUDP("Tracker successfully started", LogLevel.Info);
|
||||||
while(true) {
|
while(!stop) {
|
||||||
try {
|
try {
|
||||||
ProtocolP2PPacketUDP<?> pd = new ProtocolP2PPacketUDP<>((Object)socket);
|
ProtocolP2PPacketUDP<?> pd = new ProtocolP2PPacketUDP<>((Object)socket);
|
||||||
Payload p = pd.getPayload();
|
handleRequest(pd);
|
||||||
switch (p.getRequestResponseCode()) {
|
|
||||||
case LOAD_REQUEST:
|
|
||||||
logger.writeUDP("Received LOAD_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
|
||||||
sendNotFound(pd);
|
|
||||||
break;
|
|
||||||
case LIST_REQUEST:
|
|
||||||
logger.writeUDP("Received LIST_REQUEST from host " + pd.getHostItem() + ", sending EMPTY_DIRECTORY", LogLevel.Action);
|
|
||||||
sendEmptyDirectory(pd);
|
|
||||||
break;
|
|
||||||
case HASH_REQUEST:
|
|
||||||
logger.writeUDP("Received HASH_REQUEST from host " + pd.getHostItem() + ", sending NOT_FOUND", LogLevel.Action);
|
|
||||||
sendNotFound(pd);
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
logger.writeUDP("Received REGISTER from host " + pd.getHostItem(), LogLevel.Debug);
|
|
||||||
handleRegister(pd);
|
|
||||||
break;
|
|
||||||
case UNREGISTER:
|
|
||||||
logger.writeUDP("Received UNREGISTER from host " + pd.getHostItem(), LogLevel.Debug);
|
|
||||||
handleUnregister(pd);
|
|
||||||
break;
|
|
||||||
case DISCOVER_REQUEST:
|
|
||||||
handleDiscover(pd);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.writeUDP("Received grabbage from host " + pd.getHostItem(), LogLevel.Action);
|
|
||||||
sendInternalError(pd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.writeUDP(e, LogLevel.Warning);
|
logger.writeUDP(e, LogLevel.Warning);
|
||||||
} catch (LocalException e) {
|
} catch (LocalException e) {
|
||||||
@ -97,143 +62,42 @@ public class TrackerManagementUDP implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send a not found message.
|
/** Implementation of writeLog
|
||||||
* @param pd ProtocolP2PPacketUDP to respond
|
* @param text Text to log
|
||||||
|
* @param logLevel level of logging
|
||||||
*/
|
*/
|
||||||
private void sendNotFound(ProtocolP2PPacketUDP<?> pd) {
|
protected void writeLog(String text, LogLevel logLevel) {
|
||||||
try {
|
logger.writeUDP(text, logLevel);
|
||||||
pd.sendResponse((ProtocolP2PPacket<?>)new ProtocolP2PPacketUDP<>(new Payload(RequestResponseCode.NOT_FOUND)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeUDP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send an empty directory message.
|
/** Implementation of writeLog
|
||||||
* @param pd ProtocolP2PPacketUDP to respond
|
* @param e exception to log
|
||||||
|
* @param logLevel level of logging
|
||||||
*/
|
*/
|
||||||
private void sendEmptyDirectory(ProtocolP2PPacketUDP<?> pd) {
|
protected void writeLog(Exception e, LogLevel logLevel) {
|
||||||
try {
|
logger.writeUDP(e, logLevel);
|
||||||
pd.sendResponse((ProtocolP2PPacket<?>)new ProtocolP2PPacketUDP<>(new Payload(RequestResponseCode.EMPTY_DIRECTORY)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeUDP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send an internal error message.
|
/** Create packets
|
||||||
* @param pd ProtocolP2PPacketUDP to respond
|
* @param payload Payload
|
||||||
*/
|
*/
|
||||||
private void sendInternalError(ProtocolP2PPacketUDP<?> pd) {
|
protected < T extends Payload > ProtocolP2PPacket<T> createProtocolP2PPacket(T payload) {
|
||||||
logger.writeUDP("Internal Error", LogLevel.Warning);
|
return (ProtocolP2PPacket<T>)new ProtocolP2PPacketUDP<T>(payload);
|
||||||
try {
|
|
||||||
pd.sendResponse((ProtocolP2PPacket<?>)new ProtocolP2PPacketUDP<>(new Payload(RequestResponseCode.INTERNAL_ERROR)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeUDP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handle Registering
|
|
||||||
* @param pd ProtocolP2PPacketUDP to respond
|
/** Getter for HostItem socket
|
||||||
* @throws InternalError
|
* @param hostItem HostItem
|
||||||
*/
|
*/
|
||||||
private void handleRegister(ProtocolP2PPacketUDP<?> pd) throws InternalError {
|
protected Object getHostItemSocket(HostItem hostItem) {
|
||||||
Payload p = pd.getPayload();
|
return (Object)hostItem.getUDPSocket();
|
||||||
assert p instanceof Register : "payload must be an instance of Register";
|
|
||||||
if (!(p instanceof Register)) {
|
|
||||||
sendInternalError(pd);
|
|
||||||
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<Payload> pLReq = (ProtocolP2PPacket<Payload>)new ProtocolP2PPacketUDP<Payload>(new Payload(RequestResponseCode.LIST_REQUEST));
|
|
||||||
pLReq.sendRequest((Object)host.getUDPSocket());
|
|
||||||
logger.writeUDP("Received REGISTER from host " + pd.getHostItem() + ". Adding host " + host + " to list. Sending List request", LogLevel.Action);
|
|
||||||
ProtocolP2PPacket<?> resp = pLReq.receiveResponse();
|
|
||||||
handleListResponse((ProtocolP2PPacketUDP)resp, host);
|
|
||||||
logger.writeUDP("Received LIST RESPONSE from host " + pd.getHostItem(), LogLevel.Action);
|
|
||||||
host.closeUDPSocket();
|
|
||||||
} catch (EmptyDirectory e) {
|
|
||||||
logger.writeUDP("Empty Directory", LogLevel.Debug);
|
|
||||||
hostList.remove(host);
|
|
||||||
logger.writeUDP("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);
|
|
||||||
logger.writeUDP("Aborting the add of host " + host, LogLevel.Action);
|
|
||||||
logger.writeUDP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handle Unregistering
|
/** Close HostItem socket
|
||||||
* @param pd ProtocolP2PPacketUDP to respond
|
* @param hostItem HostItem
|
||||||
* @throws InternalError
|
|
||||||
*/
|
*/
|
||||||
private void handleUnregister(ProtocolP2PPacketUDP<?> pd) throws InternalError {
|
protected void closeHostItemSocket(HostItem hostItem) {
|
||||||
Payload p = pd.getPayload();
|
hostItem.closeUDPSocket();
|
||||||
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();
|
|
||||||
logger.writeUDP("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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle Discover request
|
|
||||||
* @param pd ProtocolP2PPacketUDP to respond
|
|
||||||
* @throws InternalError
|
|
||||||
*/
|
|
||||||
private void handleDiscover(ProtocolP2PPacketUDP<?> pd) throws InternalError {
|
|
||||||
logger.writeUDP("Received DISCOVER REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
|
||||||
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(new ProtocolP2PPacketUDP<DiscoverResponse>(new DiscoverResponse(filename, fileList.getOrDefault(filename, hostList))));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.writeUDP(e, LogLevel.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle List Responses
|
|
||||||
* @param pd ProtocolP2PPacketUDP response
|
|
||||||
* @throws InternalError
|
|
||||||
*/
|
|
||||||
private void handleListResponse(ProtocolP2PPacketUDP<?> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user