From 38a403d6a156e3216adc0da10860ae940d537144 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Sat, 5 Mar 2022 18:32:55 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20possibilit=C3=A9=20d'=C3=A9crire=20un?= =?UTF-8?q?=20fichier=20fichier=20sur=20le=20r=C3=A9seau=20et=20ajout=20de?= =?UTF-8?q?=20celle-ci=20pour=20le=20store=20backend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/lightcontainer/App.java | 31 +++++++++++ .../domains/client/ClientHandler.java | 7 ++- .../domains/client/StoreProcessor.java | 55 +++++++++++++++++-- .../server/MulticastServerListener.java | 2 +- .../interfaces/ProtocolRepository.java | 2 +- .../protocol/ProtocolWriter.java | 42 ++++++++++---- .../repository/ProtocolRepositoryImpl.java | 4 +- 7 files changed, 121 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/lightcontainer/App.java b/app/src/main/java/lightcontainer/App.java index 8de81fd..44860f4 100644 --- a/app/src/main/java/lightcontainer/App.java +++ b/app/src/main/java/lightcontainer/App.java @@ -25,6 +25,36 @@ public class App { private static final String MULTICAST_IP = "226.66.66.1"; private static final int MULTICAST_PORT = 42500; + + /* + private static Thread t1 = null; + + public static void main(String[] args) throws InterruptedException { + t1 = new Thread(new Runnable() { + @Override + public void run() { + int i = 0; + while (true) { + System.out.println("HEY " + i++); + + try { + synchronized (t1) { + System.out.println("SUSPEND"); + t1.wait(); + } + } catch (InterruptedException e) {} + } + } + }); + t1.start(); + System.out.println("START"); + Thread.sleep(1000); + synchronized (t1) { + t1.notify(); + } + } + */ + public static void main(String[] args) throws InterruptedException { // Create all repository ClientHandlerRepository clientRep = new ClientHandlerRepository(); @@ -50,4 +80,5 @@ public class App { clientRep.close(); storeRep.close(); } + } diff --git a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java index 0b32715..773ecc3 100644 --- a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java +++ b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java @@ -3,6 +3,7 @@ package lightcontainer.domains.client; import lightcontainer.interfaces.ClientHandlerFFE; import lightcontainer.interfaces.ProtocolRepository; import lightcontainer.protocol.ProtocolReader; +import lightcontainer.protocol.ProtocolWriter; import lightcontainer.protocol.rules.reader.SigninRule; import lightcontainer.protocol.rules.writer.SignErrorRule; import lightcontainer.protocol.rules.writer.SignOkRule; @@ -114,13 +115,15 @@ public class ClientHandler implements Runnable, AutoCloseable { SigninRule.Result signinResult = (SigninRule.Result) ruleResult; if (signinResult.checkCredentials()) { this.login = signinResult.getLogin(); - writer.write(protocolRep.executeWriter(SignOkRule.NAME)); + ProtocolWriter.ProtocolResult signokResult = protocolRep.executeWriter(SignOkRule.NAME); + writer.write(signokResult.getCommand()); writer.flush(); return; } } catch (ClassCastException ignored) {} - writer.write(protocolRep.executeWriter(SignErrorRule.NAME)); // Envoie SignError car echec de la connection + ProtocolWriter.ProtocolResult signErrorResult = protocolRep.executeWriter(SignErrorRule.NAME); + writer.write(signErrorResult.getCommand()); // Envoie SignError car echec de la connection writer.flush(); this.close(); // Fermeture de la connection } diff --git a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java index b573ab4..7a2321f 100644 --- a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java +++ b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java @@ -1,6 +1,9 @@ package lightcontainer.domains.client; +import lightcontainer.interfaces.ProtocolRepository; import lightcontainer.interfaces.StoreProcessorFFE; +import lightcontainer.protocol.ProtocolReader; +import lightcontainer.protocol.ProtocolWriter; import java.io.*; import java.net.Socket; @@ -21,7 +24,7 @@ import java.util.Objects; * @see AutoCloseable * @author Jérémi NIHART */ -public class StoreProcessor implements Runnable, AutoCloseable { +public class StoreProcessor extends Thread implements AutoCloseable { // Variables private final StoreProcessorFFE fileFrontEnd; private final Socket store; @@ -30,12 +33,15 @@ public class StoreProcessor implements Runnable, AutoCloseable { private BufferedReader reader; private PrintWriter writer; + private String currentCommand; + private ProtocolRepository protocolRep; // Constructor - public StoreProcessor(Socket socket, String domain, StoreProcessorFFE ffe) { + public StoreProcessor(Socket socket, String domain, StoreProcessorFFE ffe, ProtocolRepository protocolRep) { this.domain = domain; this.fileFrontEnd = ffe; this.store = socket; + this.protocolRep = protocolRep; this.client_run = false; initStore(); } @@ -73,13 +79,52 @@ public class StoreProcessor implements Runnable, AutoCloseable { this.client_run = true; while (this.client_run) { try { - String command = this.reader.readLine(); - // TODO gestion de la réception de commandes, fichier, ... - if (command != null) System.out.println("StoreBackEnd: " + command); + alertAvalaible(); + + // Request + ProtocolWriter.ProtocolResult requestResult = protocolRep.executeWriter(this.currentCommand); + this.writer.write(requestResult.getCommand()); + requestResult.write(this.store.getOutputStream()); + + + // Response + String responseCommand = this.reader.readLine(); + if (responseCommand != null) + System.out.println("StoreBackEnd: " + responseCommand); + ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(responseCommand); + System.out.println("StoreBackEnd response to client: " + responseResult.getResultCommand()); + + } catch (IOException ignore) { } } } + /** + * Permet de demander au StoreBackEnd d'effectuer une commande + * @param command La commande à effectuer + */ + public void executeCommand(String command) { + synchronized (this) { + this.currentCommand = command; + this.notify(); + } + } + + /** + * Permet de déclarer le StoreBackEnd disponible + */ + private void alertAvalaible() { + synchronized (this) { + this.currentCommand = null; + + fileFrontEnd.onStoreAvailable(this); + + try { + this.wait(); + } catch (InterruptedException e) { e.printStackTrace(); } + } + } + /** * AutoClosable Function * Close the Storage thread and resources. diff --git a/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java b/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java index 98996f3..f88fa56 100644 --- a/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java +++ b/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java @@ -69,7 +69,7 @@ public class MulticastServerListener implements Runnable { Socket socket = new Socket(packet.getAddress(), readerResult.getPort()); // Create the store processor - StoreProcessor storeProcessor = new StoreProcessor(socket, readerResult.getDomain(), null); // TODO : Voir comment on procède get via repo ou ici ?! + StoreProcessor storeProcessor = new StoreProcessor(socket, readerResult.getDomain(), null, protocolRep); // TODO : Voir comment on procède get via repo ou ici ?! // Add the store processor to its repository this.repository.addStore(storeProcessor); } catch (IOException ignore) { diff --git a/app/src/main/java/lightcontainer/interfaces/ProtocolRepository.java b/app/src/main/java/lightcontainer/interfaces/ProtocolRepository.java index af435d1..1f9f48f 100644 --- a/app/src/main/java/lightcontainer/interfaces/ProtocolRepository.java +++ b/app/src/main/java/lightcontainer/interfaces/ProtocolRepository.java @@ -7,7 +7,7 @@ public interface ProtocolRepository { T executeReader(String data); - String executeWriter(String cmdName, String... datas); + T executeWriter(String cmdName, String... data); void addReader(ProtocolReader reader); diff --git a/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java b/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java index 80d6154..6b3801f 100644 --- a/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java +++ b/app/src/main/java/lightcontainer/protocol/ProtocolWriter.java @@ -25,31 +25,51 @@ public abstract class ProtocolWriter { return cmdName; } + public class ProtocolResult { + + private String command; + + public String getCommand() { + return command; + } + + private void setCommand(String command) { + this.command = command; + } + + /** + * Permet d'écrire un fichier sur le réseau. Cad envoyer le contenu d'un fichier sur le réseau. + * Redéfinissez cette méthode pour l'utiliser. + * @param writer Buffer à remplir qui sera envoyer via le réseau + */ + public void write(OutputStream writer) {} + } /** * Permet de contruire une commande selon une règle établie. * @param data Les données à ajouter dans la commande; L'ordre défini leur position dans la commande * @return La commande construite */ - public final String execute(String... data) { + public final T execute(String... data) { // Concatatène le nom de la commande avec les données (trim), avec un espace entre chaque - String command; StringJoiner builder = new StringJoiner(" ", this.cmdName, "\r\n"); - for (String param : data) builder.add(param); - command = builder.toString(); + String command = builder.toString(); + Matcher ruleMatcher = this.rulePattern.matcher(command); // Vérifie que tout match (cf. Matcher). Si match alors on retourne la commande build, sinon on retourne NULL - // Vérifie que tout match (cf. Matcher). Si match alors on retourne la commande build, sinon on retourne NULL - Matcher ruleMatcher = this.rulePattern.matcher(command); - return ruleMatcher.matches() ? command : null; + if (ruleMatcher.matches()) { + ProtocolResult result = onExecuted(); + result.setCommand(command); + return (T) result; + } + return null; } /** - * Permet d'écrire un fichier sur le réseau. Cad envoyer le contenu d'un fichier sur le réseau. - * Redéfinissez cette méthode pour l'utiliser. - * @param writer Buffer à remplir qui sera envoyer via le réseau + * Cette méthode est appelée lors de l'exécution de la règle */ - public void write(OutputStream writer) {} + protected abstract T onExecuted(); + } diff --git a/app/src/main/java/lightcontainer/repository/ProtocolRepositoryImpl.java b/app/src/main/java/lightcontainer/repository/ProtocolRepositoryImpl.java index 4bb1c84..86da726 100644 --- a/app/src/main/java/lightcontainer/repository/ProtocolRepositoryImpl.java +++ b/app/src/main/java/lightcontainer/repository/ProtocolRepositoryImpl.java @@ -23,9 +23,9 @@ public class ProtocolRepositoryImpl implements ProtocolRepository { } @Override - public String executeWriter(String cmdName, String... data) { + public T executeWriter(String cmdName, String... data) { for (ProtocolWriter writer : writers) { - String command; + T command; if (cmdName.equals(writer.getCmdName()) && (command = writer.execute(data)) != null) { return command; }