diff --git a/app/src/main/java/lightcontainer/domains/Task.java b/app/src/main/java/lightcontainer/domains/Task.java index e5e70d3..4a89b7b 100644 --- a/app/src/main/java/lightcontainer/domains/Task.java +++ b/app/src/main/java/lightcontainer/domains/Task.java @@ -77,4 +77,8 @@ public class Task { public Context getContext() { return this.context; } + + public String getDomain() { + return context.getDomain(); + } } diff --git a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java index d10a544..3508101 100644 --- a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java +++ b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java @@ -115,16 +115,23 @@ public class ClientHandler implements Runnable, AutoCloseable { ProtocolWriter.ProtocolResult writerCommand = ruleResult.getResultCommand(); 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 + // TODO : Vérifier que le StorBackEnd demandé (Pas toujours demandé) est disponible + if (ruleResult.getRequestDomain() != null && !fileFrontEnd.canExecuteCommand(ruleResult.getRequestDomain())) { + writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client + writer.flush(); + } else { + fileFrontEnd.newCommand(context, writerCommand); // Envoie dans la file de tâche FileFrontEnd en attente d'un traitement d'un StorBackEnd - // Attend la fin de la réalisation de la tâche - waitTaskResponse(); + // Attend la fin de la réalisation de la tâche + waitTaskResponse(); + + writer.write(response.getCommand()); // Renvoie au client + writer.flush(); + response.write(this.client.getOutputStream()); // Ecrit au client si nécessaire + } - writer.write(response.getCommand()); // Renvoye au client - writer.flush(); - response.write(this.client.getOutputStream()); // Ecrit au client si nécessaire } else { - writer.print(writerCommand.getCommand()); // Renvoye au client + writer.print(writerCommand.getCommand()); // Renvoie au client writer.flush(); } @@ -133,7 +140,6 @@ public class ClientHandler implements Runnable, AutoCloseable { accessDenied(); } } catch (IOException e) { - e.printStackTrace(); repository.disconnect(this); break; } @@ -195,13 +201,13 @@ public class ClientHandler implements Runnable, AutoCloseable { /** * Vérifie s'il s'âgit d'une demande de déconnexion * @param ruleResult - */ private void checkSignError(ProtocolWriter.ProtocolResult ruleResult) { if (ruleResult.getCommand().startsWith(SignErrorRule.NAME)) { System.out.println("Pas pu connecter"); repository.disconnect(this); } } + */ /** * Permet au Client d'attendre la fin de la réalisation de sa tâche diff --git a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java index 47e2ca6..8fb1316 100644 --- a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java +++ b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java @@ -83,6 +83,10 @@ public class StoreProcessor extends Thread implements AutoCloseable { this.client_run = true; while (this.client_run) { try { + if (!store.isConnected()) { + // TODO : Gérer déconnection + break; + } waitAction(); System.out.println("[SBE] Envoie commande : " + protocolResult.getCommand()); @@ -104,7 +108,9 @@ public class StoreProcessor extends Thread implements AutoCloseable { alertAvalaible(responseResult.getResultCommand()); - } catch (IOException ignore) { } + } catch (IOException ignore) { + // TODO : Gérer déconnection + } } } @@ -153,6 +159,7 @@ public class StoreProcessor extends Thread implements AutoCloseable { try { this.client_run = false; this.store.close(); + // TODO : Gérer déconnection (enlever du repo et prévenir client et FileFrontEnd) } catch (IOException ignored) { } } } diff --git a/app/src/main/java/lightcontainer/interfaces/ClientHandlerFFE.java b/app/src/main/java/lightcontainer/interfaces/ClientHandlerFFE.java index 2cd5c90..30b6b1a 100644 --- a/app/src/main/java/lightcontainer/interfaces/ClientHandlerFFE.java +++ b/app/src/main/java/lightcontainer/interfaces/ClientHandlerFFE.java @@ -18,4 +18,5 @@ public interface ClientHandlerFFE { */ void newCommand(Context context, ProtocolWriter.ProtocolResult command); + boolean canExecuteCommand(String domain); } diff --git a/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java b/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java index 1d634c4..5f352e7 100644 --- a/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java +++ b/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java @@ -24,4 +24,6 @@ public interface MulticastSPR { String findDomain(Task task); void assignTask(String stor, Task task); + + boolean hasDomain(String domain); } diff --git a/app/src/main/java/lightcontainer/protocol/ProtocolReader.java b/app/src/main/java/lightcontainer/protocol/ProtocolReader.java index 0990f1a..e1ad527 100644 --- a/app/src/main/java/lightcontainer/protocol/ProtocolReader.java +++ b/app/src/main/java/lightcontainer/protocol/ProtocolReader.java @@ -26,6 +26,7 @@ public abstract class ProtocolReader { STOREBACKEND } + /** * Modèle utilisé par tout les résultats des règles de protocol. * Lorsqu'il retourne son résultat, on vérifie si il y a une demande de lecture/écriture de fichier depuis le réseau. Si oui on appel ces méthodes, sinon on ne fait rien. @@ -42,6 +43,11 @@ public abstract class ProtocolReader { */ private final Context context; + /** + * Domaine demandé pour l'exécution de cette commande (NULL si aucun domaine spécifique demandé) + */ + private String requestDomain; + public ProtocolResult(Context context) { this.context = context; } @@ -58,7 +64,7 @@ public abstract class ProtocolReader { * * @return Receiver */ - public ResultCmdReceiver getReceiver() { + public final ResultCmdReceiver getReceiver() { return receiver; } @@ -67,7 +73,7 @@ public abstract class ProtocolReader { * * @return Commande */ - public ProtocolWriter.ProtocolResult getResultCommand() { + public final ProtocolWriter.ProtocolResult getResultCommand() { return this.resultCommand; } @@ -77,11 +83,12 @@ public abstract class ProtocolReader { * @param resultCommand Commande à envoyer * @param receiver Le receveur de cette commande */ - public void setResultCommand(ProtocolWriter.ProtocolResult resultCommand, ResultCmdReceiver receiver) { + public final void setResultCommand(ProtocolWriter.ProtocolResult resultCommand, ResultCmdReceiver receiver) { this.resultCommand = resultCommand; this.receiver = receiver; } + /** * Permet de lire un fichier. Cad reçevoir le contenu d'un fichier provenant du réseau. * Redéfinissez cette méthode pour l'utiliser @@ -96,10 +103,32 @@ public abstract class ProtocolReader { * * @return Context courant */ - protected Context getContext() { + protected final Context getContext() { return context; } + + /** + * Cette méthode est appelée lorsque la commande à exécuter ne peut pas être exécutée + */ + public final String onNotExecutable(Context context) { + ProtocolResult cmdResult = onError(context); + return cmdResult == null ? null : cmdResult.getResultCommand().getCommand(); + } + + /** + * Accesseur du domaine demandé pour l'exécution de cette commande (NULL si aucun domaine spécifique demandé) + */ + public String getRequestDomain() { + return requestDomain; + } + + /** + * Mutateur du domaine demandé pour l'exécution de cette commande (NULL si aucun domaine spécifique demandé) + */ + public void setRequestDomain(String requestDomain) { + this.requestDomain = requestDomain; + } } /** diff --git a/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java b/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java index 481cdd8..8a772a0 100644 --- a/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java +++ b/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java @@ -60,6 +60,7 @@ public abstract class ProtocolWriter { public Context getContext() { return context; } + } /** 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 35323ca..4b4f056 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/GetFileRule.java @@ -4,9 +4,12 @@ import lightcontainer.domains.client.Context; import lightcontainer.interfaces.ProtocolRepository; import lightcontainer.protocol.ProtocolReader; import lightcontainer.protocol.rules.writer.GetFileErrorRule; +import lightcontainer.protocol.rules.writer.GetFileOkRule; import lightcontainer.storage.File; import lightcontainer.storage.ReadOnlyFile; +import java.util.Iterator; + public class GetFileRule extends ProtocolReader { // Constants private static final String PATTERN = "^GETFILE ([^ !]{1,20})\r\n$"; @@ -50,6 +53,10 @@ public class GetFileRule extends ProtocolReader { ReadOnlyFile file = context.getFileOf(data[FILE_NAME], context.getLogin()); + // Précision du store back end demandé pour traiter cette commande. + String requestDomain = extractRequestDomain(file.getStorageIterator()); + result.setRequestDomain(requestDomain); + if (true) { } else { @@ -68,4 +75,14 @@ public class GetFileRule extends ProtocolReader { result.setResultCommand(protocolRep.executeWriter(context, GetFileErrorRule.NAME), ResultCmdReceiver.CLIENT); return result; } + + /** + * TODO : But futur est de pouvoir en avoir plusieurs + * Cette méthode permet de choisir le domaine voulu. + * @param storageIterator Les domaines + * @return Le domain choisi + */ + private String extractRequestDomain(Iterator storageIterator) { + return storageIterator.next(); + } } diff --git a/app/src/main/java/lightcontainer/protocol/rules/reader/SavefileRule.java b/app/src/main/java/lightcontainer/protocol/rules/reader/SavefileRule.java index 907b1ff..8ffde95 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/reader/SavefileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/reader/SavefileRule.java @@ -102,6 +102,8 @@ public class SavefileRule extends ProtocolReader { @Override protected SavefileRule.Result onExecuted(Context context, String... data) { SavefileRule.Result result = new SavefileRule.Result(context, data[FILE_NAME], Integer.parseInt(data[FILE_SIZE])); + + return result; } 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 e6971cc..b5826bc 100644 --- a/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java +++ b/app/src/main/java/lightcontainer/protocol/rules/writer/SendfileRule.java @@ -11,7 +11,7 @@ import java.io.OutputStream; */ public class SendfileRule extends ProtocolWriter { - private static final String PATTERN = "^SENDFILE [A-Za-z0-9.]{0,200} [0-9]{1,10} [A-Za-z0-9.]{50,200}\r\n$"; + private static final String PATTERN = "^SENDFILE [A-Za-z0-9.]{50,200} [0-9]{1,10} [A-Za-z0-9.]{50,200}\r\n$"; public static final String NAME = "SENDFILE"; diff --git a/app/src/main/java/lightcontainer/repository/FileFrontEnd.java b/app/src/main/java/lightcontainer/repository/FileFrontEnd.java index 41c864e..e61dcde 100644 --- a/app/src/main/java/lightcontainer/repository/FileFrontEnd.java +++ b/app/src/main/java/lightcontainer/repository/FileFrontEnd.java @@ -82,4 +82,9 @@ public class FileFrontEnd implements ClientHandlerFFE, StoreProcessorFFE { tasks.add(task); alertStoreProcessors(task); } + + @Override + public boolean canExecuteCommand(String domain) { + return storeRepository.hasDomain(domain); + } } diff --git a/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java b/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java index 30234e4..769208a 100644 --- a/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java +++ b/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java @@ -78,6 +78,17 @@ public class StoreProcessorRepository implements AutoCloseable, MulticastSPR { handler.executeCommand(task.getContext(), task.getCommand()); } + @Override + public boolean hasDomain(String domain) { + for (StoreProcessor handler : handlers) { + if (handler.getDomain().equals(domain)) { + return true; + } + } + + return false; + } + /** * AutoClosable Function * Closes all StoreProcessor stored in this repository and deallocates all resources. diff --git a/app/src/main/resources/appdata.json b/app/src/main/resources/appdata.json index bf62c9c..f9171fe 100644 --- a/app/src/main/resources/appdata.json +++ b/app/src/main/resources/appdata.json @@ -1,27 +1 @@ -{ - "unicast_port": 8000, - "multicast_ip": "224.66.66.1", - "multicast_port": 15502, - "network_interface": "My network interface", - "tls": true, - "storagePath": "/home/benjamin/ffe", - "users": [ - { - "name": "aaaaa", - "password": "5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617", - "aes_key": "qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=", - "passwordSalt": "Ns8Al6DpqPsIDlCSRBVTEg==", - "files": [ - { - "name": "README.md", - "fileNameSalt": "/jo0zYyQs96gWI9OgBXiPQ==", - "size": 17, - "iv": "rvOFhgEvgFMISO44jqlSRg==", - "storage": [ - "lightcontainerSB01" - ] - } - ] - } - ] -} \ No newline at end of file +{"unicast_port":8000,"multicast_ip":"224.66.66.1","multicast_port":15502,"network_interface":"My network interface","tls":true,"storagePath":"/home/benjamin/ffe","users":[{"name":"aaaaa","password":"5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617","aes_key":"qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=","passwordSalt":"Ns8Al6DpqPsIDlCSRBVTEg==","files":[{"name":"main.py","fileNameSalt":"IJNYL681pFqbF9OHzRuHIg==","size":854,"iv":"bPCnwYbenKvFfwbhq+HI5A==","storage":["lightcontainerSB01"]},{"name":"README.md","fileNameSalt":"/jo0zYyQs96gWI9OgBXiPQ==","size":17,"iv":"rvOFhgEvgFMISO44jqlSRg==","storage":["lightcontainerSB01"]}]}]} \ No newline at end of file