diff --git a/app/src/main/java/lightcontainer/App.java b/app/src/main/java/lightcontainer/App.java index e5909b5..3808952 100644 --- a/app/src/main/java/lightcontainer/App.java +++ b/app/src/main/java/lightcontainer/App.java @@ -61,13 +61,13 @@ public class App { protocolRep.addReader(new FilelistRule(protocolRep)); protocolRep.addReader(new SavefileRule(protocolRep, repositoryStorage.getStoragePath())); protocolRep.addReader(new SendOkRule(protocolRep)); - protocolRep.addReader(new SendErrorRule(protocolRep, repositoryStorage.getStoragePath())); + protocolRep.addReader(new SendErrorRule(protocolRep)); protocolRep.addReader(new GetFileRule(protocolRep)); protocolRep.addReader(new EraseErrorRule(protocolRep)); protocolRep.addReader(new EraseOkRule(protocolRep)); protocolRep.addReader(new RemoveFileRule(protocolRep)); - protocolRep.addReader(new RetrieveErrorRule()); - protocolRep.addReader(new RetrieveOkRule()); + protocolRep.addReader(new RetrieveErrorRule(protocolRep)); + protocolRep.addReader(new RetrieveOkRule(protocolRep, repositoryStorage.getStoragePath())); } private static void initWritersProtocols(Repository repositoryStorage, ProtocolRepository protocolRep) { @@ -81,7 +81,7 @@ public class App { protocolRep.addWriter(new EraseFileRule()); protocolRep.addWriter(new RemoveFileErrorRule()); protocolRep.addWriter(new RemoveFileOkRule()); - protocolRep.addWriter(new GetFileOkRule()); + protocolRep.addWriter(new GetFileOkRule(repositoryStorage.getStoragePath())); protocolRep.addWriter(new RetrieveFileRule()); } diff --git a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java index f79c820..2948cdb 100644 --- a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java +++ b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java @@ -116,25 +116,24 @@ public class ClientHandler implements Runnable, AutoCloseable { ProtocolWriter.ProtocolResult writerCommand = ruleResult.getResultCommand(); // TODO : Vérifier que le StorBackEnd demandé (Pas toujours demandé) est disponible if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND && !fileFrontEnd.canExecuteCommand(ruleResult.getRequestDomain())) { - System.out.println("ICI"); - System.out.println(context.getLogin() + " - " + 2); writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client writer.flush(); } else if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND) { fileFrontEnd.newCommand(context, writerCommand); // Envoie dans la file de tâche FileFrontEnd en attente d'un traitement d'un StorBackEnd - System.out.println(context.getLogin() + " - " + 3); // Attend la fin de la réalisation de la tâche waitTaskResponse(); - System.out.println(context.getLogin() + " - " + 4); - writer.write(response.getCommand()); // Renvoie au client - writer.flush(); - response.write(this.client.getOutputStream()); // Ecrit au client si nécessaire - System.out.println(context.getLogin() + " - " + 5); + if (response != null) { + writer.write(response.getCommand()); // Renvoie au client + writer.flush(); + response.write(this.client.getOutputStream()); // Ecrit au client si nécessaire + } else { + writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client + writer.flush(); + } } else { - System.out.println(context.getLogin() + " - " + 6); writer.print(writerCommand.getCommand()); // Renvoie au client writer.flush(); } diff --git a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java index 158f308..cc4fc98 100644 --- a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java +++ b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java @@ -96,16 +96,25 @@ public class StoreProcessor extends Thread implements AutoCloseable { // Response - String responseCommand = this.reader.readLine() + "\r\n"; - if (responseCommand != null) - System.out.println("StoreBackEnd: " + responseCommand); - ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(context, responseCommand); - responseResult.read( - this.store.getInputStream() - ); - System.out.println("StoreBackEnd response to client: " + responseResult.getResultCommand()); + String responseCommand = this.reader.readLine(); + if (responseCommand != null && !responseCommand.isBlank()) { + responseCommand += "\r\n"; + ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(context, responseCommand); + if (responseResult != null) { + System.out.println("StoreBackEnd response to client: " + responseResult.getResultCommand()); + responseResult.read( + this.store.getInputStream() + ); - alertAvalaible(responseResult.getResultCommand()); + alertAvalaible(responseResult.getResultCommand()); + } else { + System.out.println("StoreBackEnd result: Commande null"); + alertAvalaible(null); + } + } else { + System.out.println("StoreBackEnd: Commande null"); + alertAvalaible(null); + } } catch (IOException ignore) { // TODO : Gérer déconnection diff --git a/app/src/main/java/lightcontainer/protocol/ProtocolReader.java b/app/src/main/java/lightcontainer/protocol/ProtocolReader.java index e1ad527..634f0af 100644 --- a/app/src/main/java/lightcontainer/protocol/ProtocolReader.java +++ b/app/src/main/java/lightcontainer/protocol/ProtocolReader.java @@ -95,8 +95,7 @@ public abstract class ProtocolReader { * * @param reader Buffer rempli du fichier */ - public void read(InputStream reader) { - } + public void read(InputStream reader) { } /** * Permet de récupérer le context courant @@ -111,7 +110,7 @@ public abstract class ProtocolReader { /** * Cette méthode est appelée lorsque la commande à exécuter ne peut pas être exécutée */ - public final String onNotExecutable(Context context) { + public final String onNotExecutable(Context context) { ProtocolResult cmdResult = onError(context); return cmdResult == null ? null : cmdResult.getResultCommand().getCommand(); } diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java index e3e9a3c..a667672 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java @@ -4,6 +4,8 @@ import lightcontainer.domains.client.Context; import lightcontainer.interfaces.ProtocolRepository; import lightcontainer.protocol.ProtocolReader; import lightcontainer.protocol.rules.writer.GetFileErrorRule; +import lightcontainer.protocol.rules.writer.RemoveFileErrorRule; +import lightcontainer.protocol.rules.writer.RetrieveFileRule; import lightcontainer.storage.ReadOnlyFile; import java.util.Iterator; @@ -36,7 +38,6 @@ public class GetFileRule extends ProtocolReader { super(context); this.fileName = fileName; } - } /** @@ -51,16 +52,21 @@ public class GetFileRule extends ProtocolReader { ReadOnlyFile file = context.getFile(data[FILE_NAME]); - // Précision du store back end demandé pour traiter cette commande. - String requestDomain = extractRequestDomain(file.getStorageIterator()); - result.setRequestDomain(requestDomain); + if (file != null) { + // Précision du store back end demandé pour traiter cette commande. + String requestDomain = extractRequestDomain(file.getStorageIterator()); + result.setRequestDomain(requestDomain); - if (true) { + // Save into bundle + context.putDataString("fileName", file.getName()); + context.putDataInt("fileSize", file.getSize()); + context.putDataString("fileIV", file.getIv()); + // Create cmd for storebacked + result.setResultCommand(protocolRep.executeWriter(context, RetrieveFileRule.NAME, context.getHashedFileName(file.getName())), ResultCmdReceiver.STOREBACKEND); } else { - + result.setResultCommand(protocolRep.executeWriter(context, GetFileErrorRule.NAME), ResultCmdReceiver.CLIENT); } - return result; } @@ -74,8 +80,8 @@ public class GetFileRule extends ProtocolReader { return result; } - /** - * TODO : But futur est de pouvoir en avoir plusieurs + /** TMP + * TODO : But futur est de pouvoir en avoir plusieurs (sbe) * Cette méthode permet de choisir le domaine voulu. * @param storageIterator Les domaines * @return Le domain choisi diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java index 551ea03..9bb8339 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveErrorRule.java @@ -1,16 +1,22 @@ package lightcontainer.protocol.rules.reader; import lightcontainer.domains.client.Context; +import lightcontainer.interfaces.ProtocolRepository; import lightcontainer.protocol.ProtocolReader; +import lightcontainer.protocol.rules.writer.GetFileErrorRule; public class RetrieveErrorRule extends ProtocolReader { // Constants private static final String PATTERN = "^RETRIEVE_ERROR\r\n$"; private static final String NAME = "RETRIEVE_ERROR"; + // Variables + private final ProtocolRepository protocolRep; + // Constructor - public RetrieveErrorRule() { + public RetrieveErrorRule(ProtocolRepository protocolRep) { super(NAME, PATTERN); + this.protocolRep = protocolRep; } /** @@ -20,7 +26,9 @@ public class RetrieveErrorRule extends ProtocolReader { * @param data Paramètres pour créer la commande. */ @Override - protected T onExecuted(Context context, String... data) { - return null; + protected ProtocolReader.ProtocolResult onExecuted(Context context, String... data) { + ProtocolReader.ProtocolResult result = new ProtocolReader.ProtocolResult(context); + result.setResultCommand(protocolRep.executeWriter(context, GetFileErrorRule.NAME), ResultCmdReceiver.CLIENT); + return result; } } diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java index 39c4cb3..412681e 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/RetrieveOkRule.java @@ -1,11 +1,18 @@ package lightcontainer.protocol.rules.reader; import lightcontainer.domains.client.Context; +import lightcontainer.interfaces.ProtocolRepository; import lightcontainer.protocol.ProtocolReader; +import lightcontainer.protocol.rules.writer.GetFileOkRule; +import lightcontainer.protocol.rules.writer.SaveFileErrorRule; +import lightcontainer.utils.FileReceiver; +import lightcontainer.utils.FileSender; + +import java.io.InputStream; public class RetrieveOkRule extends ProtocolReader { // Constants - private static final String PATTERN = "^RETRIEVE_OK ([A-Za-z0-9.]{50,200} [0-9]{1,10} [A-Za-z0-9.]{50,200})\r\n$"; + private static final String PATTERN = "^RETRIEVE_OK ([A-Za-z0-9.]{50,200}) ([0-9]{1,10}) ([A-Za-z0-9.]{50,200})\r\n$"; private static final String NAME = "RETRIEVE_OK"; // -- arguments private static final int HASHED_FILE_NAME = 0; // Index hashed filename @@ -13,8 +20,43 @@ public class RetrieveOkRule extends ProtocolReader { private static final int HASHED_FILE_CONTENT = 2; // Index hashed file content // Variables - public RetrieveOkRule() { + private ProtocolRepository protocolRep; + private String storagePath; + + // Variables + public RetrieveOkRule(ProtocolRepository protocolRep, String storagePath) { super(NAME, PATTERN); + this.protocolRep = protocolRep; + this.storagePath = storagePath; + } + + public class Result extends ProtocolResult { + // Variables + private String filename; + private int filesize; + private String hashedFileContent; + + public Result(Context context, String filename, int filesize, String hashedFileContent) { + super(context); + this.filename = filename; + this.filesize = filesize; + this.hashedFileContent = hashedFileContent; + } + + /** + * Bitch has bettern than my money + * @param reader Buffer rempli du fichier + */ + @Override + public void read(InputStream reader) { + super.read(reader); + System.out.println("Récupération du fichier du SBE"); + + FileReceiver fileReceiver = new FileReceiver(storagePath); + fileReceiver.receiveFile(reader, this.filename, this.filesize); + + // TODO fingerprint + } } /** @@ -24,12 +66,16 @@ public class RetrieveOkRule extends ProtocolReader { * @param data Paramètres pour créer la commande. */ @Override - protected T onExecuted(Context context, String... data) { - return null; + protected RetrieveOkRule.Result onExecuted(Context context, String... data) { + RetrieveOkRule.Result result = new RetrieveOkRule.Result(context, data[HASHED_FILE_NAME], Integer.parseInt(data[FILE_SIZE]), data[HASHED_FILE_CONTENT]); + result.setResultCommand(protocolRep.executeWriter(context, GetFileOkRule.NAME, context.getDataString("fileName"), String.valueOf(context.getDataInt("fileSize"))), ResultCmdReceiver.CLIENT); + return result; } @Override - protected T onError(Context context) { - return super.onError(context); + protected ProtocolReader.ProtocolResult onError(Context context) { + ProtocolResult result = new ProtocolResult(context); + result.setResultCommand(protocolRep.executeWriter(context, SaveFileErrorRule.NAME), ResultCmdReceiver.CLIENT); + return result; } } diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/SendErrorRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/SendErrorRule.java index ced3fd0..1f395f1 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/reader/SendErrorRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/SendErrorRule.java @@ -14,29 +14,23 @@ import java.nio.file.Path; * Règle permettant de de confirmer la sauvegrade d'un fichier. */ public class SendErrorRule extends ProtocolReader { - - // Constants private static final String PATTERN = "^SEND_ERROR\r\n$"; private static final String NAME = "SEND_ERROR"; private ProtocolRepository protocolRep; - private final String storagePath; // Constructor - public SendErrorRule(ProtocolRepository protocolRep, String storagePath) { + public SendErrorRule(ProtocolRepository protocolRep) { super(NAME, PATTERN); this.protocolRep = protocolRep; - this.storagePath = storagePath; } - @Override protected ProtocolResult onExecuted(Context context, String... data) { ProtocolResult result = new ProtocolResult(context); result.setResultCommand(protocolRep.executeWriter(context, SaveFileErrorRule.NAME), ResultCmdReceiver.CLIENT); - return result; } } diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java index 39944db..08390bb 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/GetFileOkRule.java @@ -1,17 +1,56 @@ package lightcontainer.protocol.rules.writer; +import lightcontainer.domains.client.Context; import lightcontainer.protocol.ProtocolWriter; +import lightcontainer.utils.FileSender; + +import java.io.OutputStream; public class GetFileOkRule extends ProtocolWriter { // Constants - private static final String PATTERN = "^GETFILE_OK (^ !]{1,20}) ([0-9]{1,10})\r\n$"; + private static final String PATTERN = "^GETFILE_OK ([^ !]{1,20}) ([0-9]{1,10})\r\n$"; public static final String NAME = "GETFILE_OK"; // -- params private static final int FILE_NAME = 0; // Index file name hashed private static final int FILE_SIZE = 1; // Index file size + // Variables + private String storagePath; + // Constructors - public GetFileOkRule() { + public GetFileOkRule(String storagePath) { super(NAME, PATTERN); + this.storagePath = storagePath; + } + + public class Result extends ProtocolWriter.ProtocolResult { + // Variables + private String filename; + private int filesize; + + // Constructors + public Result(Context context, String filename, int filesize) { + super(context); + this.filename = filename; + this.filesize = filesize; + } + + /** + * Oh yeahh baby + * @param writer Buffer à remplir qui sera envoyer via le réseau + */ + @Override + public void write(OutputStream writer) { + super.write(writer); + System.out.printf("Sauvegarde du fichier : %s %d\n", this.filename, this.filesize); + + FileSender fileSender = new FileSender(storagePath); + fileSender.sendFile(getContext().getHashedFileName(this.filename), writer, this.filesize, getContext().getAesKey(), getContext().getDataString("fileIV")); + } + } + + @Override + protected GetFileOkRule.Result onExecuted(Context context, String... data) { + return new GetFileOkRule.Result(context, data[FILE_NAME], Integer.parseInt(data[FILE_SIZE])); } } diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java index 65243c9..c397129 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/RetrieveFileRule.java @@ -6,8 +6,6 @@ public class RetrieveFileRule extends ProtocolWriter { // Constants private static final String PATTERN = "^RETRIEVEFILE ([A-Za-z0-9.]{50,200})\r\n$"; public static final String NAME = "RETRIEVEFILE"; - // -- params - private static final int HASHED_FILE_NAME = 0; // Index hashed filename // Constructor public RetrieveFileRule() { diff --git a/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java b/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java index b5826bc..36eabff 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java @@ -44,10 +44,8 @@ public class SendfileRule extends ProtocolWriter { super.write(writer); System.out.println("Envoie du fichier au SBE"); - FileSender fileSender = new FileSender(storagePath); fileSender.sendFile(hashedFileName, writer); - } } diff --git a/app/src/main/java/lightcontainer/repository/FileFrontEnd.java b/app/src/main/java/lightcontainer/repository/FileFrontEnd.java index ef6e4aa..fa1a129 100644 --- a/app/src/main/java/lightcontainer/repository/FileFrontEnd.java +++ b/app/src/main/java/lightcontainer/repository/FileFrontEnd.java @@ -48,17 +48,15 @@ public class FileFrontEnd implements ClientHandlerFFE, StoreProcessorFFE { @Override public void onStoreAvailable(StoreProcessor store, ProtocolWriter.ProtocolResult response) { // TODO : Chercher une tâche appropriée - if (response != null) { - Iterator it = tasks.iterator(); - while (it.hasNext()) { - Task task = it.next(); - System.out.println("Cherche"); - if (task.isResponseOfClient(store.getDomain())) { - System.out.println("Task trouvée"); - clientRepository.respondToClient(task.getClient(), response); - it.remove(); // Suppression de la tâche - break; - } + Iterator it = tasks.iterator(); + while (it.hasNext()) { + Task task = it.next(); + System.out.println("Cherche"); + if (task.isResponseOfClient(store.getDomain())) { + System.out.println("Task trouvée"); + clientRepository.respondToClient(task.getClient(), response); + it.remove(); // Suppression de la tâche + break; } } diff --git a/app/src/main/java/lightcontainer/utils/FileReceiver.java b/app/src/main/java/lightcontainer/utils/FileReceiver.java index 17b7513..fd6fc65 100644 --- a/app/src/main/java/lightcontainer/utils/FileReceiver.java +++ b/app/src/main/java/lightcontainer/utils/FileReceiver.java @@ -27,4 +27,28 @@ public class FileReceiver { } } + public boolean receiveFile(InputStream input, String fileName, long fileSize) { + int bytesReceived = 0; + BufferedOutputStream bosFile = null; + + try { + byte[] buffer = new byte[1024]; + bosFile = new BufferedOutputStream(new FileOutputStream(String.format("%s/%s", path, fileName))); + long currentOffset = 0; + + while((currentOffset < fileSize) && ((bytesReceived = input.read(buffer)) > 0)) { + bosFile.write(buffer, 0, bytesReceived); + currentOffset += bytesReceived; + } + bosFile.flush(); + bosFile.close(); + + return true; + } catch(Exception ex) { + ex.printStackTrace(); + if(bosFile != null) { try { bosFile.close(); } catch(Exception e) {} } + return false; + } + } + } diff --git a/app/src/main/resources/appdata.json b/app/src/main/resources/appdata.json index 7efd5d9..261cc46 100644 --- a/app/src/main/resources/appdata.json +++ b/app/src/main/resources/appdata.json @@ -1 +1,27 @@ -{"unicast_port":8000,"multicast_ip":"224.66.66.1","multicast_port":15502,"network_interface":"wlp1s0","tls":true,"storagePath":"/home/benjamin/ffe","users":[{"name":"aaaaa","password":"5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617","aes_key":"qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=","passwordSalt":"Ns8Al6DpqPsIDlCSRBVTEg==","files":[{"name":"ca.crt","fileNameSalt":"rTiE/FXNglnzbGBUGTDuJA==","size":4207,"iv":"0lg3QNhJ/eN292dbOvjShQ==","storage":["lightcontainerSB01"]},{"name":"main.py","fileNameSalt":"A3e6pNPkjZd4Rp2z9Nfzsg==","size":854,"iv":"rBqMLyPxtOQWJYasKFmrkA==","storage":["lightcontainerSB01"]},{"name":"README.md","fileNameSalt":"cDY6LMq13iqKknRS9OVBPw==","size":17,"iv":"jxc7hkIAoH64M8JF7FvNFw==","storage":["lightcontainerSB01"]}]}]} \ No newline at end of file +{ + "unicast_port": 8000, + "multicast_ip": "224.66.66.1", + "multicast_port": 15502, + "network_interface": "Software Loopback Interface 1", + "tls": true, + "storagePath": "D:\\ffe", + "users": [ + { + "name": "aaaaa", + "password": "5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617", + "aes_key": "qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=", + "passwordSalt": "Ns8Al6DpqPsIDlCSRBVTEg==", + "files": [ + { + "name": "loader.gif", + "fileNameSalt": "qIM0UIgtc4c9I+K8iLeObg==", + "size": 89594, + "iv": "WHJj4TMCmlRnCIQqgGjrnw==", + "storage": [ + "lightcontainerSB01" + ] + } + ] + } + ] +} \ No newline at end of file