diff --git a/src/Dstore.java b/src/Dstore.java index 9998daf293ae1cf942d769e77fdae3fe934786a7..dc6ba4e05cffea366495179c9e005507ab416721 100644 --- a/src/Dstore.java +++ b/src/Dstore.java @@ -102,15 +102,26 @@ public class Dstore { String filename = tokens[1]; int filesize = Integer.parseInt(tokens[2]); - // read data and store the file - byte[] data = new byte[filesize]; - client.getInputStream().readNBytes(data, 0, filesize); - FileOutputStream o = new FileOutputStream(dstore.getFile_folder() + - "/" + filename); - o.write(data); - o.flush(); - o.close(); - dstore.getFiles().add(filename); + long limit = System.currentTimeMillis() + dstore.getTimeout(); + boolean finished = false; + + while(!finished && System.currentTimeMillis() < limit) { + // read data and store the file + byte[] data = new byte[filesize]; + client.getInputStream().readNBytes(data, 0, filesize); + FileOutputStream o = new FileOutputStream(dstore.getFile_folder() + + "/" + filename); + o.write(data); + o.flush(); + o.close(); + dstore.getFiles().add(filename); + finished = true; + } + + if(!finished) { + System.out.println("ERROR: time expired"); + return; + } PrintWriter r = new PrintWriter(new OutputStreamWriter(controllerSocket.getOutputStream())); r.println("STORE_ACK " + filename + " " + dstore.getPort()); @@ -120,27 +131,35 @@ public class Dstore { System.out.println("Arguments don;t match the STORE operation"); } break; + case "LOAD_DATA": - try { + + if(tokens.length != 2) { + System.out.println("Arguments don't match in LOAD operation"); + } else { String filename = tokens[1]; - if (dstore.getFiles().contains(filename)) { - File file = new File(dstore.getFile_folder() + "/" + filename); - FileInputStream i = new FileInputStream(file); - int n; - while ((n = i.read()) != -1) { - client.getOutputStream().write(n); + + try { + if (dstore.getFiles().contains(filename)) { + File file = new File(dstore.getFile_folder() + "/" + filename); + FileInputStream i = new FileInputStream(file); + int n; + while ((n = i.read()) != -1) { + client.getOutputStream().write(n); + } + i.close(); + } else { + done = true; + client.close(); } - i.close(); - } else { - done = true; - client.close(); + Server.pos = 0; + } catch (Exception ingored) { + res.println("RELOAD " + filename); + res.flush(); } - - } catch (IndexOutOfBoundsException e) { - - System.out.println("Arguments don't match in LOAD operation"); } + break; default: System.out.println("Unknown command"); @@ -180,7 +199,7 @@ public class Dstore { dstore.getFiles().remove(filename); res.println("REMOVE_ACK " + filename); } else { - res.println("ERROR_FILE_DOES_NOT_EXIST"); + res.println("ERROR_FILE_DOES_NOT_EXIST " + filename); } res.flush(); diff --git a/src/Server.java b/src/Server.java index b321b30a0d36b486b6f02c4e703ea28432919a12..9ca3fb95c7fc977b9c2e5792d681b56e59421c78 100644 --- a/src/Server.java +++ b/src/Server.java @@ -1,11 +1,13 @@ import java.io.*; import java.net.*; +import java.nio.CharBuffer; import java.util.*; public class Server { private final Controller controller; public static FileSystem fileSystem; + public static int pos; public Server(Controller controller, FileSystem fileSystem) { this.controller = controller; @@ -15,6 +17,7 @@ public class Server { public void handleClient(Socket client) throws IOException { OutputStream out = client.getOutputStream(); InputStream in = client.getInputStream(); + pos = 0; BufferedReader req = new BufferedReader(new InputStreamReader(in)); PrintWriter res = new PrintWriter(new OutputStreamWriter(out)); @@ -41,21 +44,27 @@ public class Server { } else if (command.equals("REMOVE_ACK")){ handleRemoveACK(tokens); } else { - System.out.println("Unkown command"); + System.out.println("Unknown command"); } } else { switch (command) { case "STORE" -> handleStore(client, tokens); case "LOAD" -> handleLoad(client, tokens); + case "RELOAD" -> handleReload(client, tokens); case "REMOVE" -> handleRemove(client, tokens); case "LIST" -> handleList(client); - default -> System.out.println("Command unknown"); + default -> System.out.println("Unknown command"); } } } } } + /** + * @param client + * @param tokens gets the filename and the filesize + * @throws IOException + */ private void handleStore(Socket client, String[] tokens) throws IOException { try { @@ -63,7 +72,16 @@ public class Server { int filesize = Integer.parseInt(tokens[2]); PrintWriter res = new PrintWriter(new OutputStreamWriter(client.getOutputStream())); + if(fileSystem.getStore().containsKey(filename)) { + res.println("ERROR_FILE_ALREADY_EXISTS"); + res.flush(); + return; + } + + // update index to store in progress fileSystem.addIndex(filename, "store in progress"); + + // select R Dstores and create a string of all of their endpoints String msg = ""; int i = 0; List<FSStore> temp = new ArrayList<>(); @@ -73,13 +91,18 @@ public class Server { break; } + // in case all the ACK are received keep in memory all the dstores temp.add(fileSystem.getDstores().get(port)); - msg = fileSystem.getDstores().get(port).getPublicPort() + msg + " "; + + // construct the message + msg = fileSystem.getDstores().get(port).getPublicPort() + " " + msg; + i++; } res.println("STORE_TO " + msg); res.flush(); + // check if all the dstores have sent an ACK and send appropriate messages boolean done = false; long limit = System.currentTimeMillis() + controller.getTimeout(); @@ -88,12 +111,15 @@ public class Server { done = true; fileSystem.addIndex(filename, "store complete"); fileSystem.addStore(filename, temp); + fileSystem.addFileSize(filename, filesize); res.println("STORE_COMPLETE"); res.flush(); } } + // if the dstores didn't send a STORE_ACK in the timeout => store failed if(!done) { + fileSystem.removeIndex(filename); System.out.println(filename + " failed to upload"); } @@ -107,12 +133,41 @@ public class Server { try { String filename = tokens[1]; PrintWriter res = new PrintWriter(new OutputStreamWriter(client.getOutputStream())); + if(!fileSystem.getStore().containsKey(filename)) { + res.println("ERROR_FILE_DOES_NOT_EXIST"); + } else { + // select a Dstore from there and give an appropriate error if all Dstores fail + res.println("LOAD_FROM " + fileSystem.getStore().get(filename).get(pos).getPublicPort() + + " " + fileSystem.getFileSizes().get(filename)); + } + res.flush(); + } catch (IndexOutOfBoundsException e) { + System.out.println("Arguments don't match in LOAD operation"); + } + } + + private void handleReload(Socket client, String[] tokens) throws IOException { + pos = pos + 1; + PrintWriter res = new PrintWriter(new OutputStreamWriter(client.getOutputStream())); + + try { + String filename = tokens[1]; if(!fileSystem.getStore().containsKey(filename)) { + pos = 0; res.println("ERROR_FILE_DOES_NOT_EXIST"); } else { + + if(pos == controller.getR()) { + pos = 0; + res.println("ERROR_LOAD"); + res.flush(); + return; + } + // select a Dstore from there and give an appropriate error if all Dstores fail - res.println("LOAD_FROM " + fileSystem.getStore().get(filename).get(0).getPublicPort()); + res.println("LOAD_FROM " + fileSystem.getStore().get(filename).get(pos).getPublicPort() + + " " + fileSystem.getFileSizes().get(filename)); } res.flush(); @@ -130,7 +185,6 @@ public class Server { System.out.println(fileSystem.index.get(filename)); if(!fileSystem.store.containsKey(filename)) { - System.out.println("Entered in Controller request"); PrintWriter res = new PrintWriter(new OutputStreamWriter(client.getOutputStream())); res.println("ERROR_FILE_DOES_NOT_EXIST"); res.flush(); @@ -153,6 +207,7 @@ public class Server { done = true; fileSystem.addIndex(filename, "remove complete"); fileSystem.getStore().remove(filename); + fileSystem.getFileSizes().remove(filename); res.println("REMOVE_COMPLETE"); res.flush(); }