Merge branch 'benjamin' into dev

This commit is contained in:
Benjamin 2022-03-19 20:58:15 +01:00
commit 60fb6390b4
6 changed files with 143 additions and 116 deletions

View File

@ -27,53 +27,21 @@ import java.nio.charset.StandardCharsets;
* @see AutoCloseable * @see AutoCloseable
* @since 1.0 * @since 1.0
*/ */
public class ClientHandler implements Runnable, AutoCloseable { public class ClientHandler extends UnicastThread implements AutoCloseable {
// Variables // Variables
private final ClientHandlerFFE fileFrontEnd; private final ClientHandlerFFE fileFrontEnd;
private final Socket client;
private final ProtocolRepository protocolRep; private final ProtocolRepository protocolRep;
private final Context context;
private boolean client_run;
private final UnicastCHR repository; private final UnicastCHR repository;
private BufferedReader reader;
private PrintWriter writer;
private ProtocolWriter.ProtocolResult response; private ProtocolWriter.ProtocolResult response;
// Constructor // Constructor
public ClientHandler(UnicastCHR repository, Socket client, ClientHandlerFFE ffe, ProtocolRepository protocolRep, Context context) { public ClientHandler(UnicastCHR repository, Socket client, ClientHandlerFFE ffe, ProtocolRepository protocolRep, Context context) {
super(client, context);
this.repository = repository; this.repository = repository;
this.fileFrontEnd = ffe; this.fileFrontEnd = ffe;
this.client = client;
this.protocolRep = protocolRep; 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 * Thread Function
@ -83,13 +51,13 @@ public class ClientHandler implements Runnable, AutoCloseable {
*/ */
@Override @Override
public void run() { public void run() {
this.client_run = true; this.setRunning(true);
while (this.client_run) { while (this.isRunning()) {
// Signifie le démarrage d'une nouvelle rquête // Signifie le démarrage d'une nouvelle rquête
context.newBundle(); getContext().newBundle();
try { try {
String command = this.reader.readLine(); String command = this.readLine();
if (command != null) { if (command != null) {
System.out.println("Client: " + command); System.out.println("Client: " + command);
} else { } else {
@ -97,7 +65,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
break; break;
} }
ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(context, command + "\r\n"); ProtocolReader.ProtocolResult ruleResult = protocolRep.executeReader(getContext(), command + "\r\n");
if (ruleResult == null) { if (ruleResult == null) {
repository.disconnect(this); repository.disconnect(this);
break; break;
@ -105,29 +73,25 @@ public class ClientHandler implements Runnable, AutoCloseable {
if (checkAccess(ruleResult)) { if (checkAccess(ruleResult)) {
// Lecture du fichier client // Lecture du fichier client
ruleResult.read(this.client.getInputStream()); ruleResult.read(this.getInputStream());
System.out.println(context.getLogin() + " - " + 1); System.out.println(getContext().getLogin() + " - " + 1);
ProtocolWriter.ProtocolResult writerCommand = ruleResult.getResultCommand(); ProtocolWriter.ProtocolResult writerCommand = ruleResult.getResultCommand();
// TODO : Vérifier que le StorBackEnd demandé (Pas toujours demandé) est disponible // TODO : Vérifier que le StorBackEnd demandé (Pas toujours demandé) est disponible
if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND && !fileFrontEnd.canExecuteCommand(ruleResult.getRequestDomain())) { if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND && !fileFrontEnd.canExecuteCommand(ruleResult.getRequestDomain())) {
writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client this.print(ruleResult.onNotExecutable(getContext())); // Renvoie au client
writer.flush();
} else if (ruleResult.getReceiver() == ProtocolReader.ResultCmdReceiver.STOREBACKEND) { } 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 // Attend la fin de la réalisation de la tâche
waitTaskResponse(); waitTaskResponse();
if (response != null) { if (response != null) {
writer.write(response.getCommand()); // Renvoie au client this.write(response.getCommand()); // Renvoie au client
writer.flush(); response.write(this.getOutputStream()); // Ecrit au client si nécessaire
response.write(this.client.getOutputStream()); // Ecrit au client si nécessaire
} else { } else {
writer.print(ruleResult.onNotExecutable(context)); // Renvoie au client this.print(ruleResult.onNotExecutable(getContext())); // Renvoie au client
writer.flush();
} }
} else { } else {
writer.print(writerCommand.getCommand()); // Renvoie au client this.print(writerCommand.getCommand()); // Renvoie au client
writer.flush();
} }
} else { } else {
@ -140,12 +104,9 @@ public class ClientHandler implements Runnable, AutoCloseable {
} }
try { try {
this.reader.close(); this.close();
this.writer.close(); System.out.printf("[CLIENT] %s s'est déconnecté\n", getContext().getLogin());
this.client.close(); } catch (Exception ignored) {}
System.out.printf("[CLIENT] %s s'est déconnecté\n", context.getLogin());
} catch (IOException ignored) {
}
} }
/** /**
@ -156,7 +117,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
*/ */
private boolean checkAccess(ProtocolReader.ProtocolResult ruleResult) { private boolean checkAccess(ProtocolReader.ProtocolResult ruleResult) {
checkSignout(ruleResult); checkSignout(ruleResult);
if (context.isConnected()) if (getContext().isConnected())
return true; return true;
try { try {
@ -180,9 +141,8 @@ public class ClientHandler implements Runnable, AutoCloseable {
*/ */
private void accessDenied() { private void accessDenied() {
System.out.println("AIEAIEAIE"); System.out.println("AIEAIEAIE");
ProtocolWriter.ProtocolResult signErrorResult = protocolRep.executeWriter(context, SignErrorRule.NAME); ProtocolWriter.ProtocolResult signErrorResult = protocolRep.executeWriter(getContext(), SignErrorRule.NAME);
writer.write(signErrorResult.getCommand()); // Envoie SignError car echec de la connection this.write(signErrorResult.getCommand()); // Envoie SignError car echec de la connection
writer.flush();
} }
/** /**
@ -194,8 +154,7 @@ public class ClientHandler implements Runnable, AutoCloseable {
try { try {
ruleResult.getClass().asSubclass(SignoutRule.Result.class); ruleResult.getClass().asSubclass(SignoutRule.Result.class);
repository.disconnect(this); repository.disconnect(this);
} catch (ClassCastException e2) { } catch (ClassCastException e2) {}
}
} }
/** /**
@ -242,12 +201,15 @@ public class ClientHandler implements Runnable, AutoCloseable {
*/ */
@Override @Override
public void close() { public void close() {
try {
super.close();
} catch (Exception e) {}
System.out.println("Call close"); System.out.println("Call close");
this.client_run = false; this.setRunning(false);
} }
public String getLogin() { public String getLogin() {
return this.context.getLogin(); return this.getContext().getLogin();
} }
} }

View File

@ -24,55 +24,26 @@ import java.util.Objects;
* @version 1.1 * @version 1.1
* @see Runnable * @see Runnable
* @see AutoCloseable * @see AutoCloseable
* @since 1.0 * @since 1.0Z
*/ */
public class StoreProcessor extends Thread implements AutoCloseable { public class StoreProcessor extends UnicastThread implements AutoCloseable {
// Variables // Variables
private final StoreProcessorFFE fileFrontEnd; private final StoreProcessorFFE fileFrontEnd;
private final Socket store;
private final String domain; private final String domain;
private boolean client_run;
private LocalDateTime lastAnnounce; private LocalDateTime lastAnnounce;
private BufferedReader reader;
private Context context;
private PrintWriter writer;
private ProtocolWriter.ProtocolResult protocolResult; private ProtocolWriter.ProtocolResult protocolResult;
private final ProtocolRepository protocolRep; private final ProtocolRepository protocolRep;
// Constructor // Constructor
public StoreProcessor(Socket socket, String domain, StoreProcessorFFE ffe, ProtocolRepository protocolRep) { public StoreProcessor(Socket socket, String domain, StoreProcessorFFE ffe, ProtocolRepository protocolRep) {
super(socket);
this.domain = domain; this.domain = domain;
this.fileFrontEnd = ffe; this.fileFrontEnd = ffe;
this.store = socket;
this.protocolRep = protocolRep; 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 * Thread Function
@ -82,9 +53,9 @@ public class StoreProcessor extends Thread implements AutoCloseable {
*/ */
@Override @Override
public void run() { public void run() {
this.client_run = true; this.setRunning(true);
while (this.client_run) { while (this.isRunning()) {
try { try {
if (protocolResult == null) { // Si on n'a pas encore la commande à envoyer if (protocolResult == null) { // Si on n'a pas encore la commande à envoyer
waitAction(); waitAction();
@ -92,11 +63,10 @@ public class StoreProcessor extends Thread implements AutoCloseable {
System.out.println("[SBE] Envoie commande : " + protocolResult.getCommand()); System.out.println("[SBE] Envoie commande : " + protocolResult.getCommand());
// Request // Request
this.writer.write(protocolResult.getCommand()); this.write(protocolResult.getCommand());
this.writer.flush();
try { try {
protocolResult.write(this.store.getOutputStream()); protocolResult.write(this.getOutputStream());
} catch (IOException writeException) { // Si SBE fermé } catch (IOException writeException) { // Si SBE fermé
// Envoie au client que la requête n'a pu être traitée // Envoie au client que la requête n'a pu être traitée
alertAvailable(null); alertAvailable(null);
@ -104,14 +74,14 @@ public class StoreProcessor extends Thread implements AutoCloseable {
} }
// Response // Response
String responseCommand = this.reader.readLine(); String responseCommand = this.readLine();
if (responseCommand != null && !responseCommand.isBlank()) { if (responseCommand != null && !responseCommand.isBlank()) {
responseCommand += "\r\n"; responseCommand += "\r\n";
ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(context, responseCommand); ProtocolReader.ProtocolResult responseResult = protocolRep.executeReader(getContext(), responseCommand);
if (responseResult != null) { if (responseResult != null) {
System.out.println("StoreBackEnd (" + domain + ") response to client: " + responseResult.getResultCommand()); System.out.println("StoreBackEnd (" + domain + ") response to client: " + responseResult.getResultCommand());
responseResult.read( responseResult.read(
this.store.getInputStream() this.getInputStream()
); );
alertAvailable(responseResult.getResultCommand()); alertAvailable(responseResult.getResultCommand());
@ -132,11 +102,9 @@ public class StoreProcessor extends Thread implements AutoCloseable {
// Fermeture du SBE // Fermeture du SBE
try { try {
this.reader.close(); super.close();
this.writer.close();
this.store.close();
this.fileFrontEnd.onStoreDisconnect(this.domain); this.fileFrontEnd.onStoreDisconnect(this.domain);
} catch (IOException ioException) { } catch (Exception ioException) {
System.out.println("[ERROR] Error while closing SBE (" + domain + ") : " + ioException.getMessage()); 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) { public void executeCommand(Context context, ProtocolWriter.ProtocolResult protocolResult) {
synchronized (this) { synchronized (this) {
this.protocolResult = protocolResult; this.protocolResult = protocolResult;
this.context = context; setContext(context);
this.notify(); this.notify();
} }
} }
@ -188,10 +156,9 @@ public class StoreProcessor extends Thread implements AutoCloseable {
*/ */
@Override @Override
public void close() { public void close() {
if (this.client_run) { if (this.isRunning()) {
this.client_run = false; this.setRunning(false);
System.out.println("[SBE] Fermeture de " + domain); System.out.println("[SBE] Fermeture de " + domain);
// TODO : Gérer déconnection (enlever du repo et prévenir client et FileFrontEnd)
} }
} }

View File

@ -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;
}
}

View File

@ -59,7 +59,7 @@ public class UnicastServerListener implements Runnable {
// Add the client handler to its repository (clienthandlerrepository) // Add the client handler to its repository (clienthandlerrepository)
this.repository.addClient(clientHandler); this.repository.addClient(clientHandler);
// Start the thread // Start the thread
(new Thread(clientHandler)).start(); clientHandler.start();
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -55,7 +55,7 @@ public class StoreProcessorRepository implements AutoCloseable, MulticastSPR {
@Override @Override
public boolean addStore(StoreProcessor store) { public boolean addStore(StoreProcessor store) {
if (!this.hasDomain(store.getDomain())) { if (!this.hasDomain(store.getDomain())) {
store.startStore(); store.start();
return this.handlers.add(store); return this.handlers.add(store);
} }
return false; return false;

View File

@ -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"]}]}]} {"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":[]}]}