diff --git a/src/main/java/java/src/Request/Data/OnlineStateNotificationRequest.java b/src/main/java/java/src/Request/Data/OnlineStateNotificationRequest.java new file mode 100644 index 0000000..3bc6018 --- /dev/null +++ b/src/main/java/java/src/Request/Data/OnlineStateNotificationRequest.java @@ -0,0 +1,31 @@ +package java.src.Request.Data; + +import java.src.FileReaderWriter.FileReaderWriter; +import java.src.Peers.EOnlineState; +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; + +public record OnlineStateNotificationRequest(Peer sender, Peer receiver) implements Requestable { + + @Override + public EDataType getType() { + return EDataType.OnlineStateNotification; + } + + @Override + public Peer getSender() { + return sender; + } + + @Override + public Peer getReceiver() { + return receiver; + } + + @Override + public void execute(SendingQueue sendingQueue) { + FileReaderWriter.updatePeerList(new Peer(sender.ipAddress(), sender.port(), null, EOnlineState.Online)); + } + +} diff --git a/src/main/java/java/src/Request/Data/OnlineStateRequestRequest.java b/src/main/java/java/src/Request/Data/OnlineStateRequestRequest.java new file mode 100644 index 0000000..708fb3f --- /dev/null +++ b/src/main/java/java/src/Request/Data/OnlineStateRequestRequest.java @@ -0,0 +1,31 @@ +package java.src.Request.Data; + +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; +import java.src.Sending.Data.OnlineStateNotification; + +public record OnlineStateRequestRequest(Peer sender, Peer receiver) implements Requestable { + + @Override + public EDataType getType() { + return EDataType.OnlineStateRequest; + } + + @Override + public Peer getSender() { + return sender; + } + + @Override + public Peer getReceiver() { + return receiver; + } + + @Override + public void execute(SendingQueue sendingQueue) { + // This is receiver and wants to notify the sender about its online state. + sendingQueue.add(new OnlineStateNotification(receiver, sender)); + } + +} diff --git a/src/main/java/java/src/Request/Data/PublishFileNameNotificationRequest.java b/src/main/java/java/src/Request/Data/PublishFileNameNotificationRequest.java new file mode 100644 index 0000000..f9ad6e3 --- /dev/null +++ b/src/main/java/java/src/Request/Data/PublishFileNameNotificationRequest.java @@ -0,0 +1,57 @@ +package java.src.Request.Data; + +import java.io.FileReader; +import java.io.FileWriter; +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONTokener; + +public record PublishFileNameNotificationRequest(Peer sender, Peer receiver, String fileName) implements Requestable { + + @Override + public EDataType getType() { + return EDataType.PublishFileNameNotification; + } + + @Override + public Peer getSender() { + return sender; + } + + @Override + public Peer getReceiver() { + return receiver; + } + + @Override + public void execute(SendingQueue sendingQueue) { + String senderIpPort = sender.ipAddress() + ":" + sender.port(); + + try { + FileReader reader = new FileReader("./src/main/resources/peers.json"); + // Parse JSON file into a JSONObject + JSONObject peerFileAsJSONObject = new JSONObject(new JSONTokener(reader)); + reader.close(); + JSONArray peers = peerFileAsJSONObject.getJSONArray("peers"); + // Goes through json array and inserts new file at element that matches ip and port. + peers.forEach((peer) -> { + JSONObject peerAsJSONObject = (JSONObject)peer; + if ((peerAsJSONObject).getString("ipPort").equals(senderIpPort)) { + peerAsJSONObject.append("files", fileName); + } + }); + + FileWriter writer = new FileWriter("./src/main/resources/peers.json"); + // Writes the modified object back to the file. + writer.write(peerFileAsJSONObject.toString()); + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/java/src/Request/Data/PullFileListRequestRequest.java b/src/main/java/java/src/Request/Data/PullFileListRequestRequest.java new file mode 100644 index 0000000..d3ac842 --- /dev/null +++ b/src/main/java/java/src/Request/Data/PullFileListRequestRequest.java @@ -0,0 +1,30 @@ +package java.src.Request.Data; + +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; +import java.src.Sending.Data.PullFileListRequest; + +public record PullFileListRequestRequest(Peer sender, Peer receiver) implements Requestable { + + @Override + public EDataType getType() { + return EDataType.PullFileListRequest; + } + + @Override + public Peer getSender() { + return sender; + } + + @Override + public Peer getReceiver() { + return receiver; + } + + @Override + public void execute(SendingQueue sendingQueue) { + // Do nothing since functionality is not necessary. + } + +} diff --git a/src/main/java/java/src/Request/Data/PullFileRequestRequest.java b/src/main/java/java/src/Request/Data/PullFileRequestRequest.java new file mode 100644 index 0000000..7ce87b4 --- /dev/null +++ b/src/main/java/java/src/Request/Data/PullFileRequestRequest.java @@ -0,0 +1,40 @@ +package java.src.Request.Data; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; + +public record PullFileRequestRequest(Peer sender, Peer receiver, String fileName) implements Requestable { + + @Override + public EDataType getType() { + return EDataType.PullFileRequest; + } + + @Override + public Peer getSender() { + return sender; + } + + @Override + public Peer getReceiver() { + return receiver; + } + + @Override + public void execute(SendingQueue sendingQueue) { + // TODO read filelist with paths and read file at path. + // Write content to String and send data via sendingqueue to requesting peer + // StringBuilder stringBuilder = new StringBuilder(); + // try (BufferedReader reader = new BufferedReader(new FileReader())) { + // String line; + // while ((line = reader.readLine()) != null) { + // stringBuilder.append(line).append("\n"); + // } + // } + // return stringBuilder.toString(); + } + +} diff --git a/src/main/java/java/src/Request/Data/Requestable.java b/src/main/java/java/src/Request/Data/Requestable.java new file mode 100644 index 0000000..19d8559 --- /dev/null +++ b/src/main/java/java/src/Request/Data/Requestable.java @@ -0,0 +1,12 @@ +package java.src.Request.Data; + +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; + +public interface Requestable { + public EDataType getType(); + public Peer getSender(); + public Peer getReceiver(); + public void execute(SendingQueue sendingQueue); +} diff --git a/src/main/java/java/src/Request/Data/SendFileReplyRequest.java b/src/main/java/java/src/Request/Data/SendFileReplyRequest.java new file mode 100644 index 0000000..e4df05f --- /dev/null +++ b/src/main/java/java/src/Request/Data/SendFileReplyRequest.java @@ -0,0 +1,30 @@ +package java.src.Request.Data; + +import java.src.Peers.Peer; +import java.src.Sending.SendingQueue; +import java.src.Sending.Data.EDataType; + +public record SendFileReplyRequest(Peer sender, Peer receiver, String fileName, String fileContent) implements Requestable { + + @Override + public EDataType getType() { + return EDataType.SendFileReply; + } + + @Override + public Peer getSender() { + return sender; + } + + @Override + public Peer getReceiver() { + return receiver; + } + + @Override + public void execute(SendingQueue sendingQueue) { + System.out.println(fileName); + // TODO method that takes string and returns first 20byte....last 20byte + } + +} diff --git a/src/main/java/java/src/Request/RequestExecuterThread.java b/src/main/java/java/src/Request/RequestExecuterThread.java new file mode 100644 index 0000000..e547a6a --- /dev/null +++ b/src/main/java/java/src/Request/RequestExecuterThread.java @@ -0,0 +1,102 @@ +/** + * @author Aaron Moser + */ + +package java.src.Request; + +import java.src.Terminatable; +import java.src.FileReaderWriter.FileReaderWriter; +import java.src.FileReaderWriter.FileReaderWriter.EUpdated; +import java.src.Peers.EOnlineState; +import java.src.Peers.Peer; +import java.src.Receiving.ReceivedData; +import java.src.Receiving.ReceivingQueue; +import java.src.Request.Data.OnlineStateNotificationRequest; +import java.src.Request.Data.OnlineStateRequestRequest; +import java.src.Request.Data.PublishFileNameNotificationRequest; +import java.src.Request.Data.PullFileListRequestRequest; +import java.src.Request.Data.PullFileRequestRequest; +import java.src.Request.Data.Requestable; +import java.src.Request.Data.SendFileReplyRequest; +import java.src.Sending.SendingQueue; + +import org.json.JSONObject; + +public class RequestExecuterThread extends Thread implements Terminatable { + + private boolean requestExecuterThreadRunning = true; + + private SendingQueue sendingQueue = null; + private ReceivingQueue receivingQueue = null; + + public RequestExecuterThread(SendingQueue sendingQueue, ReceivingQueue receivingQueue) { + this.sendingQueue = sendingQueue; + this.receivingQueue = receivingQueue; + } + + @Override + public void run() { + while (requestExecuterThreadRunning) { + try { + ReceivedData receivedData = receivingQueue.take(); + + JSONObject receivedDataAsJSONObject = new JSONObject(receivedData.data()); + + Requestable request = toRequestable(receivedDataAsJSONObject); + if (request != null) { + request.execute(sendingQueue); + } + + } catch (InterruptedException e) { + System.out.println("Error, receiving queue was interrupted. Terminating (this) request executer thread.."); + this.terminate(); + } + } + } + + public void terminate() { + requestExecuterThreadRunning = false; + } + + private static Requestable toRequestable(JSONObject receivedData) { + if (receivedData.has("onlineState")) { + String onlineState = receivedData.getString("onlineState"); + switch (onlineState) { + case "": { + return new OnlineStateNotificationRequest(parseIPPortField(receivedData), FileReaderWriter.getThisPeer(EUpdated.NotUpdated)); + } + case "online": { + return new OnlineStateRequestRequest(parseIPPortField(receivedData), FileReaderWriter.getThisPeer(EUpdated.NotUpdated)); + } + default: { + System.err.println("Unknown online state."); + return null; + } + } + } + if (receivedData.has("pullFileList")) { + return new PullFileListRequestRequest(parseIPPortField(receivedData), FileReaderWriter.getThisPeer(EUpdated.Updated)); + } + if (receivedData.has("publishFileName")) { + String fileName = receivedData.getString("publishFileName"); + return new PublishFileNameNotificationRequest(parseIPPortField(receivedData), FileReaderWriter.getThisPeer(EUpdated.NotUpdated), fileName); + } + if (receivedData.has("pullFile")) { + String fileName = receivedData.getString("pullFile"); + return new PullFileRequestRequest(parseIPPortField(receivedData), FileReaderWriter.getThisPeer(EUpdated.NotUpdated), fileName); + } + if (receivedData.has("sendFile")) { + String fileContent = receivedData.getString("sendFile"); + String fileName = receivedData.getString("fileName"); + + return new SendFileReplyRequest(parseIPPortField(receivedData), FileReaderWriter.getThisPeer(EUpdated.NotUpdated), fileName, fileContent); + } + return null; + } + + private static Peer parseIPPortField(JSONObject receivedData) { + String ipPort = receivedData.getString("ipPort"); + String[] ipPortParts = ipPort.split(":"); + return new Peer(ipPortParts[0], Integer.parseInt(ipPortParts[1]), null, EOnlineState.Online); + } +}