diff --git a/gctrl/README.md b/gctrl/README.md
new file mode 100644
index 0000000..9b6634f
--- /dev/null
+++ b/gctrl/README.md
@@ -0,0 +1,2 @@
+# General Controller
+
diff --git a/gctrl/pom.xml b/gctrl/pom.xml
new file mode 100644
index 0000000..b0efab4
--- /dev/null
+++ b/gctrl/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+ fr.laas.sara.sdci
+ fr.laas.sara.sdci.gctrl
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 9
+ 9
+
+
+
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+
+
+ de.vandermeer
+ asciitable
+ 0.3.2
+
+
+ com.github.signaflo
+ timeseries
+ 0.4
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.5
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.7.5
+
+
+
\ No newline at end of file
diff --git a/gctrl/src/main/java/Analyze.java b/gctrl/src/main/java/Analyze.java
new file mode 100644
index 0000000..62bb9d7
--- /dev/null
+++ b/gctrl/src/main/java/Analyze.java
@@ -0,0 +1,78 @@
+import java.util.List;
+
+//
+
+//* @author couedrao on 25/11/2019.
+
+//* @project gctrl
+
+//
+
+//
+//* 1)Perform complex data analysis and reasoning on the symptoms provided by the monitor function.
+//* 2)Influenced by stored knowledge data.
+//* 3)If changes are required, a change request is logically passed to the plan function.
+//*
+@SuppressWarnings({"SameParameterValue", "SynchronizeOnNonFinalField"})
+class Analyze {
+ public String gw_current_RFC = "";
+ private static int i;
+
+ void start() {
+ Main.logger(this.getClass().getSimpleName(), "Start Analyzing");
+
+ while (Main.run) {
+
+ String current_symptom = get_symptom();
+ //Main.logger(this.getClass().getSimpleName(), "Received Symptom : " + current_symptom);
+
+ update_rfc(rfc_generator(current_symptom));
+ }
+ }
+
+ //Symptom Receiver
+ private String get_symptom() {
+ synchronized (Main.monitor.gw_current_SYMP) {
+ try {
+ Main.monitor.gw_current_SYMP.wait();
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return Main.monitor.gw_current_SYMP;
+ }
+
+ //Rule-based RFC Generator
+ private String rfc_generator(String symptom) {
+ List symptoms = Main.shared_knowledge.get_symptoms();
+ List rfcs = Main.shared_knowledge.get_rfc();
+
+ if (symptom.contentEquals(symptoms.get(0)) || symptom.contentEquals(symptoms.get(2))) {
+ Main.logger(this.getClass().getSimpleName(), "RFC --> To plan : " + rfcs.get(0));
+ i = 0;
+ return rfcs.get(0);
+ } else if (symptom.contentEquals(symptoms.get(1))) {
+ i++;
+ if (i < 3) {
+ Main.logger(this.getClass().getSimpleName(), "RFC --> To plan : " + rfcs.get(1));
+ return rfcs.get(1);
+ } else {
+ Main.logger(this.getClass().getSimpleName(), "RFC --> To plan : " + "YourPlansDoNotWork");
+ return "YourPlansDoNotWork";
+ }
+ } else
+ return null;
+
+ }
+
+
+ private void update_rfc(String rfc) {
+
+ synchronized (gw_current_RFC) {
+ gw_current_RFC.notify();
+ gw_current_RFC = rfc;
+
+ }
+ }
+
+}
diff --git a/gctrl/src/main/java/Execute.java b/gctrl/src/main/java/Execute.java
new file mode 100644
index 0000000..8c9c52d
--- /dev/null
+++ b/gctrl/src/main/java/Execute.java
@@ -0,0 +1,102 @@
+import java.util.List;
+
+//
+
+//* @author couedrao on 25/11/2019.
+
+//* @project gctrl
+
+//
+
+//
+//* Changes the behavior of the managed resource using effectors Changes the behavior of the managed resource using effectors, based on the actions recommended by the plan function.
+//*
+@SuppressWarnings({"SameParameterValue", "SynchronizeOnNonFinalField"})
+class Execute {
+ private static List workflow_lists;
+ private static final MANOAPI manoapi = new MANOAPI();
+ private static final SDNCtrlAPI sdnctlrapi = new SDNCtrlAPI();
+
+ void start() throws InterruptedException {
+ Main.logger(this.getClass().getSimpleName(), "Start Execution");
+ workflow_lists = Main.shared_knowledge.get_worklow_lists();
+
+ while (Main.run) {
+ String current_plan = get_plan();
+
+ // Main.logger(this.getClass().getSimpleName(), "Received Plan : " + current_plan);
+ String[] workflow = workflow_generator(current_plan);
+ for (int i = 0; i < workflow.length; i++) {
+ Main.logger(this.getClass().getSimpleName(), "workflow [" + i + "] : " + workflow[i]);
+
+ }
+
+ for (String w : workflow) {
+ Main.logger(this.getClass().getSimpleName(), "UC : " + w);
+ switch (w) {
+ case "UC1":
+ Main.logger(this.getClass().getSimpleName(), "Nothing to do");
+ break;
+ case "UC2":
+ Main.logger(this.getClass().getSimpleName(), "Deploying GW");
+ String newdestip = manoapi.deploy_gw(Main.shared_knowledge.getGwinfo());
+ Main.shared_knowledge.setNewdestip(newdestip);
+ Main.shared_knowledge.setOldgwip(newdestip);
+ break;
+ case "UC3":
+ Main.logger(this.getClass().getSimpleName(), "Redirecting Traffic");
+ String status = sdnctlrapi.redirect_traffic(Main.shared_knowledge.getOlddestip(), Main.shared_knowledge.getNewdestip());
+ Main.logger(this.getClass().getSimpleName(), status);
+ break;
+ case "UC4":
+ Main.logger(this.getClass().getSimpleName(), "Deploying LB+GWs");
+ List newgwsip = manoapi.deploy_multi_gws_and_lb(Main.shared_knowledge.getGwsinfo());
+ Main.shared_knowledge.setLbip(newgwsip.get(0));
+ Main.shared_knowledge.setNewgwsip(newgwsip.subList(1, newgwsip.size()));
+ break;
+ case "UC5":
+ Main.logger(this.getClass().getSimpleName(), "Inserting a loadbalancer");
+ status = sdnctlrapi.insert_a_loadbalancer(Main.shared_knowledge.getOldgwip(), Main.shared_knowledge.getLbip(), Main.shared_knowledge.getNewgwsip());
+ Main.logger(this.getClass().getSimpleName(), status);
+ break;
+ case "UC6":
+ Main.logger(this.getClass().getSimpleName(), "Removing less important traffic");
+ status = sdnctlrapi.remove_less_important_traffic(Main.shared_knowledge.getImportantsrcip());
+ Main.logger(this.getClass().getSimpleName(), status);
+ break;
+ default:
+ }
+ Thread.sleep(2000);
+ continue;
+
+
+ }
+
+ }
+ }
+
+ //Plan Receiver
+ private String get_plan() {
+ synchronized (Main.plan.gw_PLAN) {
+ try {
+ Main.plan.gw_PLAN.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ return Main.plan.gw_PLAN;
+ }
+
+ //Rule-based Workflow Generator
+ private String[] workflow_generator(String plan) {
+ List plans = Main.shared_knowledge.get_plans();
+ if (plan.contentEquals(plans.get(0))) {
+ return workflow_lists.get(0).split("/");
+ } else if (plan.contentEquals(plans.get(1))) {
+ return workflow_lists.get(1).split("/");
+ } else if (plan.contentEquals(plans.get(2))) {
+ return workflow_lists.get(2).split("/");
+ } else
+ return null;
+ }
+}
diff --git a/gctrl/src/main/java/Knowledge.java b/gctrl/src/main/java/Knowledge.java
new file mode 100644
index 0000000..1145379
--- /dev/null
+++ b/gctrl/src/main/java/Knowledge.java
@@ -0,0 +1,404 @@
+import org.h2.tools.DeleteDbFiles;
+
+import java.sql.*;
+import java.util.*;
+
+//
+
+//* @author couedrao on 25/11/2019.
+
+//* @project gctrl
+
+//
+
+//
+
+//* 1)Standard data shared among the monitor analyze plan and Standard data shared among the monitor, analyze, plan and execute functions
+
+//* 2)The shared knowledge includes data such as topology information, historical logs, metrics, symptoms and policies
+
+//* 3)Created by the monitor part while execute part might update the knowledge
+
+//*
+
+class Knowledge {
+
+ private static final String DB_DRIVER = "org.h2.Driver";
+ private static final String DB_CONNECTION = "jdbc:h2:~/test";
+ private static final String DB_USER = "";
+ private static final String DB_PASSWORD = "";
+
+ static final int moving_wind = 10;
+ static final int horizon = 3;
+ static final String gw = "GW_I";
+ static final double gw_lat_threshold = 20;
+
+ /*TODO : edit symptom, rfc, workflow_lists, plan*/
+ private static final List symptom = Arrays.asList("N/A", "NOK", "OK");
+ private static final List rfc = Arrays.asList("DoNotDoAnything", "DecreaseLatencyIn" + gw);
+ private static final List workflow_lists = Arrays.asList("UC1", "UC2/UC3", "UC4/UC5/UC6");
+ private static final List plan = Arrays.asList("A", "B", "C");
+ private final Map gwinfo = new HashMap<>();
+ private final List