Système permettant de retourner des résultats divers après l'exécution d'un ProtocolReader sans cast (générique)

This commit is contained in:
Maximilien LEDOUX 2022-02-26 16:55:50 +01:00
parent 8b12bf0d5f
commit 9fdc69d75f
7 changed files with 82 additions and 37 deletions

View File

@ -6,8 +6,11 @@ package lightcontainer;
import lightcontainer.domains.server.MulticastServerListener; import lightcontainer.domains.server.MulticastServerListener;
import lightcontainer.domains.server.UnicastServerListener; import lightcontainer.domains.server.UnicastServerListener;
import lightcontainer.interfaces.MulticastSPR; import lightcontainer.interfaces.MulticastSPR;
import lightcontainer.interfaces.ProtocolRepository;
import lightcontainer.protocol.rules.reader.HelloRule;
import lightcontainer.repository.ClientHandlerRepository; import lightcontainer.repository.ClientHandlerRepository;
import lightcontainer.repository.FileFrontEnd; import lightcontainer.repository.FileFrontEnd;
import lightcontainer.repository.ProtocolRepositoryImpl;
import lightcontainer.repository.StoreProcessorRepository; import lightcontainer.repository.StoreProcessorRepository;
public class App { public class App {
@ -22,9 +25,12 @@ public class App {
// Create all repository // Create all repository
ClientHandlerRepository clientRep = new ClientHandlerRepository(); ClientHandlerRepository clientRep = new ClientHandlerRepository();
StoreProcessorRepository storeRep = new StoreProcessorRepository(); StoreProcessorRepository storeRep = new StoreProcessorRepository();
ProtocolRepository protocolRep = new ProtocolRepositoryImpl();
protocolRep.addReader(new HelloRule());
new UnicastServerListener(clientRep, UNICAST_PORT); new UnicastServerListener(clientRep, UNICAST_PORT);
new MulticastServerListener(storeRep, MULTICAST_IP, MULTICAST_PORT); new MulticastServerListener(storeRep, protocolRep, MULTICAST_IP, MULTICAST_PORT);
FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep); FileFrontEnd ffe = new FileFrontEnd(clientRep, storeRep);

View File

@ -2,34 +2,38 @@ package lightcontainer.domains.server;
import lightcontainer.domains.client.StoreProcessor; import lightcontainer.domains.client.StoreProcessor;
import lightcontainer.interfaces.MulticastSPR; import lightcontainer.interfaces.MulticastSPR;
import lightcontainer.interfaces.ProtocolRepository;
import lightcontainer.protocol.ProtocolReader;
import lightcontainer.protocol.rules.reader.HelloRule;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.*;
/** /**
* StoreMulticastRunnable * StoreMulticastRunnable
* * <p>
* Class listening to the announcement of new StoreBackEnd. * Class listening to the announcement of new StoreBackEnd.
* Allowing it to be used as a storage unit. * Allowing it to be used as a storage unit.
* *
* @version 1.0
* @since 1.0
*
* @see Runnable
* @author Jérémi NIHART <j.nihart@student.helmo.be> * @author Jérémi NIHART <j.nihart@student.helmo.be>
* @version 1.0
* @see Runnable
* @since 1.0
*/ */
public class MulticastServerListener implements Runnable { public class MulticastServerListener implements Runnable {
// Variable // Variable
private final String multicast_address; private final String multicast_address;
private final int multicast_port; private final int multicast_port;
private final MulticastSPR repository; private final MulticastSPR repository;
private final ProtocolRepository protocolRep;
private final byte[] buffer = new byte[256]; private final byte[] buffer = new byte[256];
private MulticastSocket listener; private MulticastSocket listener;
// Constructor // Constructor
public MulticastServerListener(MulticastSPR repository, String multicast_address, int multicast_port) { public MulticastServerListener(MulticastSPR repository, ProtocolRepository protocolRep, String multicast_address, int multicast_port) {
this.repository = repository; this.repository = repository;
this.protocolRep = protocolRep;
this.multicast_address = multicast_address; this.multicast_address = multicast_address;
this.multicast_port = multicast_port; this.multicast_port = multicast_port;
repository.setServerListener(this); repository.setServerListener(this);
@ -38,10 +42,9 @@ public class MulticastServerListener implements Runnable {
/** /**
* Start Multicast listening on indicated port and IP group. * Start Multicast listening on indicated port and IP group.
* *
* @since 1.0
*
* @see MulticastSocket#receive(DatagramPacket) * @see MulticastSocket#receive(DatagramPacket)
* @see DatagramPacket * @see DatagramPacket
* @since 1.0
*/ */
@Override @Override
public void run() { public void run() {
@ -54,29 +57,32 @@ public class MulticastServerListener implements Runnable {
DatagramPacket packet = new DatagramPacket(this.buffer, this.buffer.length); DatagramPacket packet = new DatagramPacket(this.buffer, this.buffer.length);
// Add the listener to the multicast group // Add the listener to the multicast group
this.listener.joinGroup(listener_group); this.listener.joinGroup(listener_group);
while(true) { while (true) {
// Read the packet received and build a string of characters // Read the packet received and build a string of characters
this.listener.receive(packet); this.listener.receive(packet);
String data = new String(packet.getData(), 0, packet.getLength()); String data = new String(packet.getData(), 0, packet.getLength());
// Create a new StoreBacked (try used in the case of an error to maintain the listening loop) // Create a new StoreBacked (try used in the case of an error to maintain the listening loop)
try { try {
// TODO Récupérer le port du message du packet et le setup (add description of the line). // TODO Récupérer le port du message du packet et le setup (add description of the line).
Socket socket = new Socket(packet.getAddress(), 2500); HelloRule.Result readerResult = protocolRep.executeReader(data);
Socket socket = new Socket(packet.getAddress(), readerResult.getPort());
// Create the store processor // Create the store processor
StoreProcessor storeProcessor = new StoreProcessor(socket, null); // TODO <!!!> : Voir comment on procède get via repo ou ici ?! StoreProcessor storeProcessor = new StoreProcessor(socket, null); // TODO <!!!> : Voir comment on procède get via repo ou ici ?!
// Add the store processor to its repository // Add the store processor to its repository
this.repository.addStore(storeProcessor); this.repository.addStore(storeProcessor);
} catch (IOException ignore) { } } catch (IOException ignore) {
}
}
} catch (Exception ignore) {
} }
} catch (Exception ignore) { }
} }
/** /**
* Closes the MulticastSocket connection and aborts the listening and infinite listening loop. * Closes the MulticastSocket connection and aborts the listening and infinite listening loop.
* *
* @since 1.0
*
* @see MulticastServerListener#run() * @see MulticastServerListener#run()
* @since 1.0
*/ */
public void stop() { public void stop() {
this.listener.close(); this.listener.close();

View File

@ -5,7 +5,7 @@ import lightcontainer.protocol.ProtocolWriter;
public interface ProtocolRepository { public interface ProtocolRepository {
boolean executeReader(String data); <T extends ProtocolReader.ProtocolResult> T executeReader(String data);
String executeWriter(String... datas); String executeWriter(String... datas);

View File

@ -11,11 +11,14 @@ public abstract class ProtocolReader {
this.rulePattern = Pattern.compile(pattern); this.rulePattern = Pattern.compile(pattern);
} }
public abstract class ProtocolResult {}
/** /**
* Permet de lancer la décomposition d'une commande pour en extraire les données * Permet de lancer la décomposition d'une commande pour en extraire les données
* @param data Contenu de la commande * @param data Contenu de la commande
*/ */
public boolean execute(String data) { public <T extends ProtocolResult> T execute(String data) {
Matcher ruleMatcher = this.rulePattern.matcher(data); Matcher ruleMatcher = this.rulePattern.matcher(data);
if (ruleMatcher.matches()) { if (ruleMatcher.matches()) {
@ -24,17 +27,17 @@ public abstract class ProtocolReader {
for (int i = 1; i <= groups.length; ++i) for (int i = 1; i <= groups.length; ++i)
groups[i - 1] = ruleMatcher.group(i); groups[i - 1] = ruleMatcher.group(i);
onExecuted(groups);
return true; return onExecuted(groups);
} }
return false; return null;
} }
/** /**
* Cette méthode est appelée lors de l'exécution de la règle * Cette méthode est appelée lors de l'exécution de la règle
* @param data * @param data
*/ */
protected abstract void onExecuted(String... data); protected abstract <T> T onExecuted(String... data);
} }

View File

@ -2,6 +2,9 @@ package lightcontainer.protocol.rules.reader;
import lightcontainer.protocol.ProtocolReader; import lightcontainer.protocol.ProtocolReader;
import java.util.ArrayList;
import java.util.List;
public class HelloRule extends ProtocolReader { public class HelloRule extends ProtocolReader {
private static final String PATTERN = "^HELLO ([A-Za-z0-9]{5,20}) ([0-9]{1,5})\r\n$"; private static final String PATTERN = "^HELLO ([A-Za-z0-9]{5,20}) ([0-9]{1,5})\r\n$";
@ -17,11 +20,33 @@ public class HelloRule extends ProtocolReader {
} }
@Override public class Result extends ProtocolResult {
protected void onExecuted(String... data) {
String domain = data[DOMAIN], port = data[PORT];
System.out.printf("Règle Hello avec domain=%s et port=%s\n", domain, port); private final String domain;
private final int port;
public Result(String domain, int port) {
this.domain = domain;
this.port = port;
}
public String getDomain() {
return domain;
}
public int getPort() {
return port;
}
}
@Override
protected HelloRule.Result onExecuted(String... data) {
String domain = data[DOMAIN];
int port = Integer.parseInt(data[PORT]);
System.out.printf("Regle Hello avec domain=%s et port=%s\n", domain, port);
return new HelloRule.Result(domain, port);
} }
} }

View File

@ -8,17 +8,18 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
public class ProtocolRepositoryImpl implements ProtocolRepository { public class ProtocolRepositoryImpl implements ProtocolRepository {
private Set<ProtocolReader> readers = new HashSet<>(); private final Set<ProtocolReader> readers = new HashSet<>();
private Set<ProtocolWriter> writers = new HashSet<>(); private final Set<ProtocolWriter> writers = new HashSet<>();
@Override @Override
public boolean executeReader(String data) { public <T extends ProtocolReader.ProtocolResult> T executeReader(String data) {
for (ProtocolReader reader : readers) { for (ProtocolReader reader : readers) {
if (reader.execute(data)) { T readerResult = reader.execute(data);
return true; if (readerResult != null) {
return readerResult;
} }
} }
return false; return null;
} }
@Override @Override

View File

@ -14,8 +14,12 @@ class HelloRuleTest {
ProtocolReader protocolReader = new HelloRule(); ProtocolReader protocolReader = new HelloRule();
String request = "HELLO bento 42890\r\n"; String request = "HELLO bento 42890\r\n";
// EXPECT // WHEN
assertTrue(protocolReader.execute(request)); HelloRule.Result ruleResult = protocolReader.execute(request);
// THEN
assertEquals("bento", ruleResult.getDomain());
assertEquals(42890, ruleResult.getPort());
} }
} }