diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java index b0eef82..09ce174 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/ExnConnector.java @@ -180,14 +180,15 @@ public class ExnConnector { // We'll talk a lot with SAL etc, so we should maybe fire up a // thread so as not to block here. try { + ObjectNode json_body = mapper.convertValue(body, ObjectNode.class); String app_id = message.subject(); + Main.logFile("solver-solution-" + app_id + ".json", json_body); NebulousApp app = NebulousApps.get(app_id); if (app == null) { log.warn("Received solver solutions for non-existant app {}, discarding.", app_id); return; } else { log.debug("Received solver solutions for app {}", app_id); - ObjectNode json_body = mapper.convertValue(body, ObjectNode.class); app.processSolution(json_body); } } catch (Exception e) { diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/Main.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/Main.java index b1325d4..2d8072c 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/Main.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/Main.java @@ -92,10 +92,11 @@ public class Main implements Callable { } /** - * Initialization code shared between main and subcommands. Note that - * here we connect to SAL if possible, but (for now) do not start the EXN - * ActiveMQ middleware. Each main method needs to call - * `activeMQConnector.start`. + * Initialization code shared between this class and any + * subcommands: set logging level, create log directory and create + * the ActiveMQ adapter. Note that we do not start the EXN + * ActiveMQ middleware, so each main method needs to call + * `activeMQConnector.start` if needed. */ private void init() { log.debug("Beginning common startup of optimiser-controller"); diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousApp.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousApp.java index fe413c5..8954500 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousApp.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousApp.java @@ -374,7 +374,7 @@ public class NebulousApp { constant.put("Variable", variableName); constant.set("Value", value); } - + log.info("Sending AMPL file to solver"); exnConnector.getAmplMessagePublisher().send(mapper.convertValue(msg, Map.class), getUUID(), true); Main.logFile("to-solver-" + getUUID() + ".json", msg.toString()); Main.logFile("to-solver-" + getUUID() + ".ampl", ampl); diff --git a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java index ebe3460..ef52894 100644 --- a/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java +++ b/optimiser-controller/src/main/java/eu/nebulouscloud/optimiser/controller/NebulousAppDeployer.java @@ -78,15 +78,19 @@ public class NebulousAppDeployer { } /** - * Given a KubeVela file, extract how many nodes to deploy for each - * component. + * Given a KubeVela file, extract how many nodes to deploy for + * each component. Note that this can be zero, when the component + * should not be deployed at all, e.g., when there is a cloud and + * an edge version of the component. * - * We currently detect replica count with the following component trait: - * --- + * We currently look for the following component trait: + * + *
{@code
      * traits:
      *  - type: scaler
      *    properties:
      *      replicas: 2
+     * }
* * @param kubevela the parsed KubeVela file. * @return A map from component name to number of instances to generate. @@ -100,8 +104,6 @@ public class NebulousAppDeployer { if (t.at("/type").asText().equals("scaler") && t.at("/properties/replicas").canConvertToExactIntegral()) { - // Note this can be 0, in case we want to balance - // between e.g. cloud and edge result.put(c.get("name").asText(), t.at("/properties/replicas").asInt()); } @@ -204,8 +206,10 @@ public class NebulousAppDeployer { } /** - * Add affinities trait to all components, except for those with a replica - * count of 0. + * Produce a fresh KubeVela specification with added node affinity traits. + * + * We add the following trait to all components, except those with + * a replica count of 0: * *
{@code
      * traits:
@@ -279,7 +283,7 @@ public class NebulousAppDeployer {
 
         Main.logFile("worker-requirements-" + appUUID + ".txt", workerRequirements);
         Main.logFile("worker-counts-" + appUUID + ".txt", nodeCounts);
-        Main.logFile("contoller-requirements-" + appUUID + ".txt", controllerRequirements);
+        Main.logFile("controller-requirements-" + appUUID + ".txt", controllerRequirements);
         // ----------------------------------------
         // 2. Find node candidates
 
@@ -352,19 +356,30 @@ public class NebulousAppDeployer {
 
         JsonNode rewritten = addNodeAffinities(kubevela, app.getComponentMachineNames());
         String rewritten_kubevela = "---\n# Did not manage to create rewritten KubeVela";
-	try {
-	    rewritten_kubevela = yaml_mapper.writeValueAsString(rewritten);
-	} catch (JsonProcessingException e) {
+        try {
+            rewritten_kubevela = yaml_mapper.writeValueAsString(rewritten);
+        } catch (JsonProcessingException e) {
             log.error("Failed to convert KubeVela to YAML; this should never happen", e);
-	}
+        }
         Main.logFile("rewritten-kubevela-" + appUUID + ".yaml", rewritten_kubevela);
         // TODO: call deployApplication endpoint
     }
 
     /**
-     * Redeploy a running application.
+     * Given a KubeVela file, adapt the running application to its specification.
+     *
+     * The KubeVela file will have been rewritten with updated
+     * information from the solver.
+     *
+     * NOTE: this method is under development, pending the new endpoints.
+     *
+     * @param app the NebulOuS app object.
+     * @param kubevela the KubeVela file to deploy.
      */
     public static void redeployApplication(NebulousApp app, ObjectNode kubevela) {
+        String appUUID = app.getUUID();
+        log.info("Starting redeployment of {}", appUUID);
+
         // The overall flow:
         //
         // 1. Extract node requirements and node counts from the updated
@@ -378,7 +393,18 @@ public class NebulousAppDeployer {
         // 6. Call clusterScaleOut endpoint with list of added nodes
         // 7. Call deployApplication with rewritten KubeVela
         // 8. call clusterScaleIn endpoint with list of removed node names
-        
+        Main.logFile("kubevela-updated-from-solver-" + appUUID + ".yaml", kubevela);
+
+        // ------------------------------------------------------------
+        // 1. Extract node requirements
+        Map> workerRequirements = getWorkerRequirementsFromKubevela(kubevela);
+        Map nodeCounts = getNodeCountFromKubevela(kubevela);
+        List controllerRequirements = getControllerRequirements(appUUID);
+
+        Main.logFile("worker-requirements-" + appUUID + ".txt", workerRequirements);
+        Main.logFile("worker-counts-" + appUUID + ".txt", nodeCounts);
+        Main.logFile("controller-requirements-" + appUUID + ".txt", controllerRequirements);
+
     }
 
 }