Merge pull request 'Ratio' (#86) from ratio into etape5
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/pr-master This commit looks good
Details
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/pr-master This commit looks good
Details
commit
68446551b4
@ -0,0 +1,86 @@
|
||||
package protocolP2P;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.RequestResponseCode;
|
||||
import localException.ProtocolError;
|
||||
import localException.InternalError;
|
||||
import localException.SizeError;
|
||||
import localException.TransmissionError;
|
||||
import tools.BytesArrayTools;
|
||||
|
||||
/** Representation of payload for denied response.
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Denied extends Payload {
|
||||
private String filename;
|
||||
private long offset;
|
||||
static final private int OFFSET_POSITION = PAYLOAD_START_POSITION;
|
||||
static final private int FILENAME_POSITION = OFFSET_POSITION + 8;
|
||||
|
||||
/** Constructor (typically used by server) with informations about file part to send as parameters.
|
||||
* @param filename name of the file to send
|
||||
* @param offset where in the file begins the part we are sending
|
||||
* @throws InternalError
|
||||
*/
|
||||
public Denied(String filename, long offset) throws InternalError {
|
||||
super(RequestResponseCode.DENIED);
|
||||
/* asserts to help debugging */
|
||||
assert offset >= 0 : "offset cannot be negative";
|
||||
assert filename != null : "filename is required";
|
||||
if (offset < 0 || filename == null) {
|
||||
throw new InternalError();
|
||||
}
|
||||
this.filename = filename;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/** Constructor (typically used by client) with Packet received as parameter.
|
||||
* @param packet the full Packet received
|
||||
* @throws SizeError
|
||||
* @throws InternalError
|
||||
* @throws TransmissionError
|
||||
*/
|
||||
protected Denied(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
|
||||
super(packet);
|
||||
int filenameSize = getPayloadSize(packet) - FILENAME_POSITION + PAYLOAD_START_POSITION;
|
||||
offset = BytesArrayTools.readLong(packet, OFFSET_POSITION);
|
||||
filename = BytesArrayTools.readString(packet, FILENAME_POSITION, filenameSize);
|
||||
}
|
||||
|
||||
/** Returns a byte[] containing Packet with padding.
|
||||
* This Packet is still incomplete and should not be send directly.
|
||||
* ProtocolP2PPacket will use this method to generate the complete Packet.
|
||||
* @return Packet with padding
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
// compute total size
|
||||
int size = FILENAME_POSITION + filename.length();
|
||||
byte[] packet = new byte[size]; // java initialize all to zero
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
// set Payload size
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// write offset to Packet
|
||||
BytesArrayTools.write(packet, OFFSET_POSITION, offset);
|
||||
// write filename to Packet
|
||||
BytesArrayTools.write(packet, filename, FILENAME_POSITION);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** filename getter.
|
||||
* @return String
|
||||
*/
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/** offset getter.
|
||||
* @return offset
|
||||
*/
|
||||
public long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package protocolP2P;
|
||||
import protocolP2P.Payload;
|
||||
import tools.HostItem;
|
||||
import tools.BytesArrayTools;
|
||||
import localException.SizeError;
|
||||
import localException.InternalError;
|
||||
import localException.TransmissionError;
|
||||
import localException.ProtocolError;
|
||||
|
||||
/** Representation of payload for ratio request.
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RatioRequest extends Payload {
|
||||
private HostItem hostItem;
|
||||
private static final int HOSTNAME_START_POSITION = PAYLOAD_START_POSITION + 2;
|
||||
|
||||
/** Constructor with hostItem (typically used by client/server)
|
||||
* @param hostItem Host to get ratio of.
|
||||
* @throws InternalError
|
||||
*/
|
||||
public RatioRequest(HostItem hostItem) throws InternalError {
|
||||
super(RequestResponseCode.RATIO_REQUEST);
|
||||
this.hostItem = hostItem;
|
||||
}
|
||||
|
||||
/** Constructor (typically used by tracker) with a byte[] parameter containing the Packet received.
|
||||
* @param packet the full Packet received
|
||||
* @throws SizeError
|
||||
* @throws InternalError
|
||||
* @throws ProtocolError
|
||||
* @throws TransmissionError
|
||||
*/
|
||||
protected RatioRequest(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError {
|
||||
super(packet);
|
||||
int size = getPayloadSize(packet);
|
||||
int port = BytesArrayTools.readInt16Bits(packet, PAYLOAD_START_POSITION);
|
||||
String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION);
|
||||
hostItem = new HostItem(hostname, port);
|
||||
}
|
||||
|
||||
/** Returns a byte[] containing Packet with padding.
|
||||
* This Packet is still incomplete and should not be send directly.
|
||||
* ProtocolP2PPacket will use this method to generate the complete Packet.
|
||||
* @return Packet with padding
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String hostname = hostItem.getHostname();
|
||||
// compute total size
|
||||
int size = HOSTNAME_START_POSITION + hostname.length();
|
||||
byte[] packet = new byte[size]; // java initialize all to zero
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
// set Payload size
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// write port to Packet
|
||||
try {
|
||||
BytesArrayTools.write16Bits(packet, PAYLOAD_START_POSITION, hostItem.getPort());
|
||||
} catch (SizeError e) {
|
||||
throw new InternalError();
|
||||
}
|
||||
// write hostname to Packet
|
||||
BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** HostItem getter.
|
||||
* @return hostItem
|
||||
*/
|
||||
public HostItem getHostItem() {
|
||||
return hostItem;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package protocolP2P;
|
||||
import protocolP2P.Payload;
|
||||
import tools.HostItem;
|
||||
import tools.BytesArrayTools;
|
||||
import localException.SizeError;
|
||||
import localException.InternalError;
|
||||
import localException.TransmissionError;
|
||||
import localException.ProtocolError;
|
||||
|
||||
/** Representation of payload for ratio response.
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RatioResponse extends Payload {
|
||||
private HostItem hostItem;
|
||||
private long totalUp;
|
||||
private long totalDown;
|
||||
private static final int TOTAL_UP_START_POSITION = PAYLOAD_START_POSITION;
|
||||
private static final int TOTAL_DOWN_START_POSITION = TOTAL_UP_START_POSITION + 8;
|
||||
private static final int PORT_START_POSITION = TOTAL_DOWN_START_POSITION + 8;
|
||||
private static final int HOSTNAME_START_POSITION = PORT_START_POSITION + 2;
|
||||
|
||||
/** Constructor with hostItem (typically used by tracker)
|
||||
* @param hostItem Host to get ratio of.
|
||||
* @param totalUp total bytes uploaded
|
||||
* @param totalDown total bytes downloaded
|
||||
* @throws InternalError
|
||||
*/
|
||||
public RatioResponse(HostItem hostItem, long totalUp, long totalDown) throws InternalError {
|
||||
super(RequestResponseCode.RATIO_RESPONSE);
|
||||
this.hostItem = hostItem;
|
||||
this.totalUp = totalUp;
|
||||
this.totalDown = totalDown;
|
||||
}
|
||||
|
||||
/** Constructor (typically used by client/server) with a byte[] parameter containing the Packet received.
|
||||
* @param packet the full Packet received
|
||||
* @throws SizeError
|
||||
* @throws InternalError
|
||||
* @throws ProtocolError
|
||||
* @throws TransmissionError
|
||||
*/
|
||||
protected RatioResponse(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError {
|
||||
super(packet);
|
||||
int size = getPayloadSize(packet);
|
||||
totalUp = BytesArrayTools.readLong(packet, TOTAL_UP_START_POSITION);
|
||||
totalDown = BytesArrayTools.readLong(packet, TOTAL_DOWN_START_POSITION);
|
||||
int port = BytesArrayTools.readInt16Bits(packet, PORT_START_POSITION);
|
||||
String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION);
|
||||
hostItem = new HostItem(hostname, port);
|
||||
}
|
||||
|
||||
/** Returns a byte[] containing Packet with padding.
|
||||
* This Packet is still incomplete and should not be send directly.
|
||||
* ProtocolP2PPacket will use this method to generate the complete Packet.
|
||||
* @return Packet with padding
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String hostname = hostItem.getHostname();
|
||||
// compute total size
|
||||
int size = HOSTNAME_START_POSITION + hostname.length();
|
||||
byte[] packet = new byte[size]; // java initialize all to zero
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
// set Payload size
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// write totalUp
|
||||
BytesArrayTools.write(packet, TOTAL_UP_START_POSITION, totalUp);
|
||||
// write totalDown
|
||||
BytesArrayTools.write(packet, TOTAL_DOWN_START_POSITION, totalDown);
|
||||
// write port to Packet
|
||||
try {
|
||||
BytesArrayTools.write16Bits(packet, PORT_START_POSITION, hostItem.getPort());
|
||||
} catch (SizeError e) {
|
||||
throw new InternalError();
|
||||
}
|
||||
// write hostname to Packet
|
||||
BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** HostItem getter.
|
||||
* @return hostItem
|
||||
*/
|
||||
public HostItem getHostItem() {
|
||||
return hostItem;
|
||||
}
|
||||
|
||||
/** totalUp getter.
|
||||
* @return totalUp
|
||||
*/
|
||||
public long getTotalUp() {
|
||||
return totalUp;
|
||||
}
|
||||
|
||||
/** totalDown getter.
|
||||
* @return totalDown
|
||||
*/
|
||||
public long getTotalDown() {
|
||||
return totalDown;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package protocolP2P;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.RequestResponseCode;
|
||||
import localException.TransmissionError;
|
||||
import localException.ProtocolError;
|
||||
import localException.InternalError;
|
||||
import localException.SizeError;
|
||||
import tools.BytesArrayTools;
|
||||
import tools.HostItem;
|
||||
|
||||
/** Representation of payload for load request.
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SizeRequest extends Payload {
|
||||
private String filename;
|
||||
/** Constructor (typically used by the client) with a filename parameter.
|
||||
* @param filename name of the file to download. Must not be empty.
|
||||
*/
|
||||
public SizeRequest(String filename) throws InternalError {
|
||||
super(RequestResponseCode.SIZE_REQUEST);
|
||||
/* assert to help debugging */
|
||||
assert filename.length() != 0 : "Payload size of LoadRequest must not be empty";
|
||||
if (filename.length() == 0) {
|
||||
throw new InternalError();
|
||||
}
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
/** Constructor (typically used by server) with a byte[] parameter containing the Packet received.
|
||||
* @param packet the full Packet received
|
||||
* @throws SizeError
|
||||
* @throws InternalError
|
||||
* @throws ProtocolError
|
||||
* @throws TransmissionError
|
||||
*/
|
||||
protected SizeRequest(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
|
||||
super(packet);
|
||||
/* Read filename */
|
||||
int size = getPayloadSize(packet);
|
||||
filename = BytesArrayTools.readString(packet, PAYLOAD_START_POSITION, size);
|
||||
}
|
||||
|
||||
/** Returns a byte[] containing Packet with padding.
|
||||
* This Packet is still incomplete and should not be send directly.
|
||||
* ProtocolP2PPacket will use this method to generate the complete Packet.
|
||||
* @return Packet with padding
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
int size = PAYLOAD_START_POSITION + filename.length();
|
||||
byte[] packet = new byte[size]; // java initialize all to zero
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
// set Payload size
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// Write filename
|
||||
BytesArrayTools.write(packet, filename, PAYLOAD_START_POSITION);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** filename getter.
|
||||
* @return filename
|
||||
*/
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package protocolP2P;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.RequestResponseCode;
|
||||
import localException.ProtocolError;
|
||||
import localException.InternalError;
|
||||
import localException.SizeError;
|
||||
import localException.TransmissionError;
|
||||
import tools.BytesArrayTools;
|
||||
|
||||
/** Representation of payload for size response.
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SizeResponse extends Payload {
|
||||
private String filename;
|
||||
private long totalSize;
|
||||
static final private int TOTAL_SIZE_POSITION = PAYLOAD_START_POSITION;
|
||||
static final private int FILENAME_POSITION = TOTAL_SIZE_POSITION + 8;
|
||||
|
||||
/** Constructor (typically used by server) with informations about file part to send as parameters.
|
||||
* @param filename name of the file
|
||||
* @param totalSize size of the file
|
||||
* @throws InternalError
|
||||
*/
|
||||
public SizeResponse(String filename, long totalSize) throws InternalError {
|
||||
super(RequestResponseCode.SIZE_RESPONSE);
|
||||
/* asserts to help debugging */
|
||||
assert totalSize >= 0 : "offset cannot be negative";
|
||||
assert filename != null : "filename is required";
|
||||
if (filename == null || totalSize < 0) {
|
||||
throw new InternalError();
|
||||
}
|
||||
this.filename = filename;
|
||||
this.totalSize = totalSize;
|
||||
}
|
||||
|
||||
/** Constructor (typically used by client) with Packet received as parameter.
|
||||
* @param packet the full Packet received
|
||||
* @throws SizeError
|
||||
* @throws InternalError
|
||||
* @throws TransmissionError
|
||||
*/
|
||||
protected SizeResponse(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
|
||||
super(packet);
|
||||
int filenameSize = getPayloadSize(packet) - FILENAME_POSITION + PAYLOAD_START_POSITION;
|
||||
totalSize = BytesArrayTools.readLong(packet, TOTAL_SIZE_POSITION);
|
||||
filename = BytesArrayTools.readString(packet, FILENAME_POSITION, filenameSize);
|
||||
}
|
||||
|
||||
/** Returns a byte[] containing Packet with padding.
|
||||
* This Packet is still incomplete and should not be send directly.
|
||||
* ProtocolP2PPacket will use this method to generate the complete Packet.
|
||||
* @return Packet with padding
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
// compute total size
|
||||
int size = FILENAME_POSITION + filename.length();
|
||||
byte[] packet = new byte[size]; // java initialize all to zero
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
// set Payload size
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// write totalSize to Packet
|
||||
BytesArrayTools.write(packet, TOTAL_SIZE_POSITION, totalSize);
|
||||
// write filename to Packet
|
||||
BytesArrayTools.write(packet, filename, FILENAME_POSITION);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** filename getter.
|
||||
* @return String
|
||||
*/
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/** totalSize getter.
|
||||
* @return totalSize
|
||||
*/
|
||||
public long getTotalSize() {
|
||||
return totalSize;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package protocolP2P;
|
||||
import protocolP2P.Payload;
|
||||
import tools.HostItem;
|
||||
import tools.BytesArrayTools;
|
||||
import localException.SizeError;
|
||||
import localException.InternalError;
|
||||
import localException.TransmissionError;
|
||||
import localException.ProtocolError;
|
||||
|
||||
/** Representation of payload for update ratio.
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class UpdateRatio extends Payload {
|
||||
private HostItem client;
|
||||
private HostItem server;
|
||||
private long dataSize;
|
||||
private static final int DATA_SIZE_POSITION = PAYLOAD_START_POSITION;
|
||||
private static final int SERVER_PORT_START_POSITION = DATA_SIZE_POSITION + 8;
|
||||
private static final int CLIENT_PORT_START_POSITION = SERVER_PORT_START_POSITION + 2;
|
||||
private static final int HOSTNAMES_START_POSITION = CLIENT_PORT_START_POSITION + 2;
|
||||
|
||||
/** Constructor with hostItem (typically used by client)
|
||||
* @param client HostItem of the client application.
|
||||
* @param server HostItem of the server application.
|
||||
* @param dataSize size of data sent.
|
||||
* @throws InternalError
|
||||
*/
|
||||
public UpdateRatio(HostItem client, HostItem server, long dataSize) throws InternalError {
|
||||
super(RequestResponseCode.UPDATE_RATIO);
|
||||
this.client = client;
|
||||
this.server = server;
|
||||
this.dataSize = dataSize;
|
||||
}
|
||||
|
||||
/** Constructor (typically used by tracker) with a byte[] parameter containing the Packet received.
|
||||
* @param packet the full Packet received
|
||||
* @throws SizeError
|
||||
* @throws InternalError
|
||||
* @throws ProtocolError
|
||||
* @throws TransmissionError
|
||||
*/
|
||||
protected UpdateRatio(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError {
|
||||
super(packet);
|
||||
int size = getPayloadSize(packet);
|
||||
dataSize = BytesArrayTools.readLong(packet, DATA_SIZE_POSITION);
|
||||
int portServer = BytesArrayTools.readInt16Bits(packet, SERVER_PORT_START_POSITION);
|
||||
int portClient = BytesArrayTools.readInt16Bits(packet, CLIENT_PORT_START_POSITION);
|
||||
String[] hostnames = BytesArrayTools.readStringArray(packet, HOSTNAMES_START_POSITION, size - HOSTNAMES_START_POSITION + PAYLOAD_START_POSITION, "\n");
|
||||
server = new HostItem(hostnames[0], portServer);
|
||||
client = new HostItem(hostnames[1], portClient);
|
||||
}
|
||||
|
||||
/** Returns a byte[] containing Packet with padding.
|
||||
* This Packet is still incomplete and should not be send directly.
|
||||
* ProtocolP2PPacket will use this method to generate the complete Packet.
|
||||
* @return Packet with padding
|
||||
* @throws InternalError
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String[] hostnames = { server.getHostname(), client.getHostname()};
|
||||
// compute total size
|
||||
int size = HOSTNAMES_START_POSITION + BytesArrayTools.computeStringArraySize(hostnames, "\n");
|
||||
byte[] packet = new byte[size]; // java initialize all to zero
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
// set Payload size
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// write dataSize
|
||||
BytesArrayTools.write(packet, DATA_SIZE_POSITION, dataSize);
|
||||
// write server port to Packet
|
||||
try {
|
||||
BytesArrayTools.write16Bits(packet, SERVER_PORT_START_POSITION, server.getPort());
|
||||
} catch (SizeError e) {
|
||||
throw new InternalError();
|
||||
}
|
||||
// write client port to Packet
|
||||
try {
|
||||
BytesArrayTools.write16Bits(packet, CLIENT_PORT_START_POSITION, client.getPort());
|
||||
} catch (SizeError e) {
|
||||
throw new InternalError();
|
||||
}
|
||||
// write hostnames to Packet
|
||||
BytesArrayTools.write(packet, hostnames, HOSTNAMES_START_POSITION, "\n");
|
||||
return packet;
|
||||
}
|
||||
|
||||
/** Client getter.
|
||||
* @return client
|
||||
*/
|
||||
public HostItem getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/** Server getter
|
||||
* @return server
|
||||
*/
|
||||
public HostItem getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
/** dataSize getter.
|
||||
* @return dataSize
|
||||
*/
|
||||
public long getDataSize() {
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package remoteException;
|
||||
|
||||
import exception.RemoteException;
|
||||
|
||||
public class UnknownHost extends RemoteException {
|
||||
private static final long serialVersionUID = 12L;
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
package serverP2P;
|
||||
import tools.Logger;
|
||||
import tools.LogLevel;
|
||||
import tools.HostItem;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import exception.RemoteException;
|
||||
import exception.LocalException;
|
||||
import protocolP2P.RatioRequest;
|
||||
import protocolP2P.RatioResponse;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.ProtocolP2PPacket;
|
||||
import remoteException.UnknownHost;
|
||||
import remoteException.NotATracker;
|
||||
import localException.InternalError;
|
||||
|
||||
/** Class allowing to keep the tracker informed about ratios
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class RatioWatcher implements Runnable {
|
||||
final static double punishmentFactor = 1.2;
|
||||
protected Logger logger;
|
||||
protected volatile boolean stop;
|
||||
protected long time;
|
||||
protected boolean force;
|
||||
protected HostItem tracker;
|
||||
protected Thread thread;
|
||||
protected Map<HostItem, Double> cachePunishmentProbability = new HashMap<>();
|
||||
protected boolean lock;
|
||||
|
||||
|
||||
/** Constructor
|
||||
* @param logger Logger
|
||||
* @param millis Time interval before recheck
|
||||
* @param tracker HostItem for the tracker
|
||||
*/
|
||||
public RatioWatcher(Logger logger, long millis, HostItem tracker) {
|
||||
assert logger != null : "Logger is null";
|
||||
assert tracker != null : "Tracker is null";
|
||||
this.logger = logger;
|
||||
time = millis;
|
||||
this.tracker = tracker;
|
||||
lock = false;
|
||||
}
|
||||
|
||||
|
||||
/** Runnable implementation */
|
||||
public void run() {
|
||||
writeLog("Ratio watcher started : delay " + time + " milliseconds.", LogLevel.Info);
|
||||
while(!stop) {
|
||||
try {
|
||||
clean();
|
||||
Thread.sleep(time);
|
||||
} catch(InterruptedException e) {
|
||||
writeLog("Ratio watcher interrupted", LogLevel.Info);
|
||||
setStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Invalidate the cache by cleaning all hashmaps
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected synchronized void clean() throws InterruptedException{
|
||||
while(lock) {
|
||||
this.wait();
|
||||
}
|
||||
lock = true;
|
||||
cachePunishmentProbability.clear();
|
||||
lock = false;
|
||||
this.notifyAll();
|
||||
}
|
||||
|
||||
|
||||
/** Get Up-ratio for an applications
|
||||
* @param application HostItem of the application
|
||||
* @return Punishment Probability
|
||||
* @throws UnknownHost
|
||||
*/
|
||||
protected synchronized double getPunishmentProbability(HostItem application) throws InternalError, UnknownHost {
|
||||
try {
|
||||
while(lock) {
|
||||
this.wait();
|
||||
}
|
||||
lock = true;
|
||||
if (!cachePunishmentProbability.containsKey(application)) {
|
||||
// update if not in cache
|
||||
try {
|
||||
ProtocolP2PPacket<?> p = createProtocolP2PPacket(new RatioRequest(application));
|
||||
p.sendRequest(getTrackerSocket());
|
||||
Payload resp = p.receiveResponse().getPayload();
|
||||
if (!(resp instanceof RatioResponse)) {
|
||||
throw new InternalError();
|
||||
}
|
||||
RatioResponse rresp = (RatioResponse)resp;
|
||||
if (!rresp.getHostItem().equals(application)) {
|
||||
writeLog("Ratio response host is not the expected one. Expected : "
|
||||
+ application + ". Received : " + rresp.getHostItem(), LogLevel.Debug);
|
||||
throw new InternalError();
|
||||
}
|
||||
long up = rresp.getTotalUp();
|
||||
long down = rresp.getTotalDown();
|
||||
assert punishmentFactor > 1 : "The punishment factor must be greater than 1";
|
||||
if (down == 0 || (punishmentFactor * up) >= down) {
|
||||
cachePunishmentProbability.put(application, Double.valueOf(0));
|
||||
} else {
|
||||
cachePunishmentProbability.put(application, Double.valueOf((down - up)/(down * punishmentFactor)));
|
||||
}
|
||||
} catch (UnknownHost e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new InternalError();
|
||||
} catch (LocalException e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
throw new InternalError();
|
||||
} catch (RemoteException e) {
|
||||
writeLog(e, LogLevel.Error);
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
double ret = cachePunishmentProbability.get(application);
|
||||
lock = false;
|
||||
this.notifyAll();
|
||||
return ret;
|
||||
} catch (InterruptedException e) {
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/** Ask the thread to stop
|
||||
*/
|
||||
public void setStop() {
|
||||
stop = true;
|
||||
if (thread != null) {
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Set thread
|
||||
* @param thread Thread
|
||||
*/
|
||||
public void setThread(Thread thread) {
|
||||
this.thread = thread;
|
||||
}
|
||||
|
||||
/** Create packets
|
||||
* @param payload Payload
|
||||
*/
|
||||
protected abstract < T extends Payload > ProtocolP2PPacket<?> createProtocolP2PPacket(T payload);
|
||||
|
||||
/** Tracker socket getter
|
||||
* @return tracker socket
|
||||
*/
|
||||
protected abstract Object getTrackerSocket();
|
||||
|
||||
/** Closes tracker socket
|
||||
*/
|
||||
protected abstract void closeTrackerSocket();
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package serverP2P;
|
||||
import tools.Logger;
|
||||
import tools.LogLevel;
|
||||
import protocolP2P.ProtocolP2PPacket;
|
||||
import protocolP2P.ProtocolP2PPacketTCP;
|
||||
import protocolP2P.Payload;
|
||||
import tools.HostItem;
|
||||
import serverP2P.RatioWatcher;
|
||||
|
||||
/** Class allowing to keep the tracker informed about file list (TCP impl.)
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RatioWatcherTCP extends RatioWatcher {
|
||||
|
||||
/** Constructor
|
||||
* @param logger Logger
|
||||
* @param millis Time interval before recheck
|
||||
* @param tracker HostItem for the tracker
|
||||
*/
|
||||
public RatioWatcherTCP(Logger logger, long millis, HostItem tracker) {
|
||||
super(logger, millis, tracker);
|
||||
assert logger != null : "Logger is null";
|
||||
assert tracker != null : "Tracker is null";
|
||||
}
|
||||
|
||||
/** Implementation of writeLog
|
||||
* @param text Text to log
|
||||
* @param logLevel level of logging
|
||||
*/
|
||||
protected void writeLog(String text, LogLevel logLevel) {
|
||||
logger.writeTCP(text, logLevel);
|
||||
}
|
||||
|
||||
/** Implementation of writeLog
|
||||
* @param e exception to log
|
||||
* @param logLevel level of logging
|
||||
*/
|
||||
protected void writeLog(Exception e, LogLevel logLevel) {
|
||||
logger.writeTCP(e, logLevel);
|
||||
}
|
||||
|
||||
/** Create packets
|
||||
* @param payload Payload
|
||||
*/
|
||||
protected < T extends Payload > ProtocolP2PPacket<T> createProtocolP2PPacket(T payload) {
|
||||
return (ProtocolP2PPacket<T>)new ProtocolP2PPacketTCP<T>(payload);
|
||||
}
|
||||
|
||||
/** Tracker socket getter
|
||||
* @return tracker socket
|
||||
*/
|
||||
protected Object getTrackerSocket() {
|
||||
return tracker.getTCPSocket();
|
||||
}
|
||||
|
||||
/** Closes tracker socket
|
||||
*/
|
||||
protected void closeTrackerSocket() {
|
||||
tracker.closeTCPSocket();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package serverP2P;
|
||||
import tools.Logger;
|
||||
import tools.LogLevel;
|
||||
import protocolP2P.ProtocolP2PPacket;
|
||||
import protocolP2P.ProtocolP2PPacketUDP;
|
||||
import protocolP2P.Payload;
|
||||
import tools.HostItem;
|
||||
import serverP2P.RatioWatcher;
|
||||
|
||||
/** Class allowing to keep the tracker informed about file list (UDP impl.)
|
||||
* @author Louis Royer
|
||||
* @author Flavien Haas
|
||||
* @author JS Auge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RatioWatcherUDP extends RatioWatcher {
|
||||
|
||||
/** Constructor
|
||||
* @param logger Logger
|
||||
* @param millis Time interval before recheck
|
||||
* @param tracker HostItem for the tracker
|
||||
*/
|
||||
public RatioWatcherUDP(Logger logger, long millis, HostItem tracker) {
|
||||
super(logger, millis, tracker);
|
||||
assert logger != null : "Logger is null";
|
||||
assert tracker != null : "Tracker is null";
|
||||
}
|
||||
|
||||
/** Implementation of writeLog
|
||||
* @param text Text to log
|
||||
* @param logLevel level of logging
|
||||
*/
|
||||
protected void writeLog(String text, LogLevel logLevel) {
|
||||
logger.writeUDP(text, logLevel);
|
||||
}
|
||||
|
||||
/** Implementation of writeLog
|
||||
* @param e exception to log
|
||||
* @param logLevel level of logging
|
||||
*/
|
||||
protected void writeLog(Exception e, LogLevel logLevel) {
|
||||
logger.writeUDP(e, logLevel);
|
||||
}
|
||||
|
||||
/** Create packets
|
||||
* @param payload Payload
|
||||
*/
|
||||
protected < T extends Payload > ProtocolP2PPacket<T> createProtocolP2PPacket(T payload) {
|
||||
return (ProtocolP2PPacket<T>)new ProtocolP2PPacketUDP<T>(payload);
|
||||
}
|
||||
|
||||
/** Tracker socket getter
|
||||
* @return tracker socket
|
||||
*/
|
||||
protected Object getTrackerSocket() {
|
||||
return tracker.getUDPSocket();
|
||||
}
|
||||
|
||||
/** Closes tracker socket
|
||||
*/
|
||||
protected void closeTrackerSocket() {
|
||||
tracker.closeUDPSocket();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue