diff --git a/.idea/misc.xml b/.idea/misc.xml index 4258c62fd9edaffc241e79c34ec36a478505f4f1..a57100aa2d4f94da008f6020697aa140f169858e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -7,6 +7,7 @@ <option value="$PROJECT_DIR$/pom.xml" /> </list> </option> + <option name="workspaceImportForciblyTurnedOn" value="true" /> </component> <component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="18" project-jdk-type="JavaSDK"> <output url="file://$PROJECT_DIR$/out" /> diff --git a/internetworking_ws23.zip b/internetworking_ws23.zip deleted file mode 100644 index d493d9093c39214694934dc9d5377a8b888536fa..0000000000000000000000000000000000000000 Binary files a/internetworking_ws23.zip and /dev/null differ diff --git a/pom.xml b/pom.xml index 2c1b211df7ed3c99736c5a81e7eda15f00e4f229..121aeddd2315326758275a224d34debe8f2e379d 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,17 @@ <artifactId>byte-buddy</artifactId> <version>1.14.6</version> </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util-ajax</artifactId> + <version>9.4.46.v20220331</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>RELEASE</version> + <scope>test</scope> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/src/main/java/apps/CPServer.java b/src/main/java/apps/CPServer.java index 071a8eddca62f9ce581a813fd05d20532db66703..bfa604979a3cd0839cf4df88f266a7916ee572d5 100644 --- a/src/main/java/apps/CPServer.java +++ b/src/main/java/apps/CPServer.java @@ -10,6 +10,10 @@ import java.io.IOException; public class CPServer { protected static final int SERVER_PORT = 3027; + public static void printMessage(String cookie, int messageId, String message) { + //printing recieved message on screen + System.out.println("Received message: " + message + " id: " + messageId + " with cookie: " + cookie); + } public static void main(String[] args) { // Set up the virtual link protocol PhyProtocol phy = new PhyProtocol(SERVER_PORT); diff --git a/src/main/java/cp/CPCommandMessage.java b/src/main/java/cp/CPCommandMessage.java index a8f71f49fd0b61cc1c189fe26bd4b65c8f0f94a5..7a694699f5dc9ec6842698088ba22bc070efd910 100644 --- a/src/main/java/cp/CPCommandMessage.java +++ b/src/main/java/cp/CPCommandMessage.java @@ -7,11 +7,20 @@ import java.util.zip.Checksum; public class CPCommandMessage extends CPMsg{ private int currentMessageId; + private String command; + private String cookie; + private String message; protected static final String HEADER = "command"; public CPCommandMessage() { } + public boolean isCommandMessage() { + // Check if the message is a command message based on the specified format + // You may need to adjust this based on the actual structure of your message + return (this.data != null && this.data.startsWith("cp") && this.data.contains("command")); + } + public CPCommandMessage create(String cookie, String command, String message, int messageIdCount){ @@ -31,12 +40,32 @@ public class CPCommandMessage extends CPMsg{ str.append(calcCRC(this.data)); //calculates the crc and adds it to the Frame this.data = str.toString(); //builds the Frame again, but with the attached checksum + this.command = command; + this.cookie = cookie; + this.message = message; return this; } + public String getCommand() { + return command; + } + + public String getCookie() { + return cookie; + } + + public String getMessage() { + return message; + } + + //returns the unique id of the message public int getMessageId(){ return currentMessageId; } + + public long getTTL() { + return 0; + } } diff --git a/src/main/java/cp/CPCommandResponseMessage.java b/src/main/java/cp/CPCommandResponseMessage.java index f4806303f6aab1ec47c827d4655a7b56cafa56f1..a68092a4f266f0adb882cb3a4b59b3332d958c16 100644 --- a/src/main/java/cp/CPCommandResponseMessage.java +++ b/src/main/java/cp/CPCommandResponseMessage.java @@ -20,6 +20,9 @@ public class CPCommandResponseMessage extends CPMsg{ return currentMessageId; } + + + @Override protected Msg parse(String sentence) throws IWProtocolException { diff --git a/src/main/java/cp/CPProtocol.java b/src/main/java/cp/CPProtocol.java index 88d1055cd9d9b6d52cc9c8927b8ba9838e59056c..79ad627f3f503a19d929be2cf0723f03626ff9e2 100644 --- a/src/main/java/cp/CPProtocol.java +++ b/src/main/java/cp/CPProtocol.java @@ -1,5 +1,6 @@ package cp; +import apps.CPServer; import core.*; import exceptions.*; import phy.*; @@ -83,7 +84,7 @@ public class CPProtocol extends Protocol { while(receving){ //1.2: 2 b - CPMsg cpmsg = new CPCommandResponseMessage(); + CPCommandMessage cpmsg = new CPCommandMessage(); try { in = this.PhyProto.receive(CP_TIMEOUT); @@ -91,6 +92,8 @@ public class CPProtocol extends Protocol { //1.2: 2 b in = cpmsg.parse(in.getData()); + new CommandMessageProcessor().processCommandMessage(cpmsg); + } catch (Exception e) { System.out.println(e.getMessage()); continue; @@ -113,6 +116,40 @@ public class CPProtocol extends Protocol { return in; } + private class CommandMessageProcessor { + public void processCommandMessage(CPCommandMessage cmdMsg) throws Exception { + String command = cmdMsg.getCommand(); + String cookie = cmdMsg.getCookie(); + int messageId = cmdMsg.getMessageId(); + String message = cmdMsg.getMessage(); + long TTL = cmdMsg.getTTL(); + + switch (command) { + case "status": + processStatusCommand(cookie, messageId, Integer.parseInt(command), TTL); + break; + case "print": + processPrintCommand(cookie, messageId, message); + break; + default: + System.out.println("Unknown command: " + command); + break; + } + } + + private void processStatusCommand(String cookie, int messageId, int processedCommands, long sessionTTL) throws Exception { + CPStatusResponseMessage statusResponse = new CPStatusResponseMessage(); + statusResponse.create(cookie, messageId, processedCommands, sessionTTL); + + PhyProto.send(statusResponse.getData(), CPProtocol.this.PhyConfig); + } + + private void processPrintCommand(String cookie, int messageId, String message) { + //print on server console + CPServer.printMessage(cookie, messageId, message); + } + } + public void cookieProcesing(PhyConfiguration config, CPCookie cookie) throws IWProtocolException, IOException { @@ -168,4 +205,8 @@ public class CPProtocol extends Protocol { public static int getMaxId(){ return MAX_ID; } + + public PhyProtocol getPhyProtocol(){ + return this.PhyProto; + } } diff --git a/src/main/java/cp/CPStatusResponseMessage.java b/src/main/java/cp/CPStatusResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..6c41202a577727f720557d9ef48181516a90a2a9 --- /dev/null +++ b/src/main/java/cp/CPStatusResponseMessage.java @@ -0,0 +1,35 @@ +package cp; + +public class CPStatusResponseMessage extends CPMsg { + private int processedCommands; + private long sessionTTL; + + public CPStatusResponseMessage() { + } + + public void create(String cookie, int messageId, int processedCommands, long sessionTTL) { + this.processedCommands = processedCommands; + this.sessionTTL = sessionTTL; + + StringBuilder str = new StringBuilder(); + str.append("status").append(' '); + str.append(messageId).append(' '); + str.append(cookie).append(' '); + str.append(processedCommands).append(' '); + str.append(sessionTTL).append(' '); + + super.create(str.toString()); + + this.data = str.toString(); + str.append(calcCRC(this.data)); + this.data = str.toString(); + } + + public int getProcessedCommands() { + return processedCommands; + } + + public long getSessionTTL() { + return sessionTTL; + } +} \ No newline at end of file diff --git a/src/test/java/CPPrintCommand/CPServerTest.java b/src/test/java/CPPrintCommand/CPServerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dc6abe6755d3e6b5ff0c2f6a6a1b805fe9b0a6cd --- /dev/null +++ b/src/test/java/CPPrintCommand/CPServerTest.java @@ -0,0 +1,52 @@ +package CPPrintCommand; +import apps.CPServer; +import cp.CPCommandMessage; +import cp.CPProtocol; +import exceptions.IWProtocolException; +import org.junit.jupiter.api.Test; +import phy.PhyConfiguration; +import phy.PhyProtocol; + +import java.io.IOException; + +import static org.mockito.Mockito.*; + +public class CPServerTest { + + @Test + void testProcessWellFormedPrintCommand() throws IOException, IWProtocolException { + + PhyProtocol mockPhyProtocol = mock(PhyProtocol.class); + PhyConfiguration mockPhyConfig = mock(PhyConfiguration.class); + CPProtocol cpProtocol = mock(CPProtocol.class); + + // Set up print command message + CPCommandMessage printCommand = new CPCommandMessage(); + printCommand.create("validCookie", "print", "Hello, Server!", 1); + + // Mock the behavior getPhyProtocol() to return the mockPhyProtocol + when(cpProtocol.getPhyProtocol()).thenReturn(mockPhyProtocol); + + CPServer.printMessage("validCookie", 1, "Hello, Server!"); + verify(mockPhyProtocol).send(eq(printCommand.getData()), eq(mockPhyConfig)); + } + + @Test + void testProcessMalformedPrintCommand() throws IOException, IWProtocolException { + + PhyProtocol mockPhyProtocol = mock(PhyProtocol.class); + PhyConfiguration mockPhyConfig = mock(PhyConfiguration.class); + + CPProtocol cpProtocol = mock(CPProtocol.class); + + CPCommandMessage malformedPrintCommand = new CPCommandMessage(); + malformedPrintCommand.create("invalidOrExpiredCookie", "print", "Hello, Server!", 2); + + // Mock the behavior getPhyProtocol() to return the mockPhyProtocol + when(cpProtocol.getPhyProtocol()).thenReturn(mockPhyProtocol); + + CPServer.printMessage("invalidOrExpiredCookie", 2, "Hello, Server!"); + + verify(mockPhyProtocol, never()).send(eq(malformedPrintCommand.getData()), eq(mockPhyConfig)); + } +} \ No newline at end of file