diff --git a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java index 54fa0f0..bdee567 100644 --- a/app/src/main/java/lightcontainer/domains/client/ClientHandler.java +++ b/app/src/main/java/lightcontainer/domains/client/ClientHandler.java @@ -27,53 +27,21 @@ import java.nio.charset.StandardCharsets; * @see AutoCloseable * @since 1.0 */ -public class ClientHandler implements Runnable, AutoCloseable { +public class ClientHandler extends UnicastThread implements AutoCloseable { // Variables private final ClientHandlerFFE fileFrontEnd; - private final Socket client; private final ProtocolRepository protocolRep; - private final Context context; - private boolean client_run; private final UnicastCHR repository; - - - private BufferedReader reader; - private PrintWriter writer; private ProtocolWriter.ProtocolResult response; // Constructor public ClientHandler(UnicastCHR repository, Socket client, ClientHandlerFFE ffe, ProtocolRepository protocolRep, Context context) { + super(client, context); this.repository = repository; this.fileFrontEnd = ffe; - this.client = client; this.protocolRep = protocolRep; - this.context = context; - this.client_run = false; - initClient(); } - /** - * Initialise the Client's Reader and Writer. - * - * @see BufferedReader - * @see PrintWriter - * @since 1.0 - */ - private void initClient() { - // Start the thread - try { - this.reader = new BufferedReader(new InputStreamReader( - this.client.getInputStream(), - StandardCharsets.UTF_8 - )); - this.writer = new PrintWriter(new OutputStreamWriter( - this.client.getOutputStream(), - StandardCharsets.UTF_8 - ), true); - } catch (IOException e) { - e.printStackTrace(); - } - } /** * Thread Function @@ -83,13 +51,13 @@ public class ClientHandler implements Runnable, AutoCloseable { */ @Override public void run() { - this.client_run = true; - while (this.client_run) { + this.setRunning(true); + while (this.isRunning()) { // Signifie le démarrage d'une nouvelle rquête - context.newBundle(); + getContext().newBundle(); try { - String command = this.reader.readLine(); + String command = this.readLine(); if (command != null) { System.out.println("Client: " + command); } else { @@ -97,7 +65,7 @@ public class ClientHandler implements Runnable, AutoCloseable { break; } - ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(context, command + "\r\n"); + ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(getContext(), command + "\r\n"); if (ruleResult == null) { repository.disconnect(this); break; @@ -105,29 +73,25 @@ public class ClientHandler implements Runnable, AutoCloseable { if (checkAccess(ruleResult)) { // Lecture du fichier client - ruleResult.read(this.client.getInputStream()); - System.out.println(context.getLogin() + " - " + 1); + ruleResult.read(this.getInputStream()); + System.out.println(getContext().getLogin() + " - " + 1); 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())) { - writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client - writer.flush(); + this.print(ruleResult.onNotExecutable(getContext())); // Renvoie au client } else if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND) { - fileFrontEnd.newCommand(context, writerCommand, ruleResult.getRequestDomain()); // Envoie dans la file de tâche FileFrontEnd en attente d'un traitement d'un StorBackEnd + fileFrontEnd.newCommand(getContext(), writerCommand, ruleResult.getRequestDomain()); // 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(); if (response != null) { - writer.write(response.getCommand()); // Renvoie au client - writer.flush(); - response.write(this.client.getOutputStream()); // Ecrit au client si nécessaire + this.write(response.getCommand()); // Renvoie au client + response.write(this.getOutputStream()); // Ecrit au client si nécessaire } else { - writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client - writer.flush(); + this.print(ruleResult.onNotExecutable(getContext())); // Renvoie au client } } else { - writer.print(writerCommand.getCommand()); // Renvoie au client - writer.flush(); + this.print(writerCommand.getCommand()); // Renvoie au client } } else { @@ -140,12 +104,9 @@ public class ClientHandler implements Runnable, AutoCloseable { } try { - this.reader.close(); - this.writer.close(); - this.client.close(); - System.out.printf("[CLIENT] %s s'est déconnecté\n", context.getLogin()); - } catch (IOException ignored) { - } + this.close(); + System.out.printf("[CLIENT] %s s'est déconnecté\n", getContext().getLogin()); + } catch (Exception ignored) {} } /** @@ -156,7 +117,7 @@ public class ClientHandler implements Runnable, AutoCloseable { */ private boolean checkAccess(ProtocolReader.ProtocolResult ruleResult) { checkSignout(ruleResult); - if (context.isConnected()) + if (getContext().isConnected()) return true; try { @@ -180,9 +141,8 @@ public class ClientHandler implements Runnable, AutoCloseable { */ private void accessDenied() { System.out.println("AIEAIEAIE"); - ProtocolWriter.ProtocolResult signErrorResult = protocolRep.executeWriter(context, SignErrorRule.NAME); - writer.write(signErrorResult.getCommand()); // Envoie SignError car echec de la connection - writer.flush(); + ProtocolWriter.ProtocolResult signErrorResult = protocolRep.executeWriter(getContext(), SignErrorRule.NAME); + this.write(signErrorResult.getCommand()); // Envoie SignError car echec de la connection } /** @@ -194,8 +154,7 @@ public class ClientHandler implements Runnable, AutoCloseable { try { ruleResult.getClass().asSubclass(SignoutRule.Result.class); repository.disconnect(this); - } catch (ClassCastException e2) { - } + } catch (ClassCastException e2) {} } /** @@ -242,12 +201,15 @@ public class ClientHandler implements Runnable, AutoCloseable { */ @Override public void close() { + try { + super.close(); + } catch (Exception e) {} System.out.println("Call close"); - this.client_run = false; + this.setRunning(false); } public String getLogin() { - return this.context.getLogin(); + return this.getContext().getLogin(); } } diff --git a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java index 42c1590..718eb37 100644 --- a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java +++ b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java @@ -24,55 +24,26 @@ import java.util.Objects; * @version 1.1 * @see Runnable * @see AutoCloseable - * @since 1.0 + * @since 1.0Z */ -public class StoreProcessor extends Thread implements AutoCloseable { +public class StoreProcessor extends UnicastThread implements AutoCloseable { // Variables private final StoreProcessorFFE fileFrontEnd; - private final Socket store; private final String domain; - private boolean client_run; private LocalDateTime lastAnnounce; - private BufferedReader reader; - private Context context; - private PrintWriter writer; private ProtocolWriter.ProtocolResult protocolResult; private final ProtocolRepository protocolRep; // Constructor public StoreProcessor(Socket socket, String domain, StoreProcessorFFE ffe, ProtocolRepository protocolRep) { + super(socket); this.domain = domain; this.fileFrontEnd = ffe; - this.store = socket; this.protocolRep = protocolRep; - this.client_run = false; } - /** - * Initialise the Store's Reader and Writer. - * - * @see BufferedReader - * @see PrintWriter - * @since 1.0 - */ - public void startStore() { - try { - this.reader = new BufferedReader(new InputStreamReader( - this.store.getInputStream(), - StandardCharsets.UTF_8 - )); - this.writer = new PrintWriter(new OutputStreamWriter( - this.store.getOutputStream(), - StandardCharsets.UTF_8 - ), true); - - this.start(); - } catch (IOException e) { - e.printStackTrace(); - } - } /** * Thread Function @@ -82,9 +53,9 @@ public class StoreProcessor extends Thread implements AutoCloseable { */ @Override public void run() { - this.client_run = true; + this.setRunning(true); - while (this.client_run) { + while (this.isRunning()) { try { if (protocolResult == null) { // Si on n'a pas encore la commande à envoyer waitAction(); @@ -92,11 +63,10 @@ public class StoreProcessor extends Thread implements AutoCloseable { System.out.println("[SBE] Envoie commande : " + protocolResult.getCommand()); // Request - this.writer.write(protocolResult.getCommand()); - this.writer.flush(); + this.write(protocolResult.getCommand()); try { - protocolResult.write(this.store.getOutputStream()); + protocolResult.write(this.getOutputStream()); } catch (IOException writeException) { // Si SBE fermé // Envoie au client que la requête n'a pu être traitée alertAvailable(null); @@ -104,14 +74,14 @@ public class StoreProcessor extends Thread implements AutoCloseable { } // Response - String responseCommand = this.reader.readLine(); + String responseCommand = this.readLine(); if (responseCommand != null && !responseCommand.isBlank()) { responseCommand += "\r\n"; - ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(context, responseCommand); + ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(getContext(), responseCommand); if (responseResult != null) { System.out.println("StoreBackEnd (" + domain + ") response to client: " + responseResult.getResultCommand()); responseResult.read( - this.store.getInputStream() + this.getInputStream() ); alertAvailable(responseResult.getResultCommand()); @@ -132,11 +102,9 @@ public class StoreProcessor extends Thread implements AutoCloseable { // Fermeture du SBE try { - this.reader.close(); - this.writer.close(); - this.store.close(); + super.close(); this.fileFrontEnd.onStoreDisconnect(this.domain); - } catch (IOException ioException) { + } catch (Exception ioException) { System.out.println("[ERROR] Error while closing SBE (" + domain + ") : " + ioException.getMessage()); } } @@ -149,7 +117,7 @@ public class StoreProcessor extends Thread implements AutoCloseable { public void executeCommand(Context context, ProtocolWriter.ProtocolResult protocolResult) { synchronized (this) { this.protocolResult = protocolResult; - this.context = context; + setContext(context); this.notify(); } } @@ -188,10 +156,9 @@ public class StoreProcessor extends Thread implements AutoCloseable { */ @Override public void close() { - if (this.client_run) { - this.client_run = false; + if (this.isRunning()) { + this.setRunning(false); System.out.println("[SBE] Fermeture de " + domain); - // TODO : Gérer déconnection (enlever du repo et prévenir client et FileFrontEnd) } } diff --git a/app/src/main/java/lightcontainer/domains/client/UnicastThread.java b/app/src/main/java/lightcontainer/domains/client/UnicastThread.java new file mode 100644 index 0000000..b363c10 --- /dev/null +++ b/app/src/main/java/lightcontainer/domains/client/UnicastThread.java @@ -0,0 +1,98 @@ +package lightcontainer.domains.client; + +import java.io.*; +import java.net.Socket; +import java.nio.charset.StandardCharsets; + +public abstract class UnicastThread extends Thread implements AutoCloseable { + + private final Socket socket; + + private Context context; + + private BufferedReader reader; + + private PrintWriter writer; + + private boolean isRunning = false; + + public UnicastThread(Socket socket) { + this(socket, null); + } + + public UnicastThread(Socket socket, Context context) { + this.socket = socket; + this.context = context; + initSocket(); + } + + /** + * Initialise the Socket's Reader and Writer. + * + * @see BufferedReader + * @see PrintWriter + * @since 1.0 + */ + private void initSocket() { + // Start the thread + try { + this.reader = new BufferedReader(new InputStreamReader( + this.socket.getInputStream(), + StandardCharsets.UTF_8 + )); + this.writer = new PrintWriter(new OutputStreamWriter( + this.socket.getOutputStream(), + StandardCharsets.UTF_8 + ), true); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + protected String readLine() throws IOException { + return reader.readLine(); + } + + protected void write(String str) { + writer.write(str); + writer.flush(); + } + + protected void print(String str) { + writer.print(str); + writer.flush(); + } + + protected InputStream getInputStream() throws IOException { + return socket.getInputStream(); + } + + protected OutputStream getOutputStream() throws IOException { + return socket.getOutputStream(); + } + + + @Override + public void close() throws Exception { + this.reader.close(); + this.writer.close(); + this.socket.close(); + } + + protected boolean isRunning() { + return isRunning; + } + + protected void setRunning(boolean running) { + isRunning = running; + } + + protected Context getContext() { + return context; + } + + protected void setContext(Context context) { + this.context = context; + } +} diff --git a/app/src/main/java/lightcontainer/domains/server/UnicastServerListener.java b/app/src/main/java/lightcontainer/domains/server/UnicastServerListener.java index e68abf1..5603d5f 100644 --- a/app/src/main/java/lightcontainer/domains/server/UnicastServerListener.java +++ b/app/src/main/java/lightcontainer/domains/server/UnicastServerListener.java @@ -59,7 +59,7 @@ public class UnicastServerListener implements Runnable { // Add the client handler to its repository (clienthandlerrepository) this.repository.addClient(clientHandler); // Start the thread - (new Thread(clientHandler)).start(); + clientHandler.start(); } } catch (IOException e) { e.printStackTrace(); diff --git a/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java b/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java index 4616a42..934fb25 100644 --- a/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java +++ b/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java @@ -55,7 +55,7 @@ public class StoreProcessorRepository implements AutoCloseable, MulticastSPR { @Override public boolean addStore(StoreProcessor store) { if (!this.hasDomain(store.getDomain())) { - store.startStore(); + store.start(); return this.handlers.add(store); } return false; diff --git a/app/src/main/resources/appdata.json b/app/src/main/resources/appdata.json index 2819776..d9a25a1 100644 --- a/app/src/main/resources/appdata.json +++ b/app/src/main/resources/appdata.json @@ -1 +1 @@ -{"unicast_port":8000,"multicast_ip":"224.66.66.1","multicast_port":15502,"network_interface":"wlp1s0","tls":true,"storagePath":"/home/benjamin/ffe","users":[{"name":"benjamin","password":"$2a$10$I4vHt83CTYuQCP7xvZ04Ne7Vb0cswBiVZhV0n23k9FCxoH0ny9fZG","aes_key":"mAP6izUBUhBxIkakH2yB/TplhRz1OQV5Fp6HQmhywns=","files":[{"name":"README.md","fileNameSalt":"5rB5fhj09F6ukJPRoJgTGQ==","size":17,"iv":"hY2yWRgIxB0dRettv/vPJw==","storage":["lightcontainerSB01"]}]},{"name":"aaaaa","password":"$2a$10$nDCEDVwbNO/YDQ4qdRcxfuES4.aboluLzWouXXsk6vDoaWocv516W","aes_key":"kYtwHy9qJBg30WS6axWTFGVE0Ge5kpYiJJlC+COIEI4=","files":[{"name":"main.py","fileNameSalt":"XKxG99LVODAXohvCwvMRww==","size":854,"iv":"G9nULidPTDRxBp+Yp+IaCQ==","storage":["lightcontainerSB01"]}]}]} \ No newline at end of file +{"unicast_port":8000,"multicast_ip":"224.66.66.1","multicast_port":15502,"network_interface":"wlp1s0","tls":true,"storagePath":"/home/benjamin/ffe","users":[{"name":"benjamin","password":"$2a$10$I4vHt83CTYuQCP7xvZ04Ne7Vb0cswBiVZhV0n23k9FCxoH0ny9fZG","aes_key":"mAP6izUBUhBxIkakH2yB/TplhRz1OQV5Fp6HQmhywns=","files":[{"name":"README.md","fileNameSalt":"5rB5fhj09F6ukJPRoJgTGQ==","size":17,"iv":"hY2yWRgIxB0dRettv/vPJw==","storage":["lightcontainerSB01"]}]},{"name":"aaaaa","password":"$2a$10$nDCEDVwbNO/YDQ4qdRcxfuES4.aboluLzWouXXsk6vDoaWocv516W","aes_key":"kYtwHy9qJBg30WS6axWTFGVE0Ge5kpYiJJlC+COIEI4=","files":[]}]} \ No newline at end of file