corefx - initial work to add option to display throughputs received from core rest

This commit is contained in:
Blake J. Harnden 2018-12-13 09:25:37 -08:00
parent 6bbc47d61a
commit 5382ab2d30
10 changed files with 144 additions and 1 deletions

View file

@ -14,10 +14,12 @@ import com.jfoenix.controls.JFXDecorator;
import com.jfoenix.controls.JFXProgressBar;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingNode;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
@ -48,7 +50,9 @@ public class Controller implements Initializable {
@FXML private SwingNode swingNode;
@FXML private MenuItem saveXmlMenuItem;
@FXML private JFXProgressBar progressBar;
@FXML private CheckMenuItem throughputMenuItem;
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
private final Map<Integer, MobilityConfig> mobilityScripts = new HashMap<>();
private final Map<Integer, MobilityPlayerDialog> mobilityPlayerDialogs = new HashMap<>();
private Application application;
@ -228,6 +232,27 @@ public class Controller implements Initializable {
return result;
}
public void handleThroughputs(Throughputs throughputs) {
for (InterfaceThroughput interfaceThroughput : throughputs.getInterfaces()) {
int nodeId = interfaceThroughput.getNode();
CoreNode node = networkGraph.getVertex(nodeId);
Collection<CoreLink> links = networkGraph.getGraph().getIncidentEdges(node);
int interfaceId = interfaceThroughput.getNodeInterface();
for (CoreLink link : links) {
if (nodeId == link.getNodeOne()) {
if (interfaceId == link.getInterfaceOne().getId()) {
link.setThroughput(interfaceThroughput.getThroughput());
}
} else {
if (interfaceId == link.getInterfaceTwo().getId()) {
link.setThroughput(interfaceThroughput.getThroughput());
}
}
}
}
networkGraph.getGraphViewer().repaint();
}
private void setCoreDefaultServices() {
try {
coreClient.setDefaultServices(defaultServices);
@ -453,6 +478,9 @@ public class Controller implements Initializable {
// setup snackbar
Toast.setSnackbarRoot(stackPane);
// setup throughput menu item
throughputMenuItem.setOnAction(event -> executorService.submit(new ChangeThroughputTask()));
// node details
networkGraph.getGraphViewer().getPickedVertexState().addItemListener(event -> {
CoreNode node = (CoreNode) event.getItem();
@ -481,4 +509,35 @@ public class Controller implements Initializable {
}
});
}
private class ChangeThroughputTask extends Task<Boolean> {
@Override
protected Boolean call() throws Exception {
if (throughputMenuItem.isSelected()) {
return coreClient.startThroughput();
} else {
return coreClient.stopThroughput();
}
}
@Override
protected void succeeded() {
if (getValue()) {
if (throughputMenuItem.isSelected()) {
networkGraph.setShowThroughput(true);
} else {
networkGraph.setShowThroughput(false);
networkGraph.getGraph().getEdges().forEach(edge -> edge.setThroughput(0));
networkGraph.getGraphViewer().repaint();
}
} else {
Toast.error("Failure changing throughput");
}
}
@Override
protected void failed() {
Toast.error("Error changing throughput", new RuntimeException(getException()));
}
}
}

View file

@ -18,6 +18,10 @@ public interface ICoreClient {
Integer currentSession();
boolean startThroughput() throws IOException;
boolean stopThroughput() throws IOException;
void updateSession(Integer sessionId);
void updateState(SessionState state);

View file

@ -144,6 +144,18 @@ public class CoreRestClient implements ICoreClient {
return WebUtils.postFile(url, file);
}
@Override
public boolean startThroughput() throws IOException {
String url = getUrl("throughput/start");
return WebUtils.putJson(url);
}
@Override
public boolean stopThroughput() throws IOException {
String url = getUrl("throughput/stop");
return WebUtils.putJson(url);
}
@Override
public Map<String, List<String>> getDefaultServices() throws IOException {
String url = getUrl(String.format("sessions/%s/services/default", sessionId));

View file

@ -0,0 +1,9 @@
package com.core.data;
import lombok.Data;
@Data
public class BridgeThroughput {
private int node;
private Double throughput;
}

View file

@ -12,12 +12,16 @@ import lombok.NoArgsConstructor;
public class CoreLink {
@EqualsAndHashCode.Include
private Integer id;
@JsonIgnore
private Float weight = 1.0f;
@JsonIgnore
private boolean loaded = true;
@JsonIgnore
private double throughput;
@JsonIgnore
private boolean visible = true;

View file

@ -0,0 +1,12 @@
package com.core.data;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class InterfaceThroughput {
private int node;
@JsonProperty("interface")
private int nodeInterface;
private double throughput;
}

View file

@ -0,0 +1,12 @@
package com.core.data;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class Throughputs {
private List<InterfaceThroughput> interfaces = new ArrayList<>();
private List<BridgeThroughput> bridges = new ArrayList<>();
}

View file

@ -41,6 +41,7 @@ import java.util.stream.Collectors;
@Data
public class NetworkGraph {
private static final Logger logger = LogManager.getLogger();
private static final int EDGE_LABEL_OFFSET = -5;
private Controller controller;
private ObservableGraph<CoreNode, CoreLink> graph;
private StaticLayout<CoreNode, CoreLink> graphLayout;
@ -61,6 +62,9 @@ public class NetworkGraph {
private BackgroundPaintable<CoreNode, CoreLink> backgroundPaintable;
private CoreVertexLabelRenderer nodeLabelRenderer = new CoreVertexLabelRenderer();
// display options
private boolean showThroughput = false;
public NetworkGraph(Controller controller) {
this.controller = controller;
graph = new CoreObservableGraph<>(new UndirectedSimpleGraph<>());
@ -86,6 +90,14 @@ public class NetworkGraph {
});
// link render properties
renderContext.setEdgeLabelTransformer(link -> {
if (!showThroughput || link == null) {
return null;
}
double kbps = link.getThroughput() / 1000.0;
return String.format("%.2f kbps", kbps);
});
renderContext.setLabelOffset(EDGE_LABEL_OFFSET);
renderContext.setEdgeStrokeTransformer(edge -> {
LinkTypes linkType = LinkTypes.get(edge.getType());
if (LinkTypes.WIRELESS == linkType) {

View file

@ -2,7 +2,6 @@ package com.core.websocket;
import com.core.Controller;
import com.core.data.*;
import com.core.ui.dialogs.MobilityDialog;
import com.core.ui.dialogs.MobilityPlayerDialog;
import com.core.utils.JsonUtils;
import io.socket.client.IO;
@ -30,6 +29,7 @@ public class CoreWebSocket {
socket.on("event", this::handleEvents);
socket.on("config", this::handleConfigs);
socket.on("link", this::handleLinks);
socket.on("throughput", this::handleThroughputs);
socket.on(Socket.EVENT_DISCONNECT, args -> logger.info("disconnected from web socket"));
logger.info("attempting to connect to web socket!");
@ -45,6 +45,18 @@ public class CoreWebSocket {
}
}
private void handleThroughputs(Object... args) {
for (Object arg : args) {
logger.info("throughput update: {}", arg);
try {
Throughputs throughputs = JsonUtils.read(arg.toString(), Throughputs.class);
controller.handleThroughputs(throughputs);
} catch (IOException ex) {
logger.error("error getting throughputs", ex);
}
}
}
private void handleNodes(Object... args) {
for (Object arg : args) {
try {

View file

@ -2,6 +2,7 @@
<?import com.jfoenix.controls.JFXProgressBar?>
<?import javafx.embed.swing.SwingNode?>
<?import javafx.scene.control.CheckMenuItem?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
@ -40,6 +41,12 @@
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuBackground" text="Background" />
<MenuItem mnemonicParsing="false" onAction="#onSessionOptionsMenu" text="Options" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Widgets">
<items>
<CheckMenuItem fx:id="throughputMenuItem" mnemonicParsing="false" text="Throughput" />
<MenuItem mnemonicParsing="false" text="Throughput Config" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>