diff --git a/app/src/main/java/lightcontainer/App.java b/app/src/main/java/lightcontainer/App.java index 31d329f..7e04d2c 100644 --- a/app/src/main/java/lightcontainer/App.java +++ b/app/src/main/java/lightcontainer/App.java @@ -3,6 +3,7 @@ */ package lightcontainer; +import lightcontainer.domains.FFETimer; import lightcontainer.domains.server.MulticastServerListener; import lightcontainer.domains.server.UnicastServerListener; import lightcontainer.interfaces.ProtocolRepository; @@ -17,6 +18,7 @@ import lightcontainer.storage.JsonAdapter; import lightcontainer.storage.Repository; import java.nio.file.Paths; +import java.util.Timer; public class App { @@ -36,6 +38,11 @@ public class App { FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep, protocolRep); new UnicastServerListener(ffe, clientRep, protocolRep, repositoryStorage, repositoryStorage.getUnicastPort()); new MulticastServerListener(ffe, storeRep, protocolRep, repositoryStorage.getMulticastIp(), repositoryStorage.getMulticastPort(), repositoryStorage.getNetworkInterface()); + + // S'occupe de distribué les timeout pour les SBE plus connecté et donc de Timeout les clients + Timer ffeTimer = new Timer(); + ffeTimer.schedule(new FFETimer(storeRep), 50000, 50000); + } private static void initProtocols(Repository repositoryStorage, ProtocolRepository protocolRep) { diff --git a/app/src/main/java/lightcontainer/domains/FFETimer.java b/app/src/main/java/lightcontainer/domains/FFETimer.java new file mode 100644 index 0000000..3a6193f --- /dev/null +++ b/app/src/main/java/lightcontainer/domains/FFETimer.java @@ -0,0 +1,34 @@ +package lightcontainer.domains; + +import lightcontainer.interfaces.MulticastSPR; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.TimerTask; + +/** + * Class s'occupant de gérer les timeout des différents SBE + */ +public class FFETimer extends TimerTask { + + private final MulticastSPR processorRepository; + + public FFETimer(MulticastSPR processorRepository) { + this.processorRepository = processorRepository; + } + + @Override + public void run() { + System.out.println("Timer 1"); + for (String domain : processorRepository.getDomains()) { + LocalDateTime lastAnnounce = processorRepository.getLastAnnounce(domain); + long secondBetween = Math.abs(ChronoUnit.SECONDS.between(lastAnnounce, LocalDateTime.now())); + + System.out.println("Timer 2 : " + secondBetween); + if (secondBetween > 50) { + System.out.println("Timer 3"); + processorRepository.closeStore(domain); + } + } + } +} diff --git a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java index 80c49e0..9c938dc 100644 --- a/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java +++ b/app/src/main/java/lightcontainer/domains/client/StoreProcessor.java @@ -8,7 +8,9 @@ import lightcontainer.protocol.ProtocolWriter; import java.io.*; import java.net.Socket; +import java.net.SocketException; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; import java.util.Objects; /** @@ -30,6 +32,7 @@ public class StoreProcessor extends Thread implements AutoCloseable { private final Socket store; private final String domain; private boolean client_run; + private LocalDateTime lastAnnounce; private BufferedReader reader; private Context context; @@ -37,6 +40,7 @@ public class StoreProcessor extends Thread implements AutoCloseable { private ProtocolWriter.ProtocolResult protocolResult; private final ProtocolRepository protocolRep; + // Constructor public StoreProcessor(Socket socket, String domain, StoreProcessorFFE ffe, ProtocolRepository protocolRep) { this.domain = domain; @@ -94,8 +98,6 @@ public class StoreProcessor extends Thread implements AutoCloseable { try { protocolResult.write(this.store.getOutputStream()); } catch (IOException writeException) { // Si SBE fermé - System.out.println("STOPPER"); - writeException.printStackTrace(); // Envoie au client que la requête n'a pu être traitée alertAvailable(null); break; @@ -188,6 +190,7 @@ public class StoreProcessor extends Thread implements AutoCloseable { public void close() { if (this.client_run) { this.client_run = false; + System.out.println("[FERMETURE SBE] " + domain); // TODO : Gérer déconnection (enlever du repo et prévenir client et FileFrontEnd) } } @@ -218,4 +221,19 @@ public class StoreProcessor extends Thread implements AutoCloseable { public String getDomain() { return this.domain; } + + + /** + * Permet de mettre à jours la dernière annonce de ce SBE au FFE + */ + public void setLastAnnounce(LocalDateTime lastAnnounce) { + this.lastAnnounce = lastAnnounce; + } + + /** + * Permet de mettre à jours la dernière annonce de ce SBE au FFE + */ + public LocalDateTime getLastAnnounce() { + return lastAnnounce; + } } diff --git a/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java b/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java index ba40f10..32e9c42 100644 --- a/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java +++ b/app/src/main/java/lightcontainer/domains/server/MulticastServerListener.java @@ -94,6 +94,8 @@ public class MulticastServerListener implements Runnable { // Add the store processor to its repository this.repository.addStore(storeProcessor); } + // Contient déjà le SBE donc maj de la dernière activité + this.repository.updateLastAnnounce(readerResult.getDomain()); } catch (IOException | ClassCastException exception) { System.out.println("[ERREUR] Une SBE essaye de se connecter avec une mauvaise configuration : " + exception.getMessage()); } diff --git a/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java b/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java index 7aee90a..08fff0f 100644 --- a/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java +++ b/app/src/main/java/lightcontainer/interfaces/MulticastSPR.java @@ -5,6 +5,9 @@ import lightcontainer.domains.client.StoreProcessor; import lightcontainer.domains.server.MulticastServerListener; import lightcontainer.repository.StoreProcessorRepository; +import java.time.LocalDateTime; +import java.util.Collection; + /** * A communication interface between a {@link StoreProcessor} and the {@link StoreProcessorRepository}. */ @@ -42,4 +45,23 @@ public interface MulticastSPR { * @param domain Le domaine du SBE à déconnecter */ void closeStore(String domain); + + /** + * Permet de mettre à jours la dernière annonce de ce SBE au FFE + * @param domain Le domain s'annoncant + */ + void updateLastAnnounce(String domain); + + + /** + * Permet de récupérer les noms des domaines connectés au FFE + * @return Les noms des domaines connectés au FFE + */ + Collection getDomains(); + + /** + * Permet de récupérer la dernière annonce d'un SBE + * @return La dernière annonce d'un SBE + */ + LocalDateTime getLastAnnounce(String domain); } diff --git a/app/src/main/java/lightcontainer/repository/FileFrontEnd.java b/app/src/main/java/lightcontainer/repository/FileFrontEnd.java index b808ff0..66a4f94 100644 --- a/app/src/main/java/lightcontainer/repository/FileFrontEnd.java +++ b/app/src/main/java/lightcontainer/repository/FileFrontEnd.java @@ -47,7 +47,6 @@ public class FileFrontEnd implements ClientHandlerFFE, StoreProcessorFFE { */ @Override public void onStoreAvailable(StoreProcessor store, ProtocolWriter.ProtocolResult response) { - // TODO : Chercher une tâche appropriée Iterator it = tasks.iterator(); while (it.hasNext()) { Task task = it.next(); diff --git a/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java b/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java index 5a3b617..4616a42 100644 --- a/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java +++ b/app/src/main/java/lightcontainer/repository/StoreProcessorRepository.java @@ -5,6 +5,8 @@ import lightcontainer.domains.client.StoreProcessor; import lightcontainer.domains.server.MulticastServerListener; import lightcontainer.interfaces.MulticastSPR; +import java.time.LocalDateTime; +import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -123,19 +125,54 @@ public class StoreProcessorRepository implements AutoCloseable, MulticastSPR { */ @Override public void closeStore(String domain) { - Iterator it = this.handlers.iterator(); - - System.out.println("1 Nombre de SBE : " + handlers.size()); - while (it.hasNext()) { - StoreProcessor storeProcessor = it.next(); - if (storeProcessor.getDomain().equals(domain)) { - storeProcessor.close(); - it.remove(); - return; - } + StoreProcessor storeProcessor = getSBE(domain); + if (storeProcessor != null) { + storeProcessor.close(); + handlers.remove(storeProcessor); } } + /** + * Permet de mettre à jours la dernière annonce de ce SBE au FFE + * + * @param domain Le domain s'annoncant + */ + @Override + public void updateLastAnnounce(String domain) { + StoreProcessor storeProcessor = getSBE(domain); + if (storeProcessor != null) { + storeProcessor.setLastAnnounce(LocalDateTime.now()); + } + } + + /** + * Permet de récupérer les noms des domaines connectés au FFE + * + * @return Les noms des domaines connectés au FFE + */ + @Override + public Collection getDomains() { + Set domains = new HashSet<>(); + + for (StoreProcessor domain : handlers) { + domains.add(domain.getDomain()); + } + + return domains; + } + + /** + * Permet de récupérer la dernière annonce d'un SBE + * + * @param domain + * @return La dernière annonce d'un SBE + */ + @Override + public LocalDateTime getLastAnnounce(String domain) { + StoreProcessor storeProcessor = getSBE(domain); + return storeProcessor == null ? null : storeProcessor.getLastAnnounce(); + } + /** * AutoClosable Function * Closes all StoreProcessor stored in this repository and deallocates all resources. @@ -149,4 +186,7 @@ public class StoreProcessorRepository implements AutoCloseable, MulticastSPR { // Close each client. this.handlers.forEach(StoreProcessor::close); } + + + } diff --git a/app/src/main/resources/appdata.json b/app/src/main/resources/appdata.json index 5cd8dca..7d33a47 100644 --- a/app/src/main/resources/appdata.json +++ b/app/src/main/resources/appdata.json @@ -1 +1,24 @@ -{"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":"atK0eGo/J8IBOTCpIZpWow==","size":17,"iv":"fXPzefxl0cO4Hf02Qwi+BA==","storage":["lightcontainerSB01"]}]},{"name":"aaaaa","password":"$2a$10$nDCEDVwbNO/YDQ4qdRcxfuES4.aboluLzWouXXsk6vDoaWocv516W","aes_key":"kYtwHy9qJBg30WS6axWTFGVE0Ge5kpYiJJlC+COIEI4=","files":[{"name":"ca.crt","fileNameSalt":"qz6FoPGyJJ8Hy+1LIouvZA==","size":4207,"iv":"8v2H+cOzztD++NXHXw5Ofw==","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": "aaaaa", + "password": "$2a$10$nDCEDVwbNO/YDQ4qdRcxfuES4.aboluLzWouXXsk6vDoaWocv516W", + "aes_key": "kYtwHy9qJBg30WS6axWTFGVE0Ge5kpYiJJlC+COIEI4=", + "files": [ + ] + } + ] +} \ No newline at end of file