Change format of message to solver

Use first utility function as objective function, for now

Change-Id: I415c9402282b0ca89b2cf45d56346fc06ba56ea5
This commit is contained in:
Rudi Schlatte
2024-01-29 10:17:13 +01:00
parent d49e9d549c
commit 886c81fe63
2 changed files with 34 additions and 7 deletions

View File

@@ -106,7 +106,7 @@ public class AMPLGenerator {
private static void generateUtilityFunctions(NebulousApp app, PrintWriter out) {
out.println("# Utility functions");
for (JsonNode f : app.getOriginalAppMessage().withArray(NebulousApp.utility_function_path)) {
for (JsonNode f : app.getUtilityFunctions().values()) {
String formula = replaceVariables(f.get("formula").asText(), f.withObject("mapping"));
out.format("# %s : %s%n", f.get("name").asText(), f.get("formula").asText());
out.format("%s %s :%n %s;%n",
@@ -178,7 +178,7 @@ public class AMPLGenerator {
ObjectNode slo = app.getOriginalAppMessage().withObject(NebulousApp.constraints_path);
slo.findParents("key").forEach(keyNode -> result.add(keyNode.asText()));
// collect from utility functions
for (JsonNode function : app.getOriginalAppMessage().withArray(NebulousApp.utility_function_path)) {
for (JsonNode function : app.getUtilityFunctions().values()) {
function.withObject("mapping").elements()
.forEachRemaining(node -> result.add(node.asText()));
}

View File

@@ -50,7 +50,7 @@ public class NebulousApp {
/** Locations of the UUID and name in the app creation message (String) */
private static final JsonPointer uuid_path = JsonPointer.compile("/application/uuid");
private static final JsonPointer name_path = JsonPointer.compile("/application/name");
public static final JsonPointer utility_function_path = JsonPointer.compile("/utility_functions");
private static final JsonPointer utility_function_path = JsonPointer.compile("/utility_functions");
public static final JsonPointer constraints_path = JsonPointer.compile("/slo");
/** The YAML converter */
@@ -102,7 +102,8 @@ public class NebulousApp {
@Getter private Map<String, JsonNode> compositeMetrics = new HashMap<>();
/** The app's performance indicators, a map from key to the defining JSON node. */
@Getter private Map<String, JsonNode> performanceIndicators = new HashMap<>();
/** The app's utility functions; the AMPL solver will optimize for one of these. */
@Getter private Map<String, JsonNode> utilityFunctions = new HashMap<>();
/** When an app gets deployed or redeployed, this is where we send the AMPL file */
private Publisher ampl_message_channel;
/** Have we ever been deployed? I.e., when we rewrite KubeVela, are there
@@ -135,6 +136,9 @@ public class NebulousApp {
kubevela_variable_paths.put(p.get("key").asText(),
yqPathToJsonPointer(p.get("path").asText()));
}
for (JsonNode f : originalAppMessage.withArray(utility_function_path)) {
utilityFunctions.put(f.get("key").asText(), f);
}
// We need to know which metrics are raw, composite, and which ones
// are performance indicators in disguise.
@@ -171,6 +175,10 @@ public class NebulousApp {
// What's left is neither a raw nor composite metric.
performanceIndicators.put(m.get("key").asText(), m);
}
for (JsonNode f : app_message.withArray(utility_function_path)) {
// What's left is neither a raw nor composite metric.
utilityFunctions.put(f.get("key").asText(), f);
}
log.debug("New App instantiated: Name='{}', UUID='{}'", name, UUID);
}
@@ -312,7 +320,7 @@ public class NebulousApp {
}
/**
* Calculate AMPL file and send it off to the right channel.
* Calculate AMPL file and send it off to the solver.
*/
public void sendAMPL() {
if (ampl_message_channel == null) {
@@ -321,14 +329,33 @@ public class NebulousApp {
}
String ampl = AMPLGenerator.generateAMPL(this);
ObjectNode msg = mapper.createObjectNode();
msg.put(getUUID() + ".ampl", ampl);
msg.put("FileName", getUUID() + ".ampl"); // TODO: check if filename needs to be unique
msg.put("FileContent", ampl);
msg.put("ObjectiveFunction", getObjectiveFunction());
ampl_message_channel.send(mapper.convertValue(msg, Map.class), getUUID());
Main.logFile(getUUID() + "to-solver.json", msg.toString());
Main.logFile(getUUID() + ".ampl", ampl);
}
/**
* The objective function to use. In case the app creation message
* specifies more than one and doesn't indicate which one to use, choose
* the first one.
*
* @return the objective function specified in the app creation message.
*/
private String getObjectiveFunction() {
ArrayNode utility_functions = originalAppMessage.withArray(utility_function_path);
if (utility_functions.size() == 0) {
log.warn("No utility function given in app message; solver will likely complain");
return "";
} else {
return utility_functions.get(0).get("key").asText();
}
}
/**
* Handle incoming solver message.
*
* @param solution The message from the solver, containing a field