diff --git a/.idea/.gitignore b/.idea/.gitignore
index 13566b8..73f69e0 100644
--- a/.idea/.gitignore
+++ b/.idea/.gitignore
@@ -1,8 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..d8e9561
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..601f39c
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries-with-intellij-classes.xml b/.idea/libraries-with-intellij-classes.xml
new file mode 100644
index 0000000..9fa3156
--- /dev/null
+++ b/.idea/libraries-with-intellij-classes.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 5d98256..3e79c5f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,7 +4,5 @@
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/java/lightcontainer/App.java b/app/src/main/java/lightcontainer/App.java
index aa63180..e590d9d 100644
--- a/app/src/main/java/lightcontainer/App.java
+++ b/app/src/main/java/lightcontainer/App.java
@@ -3,12 +3,30 @@
*/
package lightcontainer;
-public class App {
- public String getGreeting() {
- return "Hello World!";
- }
+import lightcontainer.domains.StoreMulticastRunnable;
+import lightcontainer.protocol.Protocol;
+import java.util.HashMap;
+import java.util.Map;
+
+public class App {
public static void main(String[] args) {
- System.out.println(new App().getGreeting());
+ System.out.println("Hello World !");
+
+ int port = 42500;
+ String ip = "226.0.0.1";
+
+ StoreMulticastRunnable multicast = new StoreMulticastRunnable(ip, port);
+ (new Thread(multicast)).start();
+
+ // Sleep
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ // Close
+ multicast.stop();
}
}
diff --git a/app/src/main/java/lightcontainer/domains/FileFrontEnd.java b/app/src/main/java/lightcontainer/domains/FileFrontEnd.java
new file mode 100644
index 0000000..6916615
--- /dev/null
+++ b/app/src/main/java/lightcontainer/domains/FileFrontEnd.java
@@ -0,0 +1,5 @@
+package lightcontainer.domains;
+
+public class FileFrontEnd {
+
+}
diff --git a/app/src/main/java/lightcontainer/domains/StoreMulticastRunnable.java b/app/src/main/java/lightcontainer/domains/StoreMulticastRunnable.java
new file mode 100644
index 0000000..f6aede3
--- /dev/null
+++ b/app/src/main/java/lightcontainer/domains/StoreMulticastRunnable.java
@@ -0,0 +1,70 @@
+package lightcontainer.domains;
+
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+/**
+ * StoreMulticastRunnable
+ *
+ * Class listening to the announcement of new StoreBackEnd.
+ * Allowing it to be used as a storage unit.
+ *
+ * @version 1.0
+ * @since 1.0
+ *
+ * @see Runnable
+ * @author Jérémi NIHART
+ */
+public class StoreMulticastRunnable implements Runnable {
+ // Variable
+ private final String multicast_address;
+ private final int multicast_port;
+
+ private final byte[] buffer = new byte[256];
+ private MulticastSocket listener;
+
+ // Constructor
+ public StoreMulticastRunnable(String multicast_address, int multicast_port) {
+ this.multicast_address = multicast_address;
+ this.multicast_port = multicast_port;
+ }
+
+ /**
+ * Start Multicast listening on indicated port and IP group.
+ *
+ * @since 1.0
+ *
+ * @see MulticastSocket#receive(DatagramPacket)
+ * @see DatagramPacket
+ */
+ @Override
+ public void run() {
+ try {
+ // Create a new listening socket
+ this.listener = new MulticastSocket(this.multicast_port);
+ // Create an identifier for the multicast group on the specified ip
+ InetAddress listener_group = InetAddress.getByName(this.multicast_address);
+ // Creation of a packet for the information received
+ DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
+ // Add the listener to the multicast group
+ listener.joinGroup(listener_group);
+ while(true) {
+ listener.receive(packet);
+ String data = new String(packet.getData(), 0, packet.getLength());
+ System.out.println(data); // TODO ajouter un controller et lui signaler qu'il y a un nouveau StoreBackEnd
+ }
+ } catch (Exception ignore) { }
+ }
+
+ /**
+ * Closes the MulticastSocket connection and aborts the listening and infinite listening loop.
+ *
+ * @since 1.0
+ *
+ * @see StoreMulticastRunnable#run()
+ */
+ public void stop() {
+ this.listener.close();
+ }
+}
diff --git a/app/src/main/java/lightcontainer/protocol/HelloRule.java b/app/src/main/java/lightcontainer/protocol/HelloRule.java
new file mode 100644
index 0000000..c9c2b94
--- /dev/null
+++ b/app/src/main/java/lightcontainer/protocol/HelloRule.java
@@ -0,0 +1,31 @@
+package lightcontainer.protocol;
+
+public class HelloRule extends Protocol {
+ // Variables
+
+ // Constructor
+ protected HelloRule() {
+ super("HELLO", "HELLO "); // TODO : add the regex here (sbe_hello = "HELLO bl domain bl port line")
+ }
+
+ /**
+ * Execute the rule on a command.
+ *
+ * This function allows you to check a command and process those groups (parameters)
+ * use the utility functions of {@link Protocol} to facilitate processing, see @see.
+ *
+ * @param cmd Command on which to execute the rule.
+ * @see Protocol#execute(String)
+ * @see #matcherCheck(String)
+ * @see #matcherGetGroups()
+ * @since 1.0
+ */
+ @Override
+ public void execute(String cmd) {
+ if (matcherCheck(cmd)) {
+ System.out.println("Good rule ;-) !");
+ } else {
+ System.out.println("OUPPS unknown rule !");
+ }
+ }
+}
diff --git a/app/src/main/java/lightcontainer/protocol/Protocol.java b/app/src/main/java/lightcontainer/protocol/Protocol.java
new file mode 100644
index 0000000..e7449f3
--- /dev/null
+++ b/app/src/main/java/lightcontainer/protocol/Protocol.java
@@ -0,0 +1,125 @@
+package lightcontainer.protocol;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Protocol
+ *
+ * Class allowing to define new rules for the LightContainer protocol,
+ * also provides utility functions to work with regexes and the command to compare.
+ *
+ * @version 1.0
+ * @since 1.0
+ *
+ * @see Pattern
+ * @author Jérémi NIHART
+ */
+public abstract class Protocol {
+ // Variables
+ private final String rule;
+ private final Pattern rulePattern;
+ private List groups;
+
+ /**
+ * Protocol constructor
+ * @param rule Command (e.g: LOGIN).
+ * @param regex Regex to compile and use for this command (e.g: LOGIN ([A-Z0-9a-z]{1,20})).
+ * Do not forget to define the groups in the regex.
+ */
+ protected Protocol(String rule, String regex) {
+ this.rule = rule;
+ this.rulePattern = Pattern.compile(regex);
+ }
+
+ /**
+ * Retrieve, the name of the Rule.
+ *
+ * @return Name of this rule.
+ *
+ * @since 1.0
+ */
+ public String getRule() {
+ return this.rule;
+ }
+
+ /**
+ * Check if a command matches the rule with the rule matcher.
+ *
+ * @return True : if the command match with the rule.
+ * False though.
+ * @param cmd Command to verify with the rule matcher.
+ *
+ * @since 1.0
+ */
+ protected boolean matcherCheck(String cmd) {
+ Matcher ruleMatcher = this.rulePattern.matcher(cmd);
+ if (ruleMatcher.matches()) {
+ this.groups = new ArrayList<>();
+ for (int i=1; i <= ruleMatcher.groupCount(); i++) this.groups.add(ruleMatcher.group(i));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get a list of all the groups extracted from the previously matched command with {@link #matcherCheck(String)}.
+ *
+ * Requires to have run {@link #matcherCheck(String)}
+ *
+ * @return String list containing all the groups extrapolated from the command.
+ *
+ * @since 1.0
+ *
+ * @see Protocol#matcherCheck(String)
+ */
+ protected List matcherGetGroups() {
+ return this.groups;
+ }
+
+ /**
+ * Execute the rule on a command.
+ *
+ * This function allows you to check a command and process those groups (parameters)
+ * use the utility functions of {@link Protocol} to facilitate processing, see @see.
+ *
+ * @param cmd Command on which to execute the rule.
+ *
+ * @since 1.0
+ *
+ * @see Protocol#execute(String)
+ * @see #matcherCheck(String)
+ * @see #matcherGetGroups()
+ */
+ public abstract void execute(String cmd);
+
+ /**
+ * Retrieve, the hashcode of the rule.
+ *
+ * @return Rule hashcode.
+ *
+ * @since 1.0
+ */
+ @Override
+ public int hashCode() {
+ return rule.hashCode() % 8;
+ }
+
+ /**
+ * Compare the equality of two rules.
+ *
+ * @return True : if the rules are equals
+ * False if not.
+ *
+ * @since 1.0
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) return true;
+ if (!(obj instanceof Protocol)) return false;
+ final Protocol other = (Protocol) obj;
+ return hashCode() == other.hashCode();
+ }
+}
diff --git a/app/src/test/java/lightcontainer/AppTest.java b/app/src/test/java/lightcontainer/AppTest.java
index f435009..9d64c1d 100644
--- a/app/src/test/java/lightcontainer/AppTest.java
+++ b/app/src/test/java/lightcontainer/AppTest.java
@@ -7,8 +7,8 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class AppTest {
- @Test void appHasAGreeting() {
- App classUnderTest = new App();
- assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
- }
+// @Test void appHasAGreeting() {
+// App classUnderTest = new App();
+// assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
+// }
}