diff --git a/corefx/src/main/java/com/core/Controller.java b/corefx/src/main/java/com/core/Controller.java index a5664689..6b19101c 100644 --- a/corefx/src/main/java/com/core/Controller.java +++ b/corefx/src/main/java/com/core/Controller.java @@ -61,7 +61,7 @@ public class Controller implements Initializable { // ui elements private NetworkGraph networkGraph = new NetworkGraph(this); private AnnotationToolbar annotationToolbar = new AnnotationToolbar(networkGraph); - private NodeDetails nodeDetails = new NodeDetails(); + private NodeDetails nodeDetails = new NodeDetails(this); private LinkDetails linkDetails = new LinkDetails(networkGraph); private GraphToolbar graphToolbar = new GraphToolbar(this); private MobilityPlayer mobilityPlayer = new MobilityPlayer(this); diff --git a/corefx/src/main/java/com/core/data/CoreNode.java b/corefx/src/main/java/com/core/data/CoreNode.java index 353cb22a..1884ea04 100644 --- a/corefx/src/main/java/com/core/data/CoreNode.java +++ b/corefx/src/main/java/com/core/data/CoreNode.java @@ -7,7 +7,8 @@ import lombok.NoArgsConstructor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.*; +import java.util.HashSet; +import java.util.Set; @Data @NoArgsConstructor @@ -26,8 +27,6 @@ public class CoreNode { @JsonIgnore private String icon; @JsonIgnore - private Map interfaces = new HashMap<>(); - @JsonIgnore private boolean loaded = true; public CoreNode(Integer id) { @@ -36,10 +35,6 @@ public class CoreNode { this.loaded = false; } - public CoreInterface getInterface(Integer id) { - return interfaces.get(id); - } - @JsonIgnore public String getNodeTypeKey() { if (model == null) { @@ -48,18 +43,4 @@ public class CoreNode { return String.format("%s-%s", type, model); } } - - public void addInterface(CoreInterface coreInterface) { - logger.info("adding interface node({}) {}", id, coreInterface); - interfaces.put(coreInterface.getId(), coreInterface); - } - - @JsonIgnore - public int getNextInterfaceId() { - if (interfaces.isEmpty()) { - return 0; - } else { - return Collections.max(interfaces.keySet()) + 1; - } - } } diff --git a/corefx/src/main/java/com/core/graph/NetworkGraph.java b/corefx/src/main/java/com/core/graph/NetworkGraph.java index 235dec64..b7206474 100644 --- a/corefx/src/main/java/com/core/graph/NetworkGraph.java +++ b/corefx/src/main/java/com/core/graph/NetworkGraph.java @@ -33,8 +33,10 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.*; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; @Data @@ -119,7 +121,7 @@ public class NetworkGraph { Toast.error("Node terminal command failed"); } } catch (InterruptedException ex) { - logger.error("error waiting for terminal to start"); + logger.error("error waiting for terminal to start", ex); } } catch (IOException ex) { logger.error("error launching terminal", ex); @@ -204,20 +206,20 @@ public class NetworkGraph { // create interfaces for nodes int sub = coreAddresses.getSubnet( - nodeOne.getInterfaces().values(), - nodeTwo.getInterfaces().values() + getInterfaces(nodeOne), + getInterfaces(nodeTwo) ); link.setNodeOne(nodeOne.getId()); - int interfaceOneId = nodeOne.getNextInterfaceId(); if (isNode(nodeOne)) { + int interfaceOneId = nextInterfaceId(nodeOne); CoreInterface interfaceOne = createInterface(nodeOne, sub, interfaceOneId); link.setInterfaceOne(interfaceOne); } link.setNodeTwo(nodeTwo.getId()); if (isNode(nodeTwo)) { - int interfaceTwoId = nodeTwo.getNextInterfaceId(); + int interfaceTwoId = nextInterfaceId(nodeTwo); CoreInterface interfaceTwo = createInterface(nodeTwo, sub, interfaceTwoId); link.setInterfaceTwo(interfaceTwo); } @@ -229,18 +231,53 @@ public class NetworkGraph { } } + public List getInterfaces(CoreNode node) { + return graph.getIncidentEdges(node).stream() + .map(link -> { + if (node.getId().equals(link.getNodeOne())) { + return link.getInterfaceOne(); + } else { + return link.getInterfaceTwo(); + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + private int nextInterfaceId(CoreNode node) { + Set interfaceIds = graph.getIncidentEdges(node).stream() + .map(link -> { + if (node.getId().equals(link.getNodeOne())) { + return link.getInterfaceOne(); + } else { + return link.getInterfaceTwo(); + } + }) + .filter(Objects::nonNull) + .map(CoreInterface::getId) + .collect(Collectors.toSet()); + + int i = 0; + while (true) { + if (!interfaceIds.contains(i)) { + return i; + } + + i += 1; + } + } + private boolean isNode(CoreNode node) { return node.getType() == NodeType.DEFAULT; } private CoreInterface createInterface(CoreNode node, int sub, int interfaceId) { - String nodeOneIp4 = coreAddresses.getIp4Address(sub, node.getId()); CoreInterface coreInterface = new CoreInterface(); coreInterface.setId(interfaceId); coreInterface.setName(String.format("eth%s", interfaceId)); + String nodeOneIp4 = coreAddresses.getIp4Address(sub, node.getId()); coreInterface.setIp4(nodeOneIp4); coreInterface.setIp4Mask(CoreAddresses.IP4_MASK); - node.addInterface(coreInterface); return coreInterface; } @@ -322,18 +359,8 @@ public class NetworkGraph { public void addLink(CoreLink link) { link.setId(linkId++); - CoreNode nodeOne = nodeMap.get(link.getNodeOne()); - CoreInterface interfaceOne = link.getInterfaceOne(); - if (interfaceOne != null) { - nodeOne.addInterface(interfaceOne); - } - CoreNode nodeTwo = nodeMap.get(link.getNodeTwo()); - CoreInterface interfaceTwo = link.getInterfaceTwo(); - if (interfaceTwo != null) { - nodeTwo.addInterface(interfaceTwo); - } boolean isVisible = !isWirelessLink(nodeOne, nodeTwo); link.setVisible(isVisible); @@ -362,26 +389,4 @@ public class NetworkGraph { } } } - - private void linkNodes(CoreNode nodeOne, CoreNode nodeTwo, CoreLink link) { - // create interfaces for nodes - int sub = coreAddresses.getSubnet( - nodeOne.getInterfaces().values(), - nodeTwo.getInterfaces().values() - ); - - link.setNodeOne(nodeOne.getId()); - int interfaceOneId = nodeOne.getNextInterfaceId(); - if (isNode(nodeOne)) { - CoreInterface interfaceOne = createInterface(nodeOne, sub, interfaceOneId); - link.setInterfaceOne(interfaceOne); - } - - link.setNodeTwo(nodeTwo.getId()); - if (isNode(nodeTwo)) { - int interfaceTwoId = nodeTwo.getNextInterfaceId(); - CoreInterface interfaceTwo = createInterface(nodeTwo, sub, interfaceTwoId); - link.setInterfaceTwo(interfaceTwo); - } - } } diff --git a/corefx/src/main/java/com/core/ui/NodeDetails.java b/corefx/src/main/java/com/core/ui/NodeDetails.java index f506a2e7..b18ef979 100644 --- a/corefx/src/main/java/com/core/ui/NodeDetails.java +++ b/corefx/src/main/java/com/core/ui/NodeDetails.java @@ -1,9 +1,16 @@ package com.core.ui; +import com.core.Controller; import com.core.data.CoreInterface; +import com.core.data.CoreLink; import com.core.data.CoreNode; import com.core.data.NodeType; +import com.jfoenix.controls.JFXButton; +import com.jfoenix.controls.JFXListView; +import com.jfoenix.controls.JFXScrollPane; import com.jfoenix.controls.JFXTextField; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Insets; @@ -12,8 +19,6 @@ import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.Separator; import javafx.scene.layout.GridPane; -import javafx.scene.text.Font; -import javafx.scene.text.FontWeight; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -22,13 +27,18 @@ import java.io.IOException; public class NodeDetails extends ScrollPane { private static final Logger logger = LogManager.getLogger(); private static final int START_INDEX = 1; + private final Controller controller; + + @FXML + private ScrollPane scrollPane; @FXML private GridPane gridPane; private int index = START_INDEX; - public NodeDetails() { + public NodeDetails(Controller controller) { + this.controller = controller; FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/node_details.fxml")); loader.setRoot(this); loader.setController(this); @@ -60,18 +70,54 @@ public class NodeDetails extends ScrollPane { addRow("X", node.getPosition().getX().toString()); addRow("Y", node.getPosition().getY().toString()); - for (CoreInterface coreInterface : node.getInterfaces().values()) { + for (CoreLink link : controller.getNetworkGraph().getGraph().getIncidentEdges(node)) { + CoreNode linkedNode; + CoreInterface coreInterface; + if (node.getId().equals(link.getNodeOne())) { + coreInterface = link.getInterfaceOne(); + linkedNode = controller.getNetworkGraph().getNodeMap().get(link.getNodeTwo()); + } else { + coreInterface = link.getInterfaceTwo(); + linkedNode = controller.getNetworkGraph().getNodeMap().get(link.getNodeOne()); + } + + if (coreInterface == null) { + continue; + } + addSeparator(); + if (linkedNode.getType() == NodeType.EMANE) { + addButton(linkedNode.getName(), event -> controller.getNodeEmaneDialog().showDialog(linkedNode)); + } + + if (linkedNode.getType() == NodeType.WLAN) { + addButton(linkedNode.getName(), event -> controller.getNodeWlanDialog().showDialog(linkedNode)); + } addInterface(coreInterface); } + if (!node.getServices().isEmpty()) { addSeparator(); addLabel("Services"); + JFXListView listView = new JFXListView<>(); + listView.setMouseTransparent(true); + listView.setFocusTraversable(false); for (String service : node.getServices()) { - gridPane.add(new Label(service), 0, index++, 2, 1); + listView.getItems().add(service); } + gridPane.add(listView, 0, index++, 2, 1); } + + JFXScrollPane.smoothScrolling(scrollPane); + } + + private void addButton(String text, EventHandler handler) { + JFXButton emaneButton = new JFXButton(text); + emaneButton.getStyleClass().add("core-button"); + emaneButton.setMaxWidth(Double.MAX_VALUE); + emaneButton.setOnAction(handler); + gridPane.add(emaneButton, 0, index++, 2, 1); } private void addLabel(String text) { diff --git a/corefx/src/main/resources/fxml/node_details.fxml b/corefx/src/main/resources/fxml/node_details.fxml index 9d0fe46b..e6665e04 100644 --- a/corefx/src/main/resources/fxml/node_details.fxml +++ b/corefx/src/main/resources/fxml/node_details.fxml @@ -8,7 +8,7 @@ - +