Small fixes; handle metrics in local testing
Change-Id: I5481fa53baabc3a962dc84fdfd2ad8ef0888261a
This commit is contained in:
parent
d59b05b342
commit
6e9d2d771f
@ -2,6 +2,7 @@ package eu.nebulouscloud.optimiser.controller;
|
|||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -25,6 +26,17 @@ import static net.logstash.logback.argument.StructuredArguments.keyValue;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AMPLGenerator {
|
public class AMPLGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the app's metric list.
|
||||||
|
*/
|
||||||
|
public static List<String> getMetricList(NebulousApp app) {
|
||||||
|
List<String> metrics = new ArrayList<>();
|
||||||
|
app.getRawMetrics().forEach((k, v) -> metrics.add(k));
|
||||||
|
app.getCompositeMetrics().forEach((k, v) -> metrics.add(k));
|
||||||
|
return metrics;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate AMPL code for the app, based on the parameter definition(s).
|
* Generate AMPL code for the app, based on the parameter definition(s).
|
||||||
* Public for testability, not because we'll be calling it outside of its
|
* Public for testability, not because we'll be calling it outside of its
|
||||||
@ -172,7 +184,7 @@ public class AMPLGenerator {
|
|||||||
out.format("param %s; # %s%n", name, m.get("name").asText());
|
out.format("param %s; # %s%n", name, m.get("name").asText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out.println("## Composite metrics");
|
out.println("## Composite metrics");
|
||||||
for (final JsonNode m : app.getCompositeMetrics().values()) {
|
for (final JsonNode m : app.getCompositeMetrics().values()) {
|
||||||
String name = m.get("name").asText();
|
String name = m.get("name").asText();
|
||||||
@ -216,7 +228,7 @@ public class AMPLGenerator {
|
|||||||
if (allMetrics.contains(name)) result.add(name);
|
if (allMetrics.contains(name)) result.add(name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +294,7 @@ public class AMPLGenerator {
|
|||||||
int lengthDiff = 0;
|
int lengthDiff = 0;
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
String var = matcher.group(1);
|
String var = matcher.group(1);
|
||||||
|
|
||||||
JsonNode re = StreamSupport.stream(Spliterators.spliteratorUnknownSize(mappings.elements(), Spliterator.ORDERED), false)
|
JsonNode re = StreamSupport.stream(Spliterators.spliteratorUnknownSize(mappings.elements(), Spliterator.ORDERED), false)
|
||||||
.filter(v -> v.at("/name").asText().equals(var))
|
.filter(v -> v.at("/name").asText().equals(var))
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
|
@ -143,9 +143,9 @@ public class ExnConnector {
|
|||||||
labelNodes = new SyncedPublisher("labelNodes", "eu.nebulouscloud.exn.sal.cluster.label", true, true);
|
labelNodes = new SyncedPublisher("labelNodes", "eu.nebulouscloud.exn.sal.cluster.label", true, true);
|
||||||
deployCluster = new SyncedPublisher("deployCluster", "eu.nebulouscloud.exn.sal.cluster.deploy", true, true);
|
deployCluster = new SyncedPublisher("deployCluster", "eu.nebulouscloud.exn.sal.cluster.deploy", true, true);
|
||||||
deployApplication = new SyncedPublisher("deployApplication", "eu.nebulouscloud.exn.sal.cluster.deployapplication", true, true);
|
deployApplication = new SyncedPublisher("deployApplication", "eu.nebulouscloud.exn.sal.cluster.deployapplication", true, true);
|
||||||
scaleOut = new SyncedPublisher("scaleOut", "eu.nebulouscloud.exn.sal.scale.out", true, true);
|
scaleOut = new SyncedPublisher("scaleOut", "eu.nebulouscloud.exn.sal.cluster.scaleout", true, true);
|
||||||
scaleIn = new SyncedPublisher("scaleIn", "eu.nebulouscloud.exn.sal.scale.in", true, true);
|
scaleIn = new SyncedPublisher("scaleIn", "eu.nebulouscloud.exn.sal.cluster.scalein", true, true);
|
||||||
deleteCluster = new SyncedPublisher("deployCluster", "eu.nebulouscloud.exn.sal.cluster.delete", true, true);
|
deleteCluster = new SyncedPublisher("deleteCluster", "eu.nebulouscloud.exn.sal.cluster.delete", true, true);
|
||||||
|
|
||||||
conn = new Connector("optimiser_controller",
|
conn = new Connector("optimiser_controller",
|
||||||
callback,
|
callback,
|
||||||
@ -699,7 +699,7 @@ public class ExnConnector {
|
|||||||
superfluousNodes.forEach(nodeName -> body.add(nodeName));
|
superfluousNodes.forEach(nodeName -> body.add(nodeName));
|
||||||
Map<String, Object> msg;
|
Map<String, Object> msg;
|
||||||
try {
|
try {
|
||||||
msg = Map.of("metaData", Map.of("user", "admin"),
|
msg = Map.of("metaData", Map.of("user", "admin", "clusterName", clusterName),
|
||||||
"body", mapper.writeValueAsString(body));
|
"body", mapper.writeValueAsString(body));
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
log.error("Could not convert JSON to string (this should never happen)",
|
log.error("Could not convert JSON to string (this should never happen)",
|
||||||
|
@ -19,7 +19,7 @@ import picocli.CommandLine.ParentCommand;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Command(name = "local",
|
@Command(name = "local",
|
||||||
aliases = {"l"},
|
aliases = {"l"},
|
||||||
description = "Handle a single app creation message from the command line, printing its AMPL. If an ActiveMQ connection is specified, additionally send a message to the solver.",
|
description = "Start single app from the command line.",
|
||||||
mixinStandardHelpOptions = true)
|
mixinStandardHelpOptions = true)
|
||||||
public class LocalExecution implements Callable<Integer> {
|
public class LocalExecution implements Callable<Integer> {
|
||||||
|
|
||||||
@ -28,8 +28,12 @@ public class LocalExecution implements Callable<Integer> {
|
|||||||
@ParentCommand
|
@ParentCommand
|
||||||
private Main main;
|
private Main main;
|
||||||
|
|
||||||
@Parameters(description = "The file containing a JSON app creation message")
|
@Parameters(description = "The file containing a JSON app creation message, as sent by the GUI")
|
||||||
private Path app_creation_msg;
|
private Path appCreationMessage;
|
||||||
|
|
||||||
|
@Parameters(description = "The file containing a JSON performance indicator message, as sent by the utility evaluator")
|
||||||
|
private Path perfIndicatorMessage;
|
||||||
|
|
||||||
|
|
||||||
@Option(names = { "--deploy" },
|
@Option(names = { "--deploy" },
|
||||||
description = "Deploy application (default true).",
|
description = "Deploy application (default true).",
|
||||||
@ -37,12 +41,6 @@ public class LocalExecution implements Callable<Integer> {
|
|||||||
negatable = true)
|
negatable = true)
|
||||||
private boolean deploy;
|
private boolean deploy;
|
||||||
|
|
||||||
@Option(names = { "--ampl" },
|
|
||||||
description = "Send AMPL file to solver (default true).",
|
|
||||||
defaultValue = "true", fallbackValue = "true",
|
|
||||||
negatable = true)
|
|
||||||
private boolean sendAMPL;
|
|
||||||
|
|
||||||
@Override public Integer call() {
|
@Override public Integer call() {
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
CountDownLatch exn_synchronizer = new CountDownLatch(1);
|
CountDownLatch exn_synchronizer = new CountDownLatch(1);
|
||||||
@ -50,24 +48,32 @@ public class LocalExecution implements Callable<Integer> {
|
|||||||
if (connector != null) {
|
if (connector != null) {
|
||||||
connector.start(exn_synchronizer);
|
connector.start(exn_synchronizer);
|
||||||
}
|
}
|
||||||
JsonNode msg;
|
JsonNode app_msg = null;
|
||||||
|
JsonNode perf_msg = null;
|
||||||
try {
|
try {
|
||||||
msg = mapper.readTree(Files.readString(app_creation_msg, StandardCharsets.UTF_8));
|
app_msg = mapper.readTree(Files.readString(appCreationMessage, StandardCharsets.UTF_8));
|
||||||
|
perf_msg = mapper.readTree(Files.readString(perfIndicatorMessage, StandardCharsets.UTF_8));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Could not read an input file: {}", app_creation_msg, e);
|
log.error("Could not read an input file: {}",
|
||||||
|
app_msg == null ? appCreationMessage : perfIndicatorMessage, e);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
NebulousApp app = NebulousApp.newFromAppMessage(msg, connector);
|
NebulousApp app = NebulousApp.newFromAppMessage(app_msg, connector);
|
||||||
|
app.setStateReady(perf_msg);
|
||||||
if (connector != null) {
|
if (connector != null) {
|
||||||
if (sendAMPL) {
|
|
||||||
log.debug("Sending AMPL to channel {}", connector.getAmplMessagePublisher());
|
|
||||||
app.sendAMPL();
|
|
||||||
System.out.println(AMPLGenerator.generateAMPL(app));
|
|
||||||
}
|
|
||||||
if (deploy) {
|
if (deploy) {
|
||||||
log.debug("Deploying application", connector.getAmplMessagePublisher());
|
log.debug("Deploying application", connector.getAmplMessagePublisher());
|
||||||
app.setStateReady(null); // TODO: insert second file here
|
|
||||||
app.deployUnmodifiedApplication();
|
app.deployUnmodifiedApplication();
|
||||||
|
} else {
|
||||||
|
String ampl = AMPLGenerator.generateAMPL(app);
|
||||||
|
System.out.println("--------------------");
|
||||||
|
System.out.println("AMPL");
|
||||||
|
System.out.println("--------------------");
|
||||||
|
System.out.println(ampl);
|
||||||
|
System.out.println("--------------------");
|
||||||
|
System.out.println("Metrics");
|
||||||
|
System.out.println("--------------------");
|
||||||
|
AMPLGenerator.getMetricList(app).forEach(System.out::println);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (connector != null) {
|
if (connector != null) {
|
||||||
|
@ -106,6 +106,7 @@ public class NebulousApp {
|
|||||||
private static final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
|
private static final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
|
||||||
|
|
||||||
/** General-purpose object mapper */
|
/** General-purpose object mapper */
|
||||||
|
@Getter
|
||||||
private static final ObjectMapper jsonMapper = new ObjectMapper();
|
private static final ObjectMapper jsonMapper = new ObjectMapper();
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
@ -559,8 +560,7 @@ public class NebulousApp {
|
|||||||
Publisher metricsChannel = exnConnector.getMetricListPublisher();
|
Publisher metricsChannel = exnConnector.getMetricListPublisher();
|
||||||
ObjectNode msg = jsonMapper.createObjectNode();
|
ObjectNode msg = jsonMapper.createObjectNode();
|
||||||
ArrayNode metricNames = msg.withArray("/metrics");
|
ArrayNode metricNames = msg.withArray("/metrics");
|
||||||
getRawMetrics().forEach((k, v) -> metricNames.add(k));
|
AMPLGenerator.getMetricList(this).forEach(metricNames::add);
|
||||||
getCompositeMetrics().forEach((k, v) -> metricNames.add(k));
|
|
||||||
log.info("Sending metric list", keyValue("appId", UUID));
|
log.info("Sending metric list", keyValue("appId", UUID));
|
||||||
metricsChannel.send(jsonMapper.convertValue(msg, Map.class), getUUID(), true);
|
metricsChannel.send(jsonMapper.convertValue(msg, Map.class), getUUID(), true);
|
||||||
Main.logFile("metric-names-" + getUUID() + ".json", msg.toPrettyString());
|
Main.logFile("metric-names-" + getUUID() + ".json", msg.toPrettyString());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user