Merge branch 'develop' of https://github.com/coreemu/core into develop

This commit is contained in:
Blake Harnden 2019-07-11 13:09:07 -07:00
commit 60588eabbb
14 changed files with 170 additions and 141 deletions

View file

@ -140,36 +140,15 @@ public class Controller implements Initializable {
Platform.runLater(() -> borderPane.setRight(null)); Platform.runLater(() -> borderPane.setRight(null));
// get session to join // get session to join
Session session = coreClient.getSession(sessionId); Session session = coreClient.joinSession(sessionId);
SessionState sessionState = SessionState.get(session.getState());
// update client to use this session
coreClient.updateSession(sessionId);
coreClient.updateState(sessionState);
// setup event handlers
coreClient.setupEventHandlers(this);
// display all nodes // display all nodes
logger.info("joining core session({}) state({}): {}", sessionId, sessionState, session);
for (CoreNode node : session.getNodes()) { for (CoreNode node : session.getNodes()) {
NodeType nodeType = NodeType.find(node.getType(), node.getModel());
if (nodeType == null) {
logger.info(String.format("failed to find node type(%s) model(%s): %s",
node.getType(), node.getModel(), node.getName()));
continue;
}
node.setNodeType(nodeType);
networkGraph.addNode(node); networkGraph.addNode(node);
} }
// display all links // display all links
for (CoreLink link : session.getLinks()) { for (CoreLink link : session.getLinks()) {
if (link.getInterfaceOne() != null || link.getInterfaceTwo() != null) {
link.setType(LinkTypes.WIRED.getValue());
}
networkGraph.addLink(link); networkGraph.addLink(link);
} }
@ -448,6 +427,7 @@ public class Controller implements Initializable {
connectToCore(address, port); connectToCore(address, port);
logger.info("controller initialize"); logger.info("controller initialize");
coreClient.initialize(this);
swingNode.setContent(networkGraph.getGraphViewer()); swingNode.setContent(networkGraph.getGraphViewer());
// update graph preferences // update graph preferences

View file

@ -23,16 +23,14 @@ public interface ICoreClient {
boolean stopThroughput() throws IOException; boolean stopThroughput() throws IOException;
void updateSession(Integer sessionId);
void updateState(SessionState state);
SessionOverview createSession() throws IOException; SessionOverview createSession() throws IOException;
boolean deleteSession(Integer sessionId) throws IOException; boolean deleteSession(Integer sessionId) throws IOException;
List<SessionOverview> getSessions() throws IOException; List<SessionOverview> getSessions() throws IOException;
Session joinSession(Integer sessionId) throws IOException;
Session getSession(Integer sessionId) throws IOException; Session getSession(Integer sessionId) throws IOException;
boolean start(Collection<CoreNode> nodes, Collection<CoreLink> links, List<Hook> hooks) throws IOException; boolean start(Collection<CoreNode> nodes, Collection<CoreLink> links, List<Hook> hooks) throws IOException;
@ -117,5 +115,5 @@ public interface ICoreClient {
boolean setLocationConfig(LocationConfig config) throws IOException; boolean setLocationConfig(LocationConfig config) throws IOException;
void setupEventHandlers(Controller controller) throws IOException; void initialize(Controller controller);
} }

View file

@ -33,6 +33,7 @@ public class CoreGrpcClient implements ICoreClient {
private final ExecutorService executorService = Executors.newFixedThreadPool(6); private final ExecutorService executorService = Executors.newFixedThreadPool(6);
private boolean handlingEvents = false; private boolean handlingEvents = false;
private boolean handlingThroughputs = false; private boolean handlingThroughputs = false;
private Controller controller;
private CoreProto.Node nodeToProto(CoreNode node) { private CoreProto.Node nodeToProto(CoreNode node) {
CoreProto.Position position = CoreProto.Position.newBuilder() CoreProto.Position position = CoreProto.Position.newBuilder()
@ -58,6 +59,9 @@ public class CoreGrpcClient implements ICoreClient {
if (node.getIcon() != null) { if (node.getIcon() != null) {
builder.setIcon(node.getIcon()); builder.setIcon(node.getIcon());
} }
if (node.getImage() != null) {
builder.setImage(node.getImage());
}
return builder.build(); return builder.build();
} }
@ -157,14 +161,26 @@ public class CoreGrpcClient implements ICoreClient {
private CoreNode protoToNode(CoreProto.Node protoNode) { private CoreNode protoToNode(CoreProto.Node protoNode) {
CoreNode node = new CoreNode(protoNode.getId()); CoreNode node = new CoreNode(protoNode.getId());
node.setType(protoNode.getTypeValue());
node.setName(protoNode.getName()); node.setName(protoNode.getName());
node.setEmane(protoNode.getEmane());
node.setIcon(protoNode.getIcon()); node.setIcon(protoNode.getIcon());
node.setModel(protoNode.getModel()); node.setModel(protoNode.getModel());
if (!protoNode.getEmane().isEmpty()) {
node.setEmane(protoNode.getEmane());
}
if (!protoNode.getImage().isEmpty()) {
node.setImage(protoNode.getImage());
}
node.setServices(new HashSet<>(protoNode.getServicesList())); node.setServices(new HashSet<>(protoNode.getServicesList()));
node.getPosition().setX((double) protoNode.getPosition().getX()); node.getPosition().setX((double) protoNode.getPosition().getX());
node.getPosition().setY((double) protoNode.getPosition().getY()); node.getPosition().setY((double) protoNode.getPosition().getY());
node.setType(protoNode.getTypeValue()); NodeType nodeType = NodeType.find(node.getType(), node.getModel());
if (nodeType == null) {
logger.error("failed to find node type({}) model({}): {}",
node.getType(), node.getModel(), node.getName());
}
node.setNodeType(nodeType);
node.setLoaded(true);
return node; return node;
} }
@ -172,7 +188,9 @@ public class CoreGrpcClient implements ICoreClient {
CoreInterface coreInterface = new CoreInterface(); CoreInterface coreInterface = new CoreInterface();
coreInterface.setId(protoInterface.getId()); coreInterface.setId(protoInterface.getId());
coreInterface.setName(protoInterface.getName()); coreInterface.setName(protoInterface.getName());
if (!protoInterface.getMac().isEmpty()) {
coreInterface.setMac(protoInterface.getMac()); coreInterface.setMac(protoInterface.getMac());
}
String ip4String = String.format("%s/%s", protoInterface.getIp4(), protoInterface.getIp4Mask()); String ip4String = String.format("%s/%s", protoInterface.getIp4(), protoInterface.getIp4Mask());
IPAddress ip4 = new IPAddressString(ip4String).getAddress(); IPAddress ip4 = new IPAddressString(ip4String).getAddress();
coreInterface.setIp4(ip4); coreInterface.setIp4(ip4);
@ -184,6 +202,7 @@ public class CoreGrpcClient implements ICoreClient {
private CoreLink protoToLink(CoreProto.Link linkProto) { private CoreLink protoToLink(CoreProto.Link linkProto) {
CoreLink link = new CoreLink(); CoreLink link = new CoreLink();
link.setType(linkProto.getTypeValue());
link.setNodeOne(linkProto.getNodeOneId()); link.setNodeOne(linkProto.getNodeOneId());
link.setNodeTwo(linkProto.getNodeTwoId()); link.setNodeTwo(linkProto.getNodeTwoId());
CoreInterface interfaceOne = protoToInterface(linkProto.getInterfaceOne()); CoreInterface interfaceOne = protoToInterface(linkProto.getInterfaceOne());
@ -211,6 +230,11 @@ public class CoreGrpcClient implements ICoreClient {
return link; return link;
} }
@Override
public void initialize(Controller controller) {
this.controller = controller;
}
@Override @Override
public void setConnection(String address, int port) { public void setConnection(String address, int port) {
this.address = address; this.address = address;
@ -283,16 +307,6 @@ public class CoreGrpcClient implements ICoreClient {
return true; return true;
} }
@Override
public void updateSession(Integer sessionId) {
this.sessionId = sessionId;
}
@Override
public void updateState(SessionState state) {
sessionState = state;
}
@Override @Override
public SessionOverview createSession() throws IOException { public SessionOverview createSession() throws IOException {
CoreProto.CreateSessionRequest request = CoreProto.CreateSessionRequest.newBuilder().build(); CoreProto.CreateSessionRequest request = CoreProto.CreateSessionRequest.newBuilder().build();
@ -345,6 +359,7 @@ public class CoreGrpcClient implements ICoreClient {
try { try {
CoreProto.GetSessionResponse response = blockingStub.getSession(request); CoreProto.GetSessionResponse response = blockingStub.getSession(request);
Session session = new Session(); Session session = new Session();
session.setId(sessionId);
for (CoreProto.Node protoNode : response.getSession().getNodesList()) { for (CoreProto.Node protoNode : response.getSession().getNodesList()) {
if (CoreProto.NodeType.Enum.PEER_TO_PEER == protoNode.getType()) { if (CoreProto.NodeType.Enum.PEER_TO_PEER == protoNode.getType()) {
continue; continue;
@ -355,19 +370,43 @@ public class CoreGrpcClient implements ICoreClient {
session.getNodes().add(node); session.getNodes().add(node);
} }
for (CoreProto.Link linkProto : response.getSession().getLinksList()) { for (CoreProto.Link linkProto : response.getSession().getLinksList()) {
logger.info("adding link: {} - {}", linkProto.getNodeOneId(), linkProto.getNodeTwoId()); logger.info("adding link: {}", linkProto);
CoreLink link = protoToLink(linkProto); CoreLink link = protoToLink(linkProto);
session.getLinks().add(link); session.getLinks().add(link);
} }
session.setState(response.getSession().getStateValue()); SessionState state = SessionState.get(response.getSession().getStateValue());
session.setState(state);
return session; return session;
} catch (StatusRuntimeException ex) { } catch (StatusRuntimeException ex) {
throw new IOException(ex); throw new IOException(ex);
} }
} }
@Override
public Session joinSession(Integer sessionId) throws IOException {
// stop handling previous session events if currently running
if (isRunning()) {
handlingEvents = false;
}
// join desired session
Session session = getSession(sessionId);
this.sessionId = session.getId();
sessionState = session.getState();
logger.info("joining session({}) state({})", this.sessionId, sessionState);
// setup event handlers if joined session is running
if (isRunning()) {
setupEventHandlers();
}
return session;
}
@Override @Override
public boolean start(Collection<CoreNode> nodes, Collection<CoreLink> links, List<Hook> hooks) throws IOException { public boolean start(Collection<CoreNode> nodes, Collection<CoreLink> links, List<Hook> hooks) throws IOException {
setupEventHandlers();
boolean result = setState(SessionState.DEFINITION); boolean result = setState(SessionState.DEFINITION);
if (!result) { if (!result) {
return false; return false;
@ -806,6 +845,8 @@ public class CoreGrpcClient implements ICoreClient {
@Override @Override
public boolean deleteNode(CoreNode node) throws IOException { public boolean deleteNode(CoreNode node) throws IOException {
CoreProto.DeleteNodeRequest request = CoreProto.DeleteNodeRequest.newBuilder() CoreProto.DeleteNodeRequest request = CoreProto.DeleteNodeRequest.newBuilder()
.setSessionId(sessionId)
.setNodeId(node.getId())
.build(); .build();
try { try {
CoreProto.DeleteNodeResponse response = blockingStub.deleteNode(request); CoreProto.DeleteNodeResponse response = blockingStub.deleteNode(request);
@ -1132,8 +1173,7 @@ public class CoreGrpcClient implements ICoreClient {
} }
} }
@Override private void setupEventHandlers() throws IOException {
public void setupEventHandlers(Controller controller) throws IOException {
logger.info("setting up event handlers"); logger.info("setting up event handlers");
handlingEvents = true; handlingEvents = true;
try { try {
@ -1151,22 +1191,22 @@ public class CoreGrpcClient implements ICoreClient {
logger.info("handling event: {}", event); logger.info("handling event: {}", event);
switch (event.getEventTypeCase()) { switch (event.getEventTypeCase()) {
case SESSION_EVENT: case SESSION_EVENT:
handleSessionEvents(controller, event.getSessionEvent()); handleSessionEvents(event.getSessionEvent());
break; break;
case NODE_EVENT: case NODE_EVENT:
handleNodeEvents(controller, event.getNodeEvent()); handleNodeEvents(event.getNodeEvent());
break; break;
case LINK_EVENT: case LINK_EVENT:
handleLinkEvents(controller, event.getLinkEvent()); handleLinkEvents(event.getLinkEvent());
break; break;
case CONFIG_EVENT: case CONFIG_EVENT:
handleConfigEvents(controller, event.getConfigEvent()); handleConfigEvents(event.getConfigEvent());
break; break;
case EXCEPTION_EVENT: case EXCEPTION_EVENT:
handleExceptionEvents(controller, event.getExceptionEvent()); handleExceptionEvents(event.getExceptionEvent());
break; break;
case FILE_EVENT: case FILE_EVENT:
handleFileEvents(controller, event.getFileEvent()); handleFileEvents(event.getFileEvent());
break; break;
default: default:
logger.error("unknown event type: {}", event.getEventTypeCase()); logger.error("unknown event type: {}", event.getEventTypeCase());
@ -1185,7 +1225,7 @@ public class CoreGrpcClient implements ICoreClient {
} }
} }
private void handleSessionEvents(Controller controller, CoreProto.SessionEvent event) { private void handleSessionEvents(CoreProto.SessionEvent event) {
logger.info("session event: {}", event); logger.info("session event: {}", event);
SessionState state = SessionState.get(event.getEvent()); SessionState state = SessionState.get(event.getEvent());
if (state == null) { if (state == null) {
@ -1196,7 +1236,7 @@ public class CoreGrpcClient implements ICoreClient {
// session state event // session state event
if (state.getValue() <= 6) { if (state.getValue() <= 6) {
logger.info("event updating session state: {}", state); logger.info("event updating session state: {}", state);
updateState(state); sessionState = state;
// mobility script event // mobility script event
} else if (state.getValue() <= 9) { } else if (state.getValue() <= 9) {
Integer nodeId = event.getNodeId(); Integer nodeId = event.getNodeId();
@ -1211,21 +1251,21 @@ public class CoreGrpcClient implements ICoreClient {
} }
} }
private void handleNodeEvents(Controller controller, CoreProto.NodeEvent event) { private void handleNodeEvents(CoreProto.NodeEvent event) {
logger.info("node event: {}", event); logger.info("node event: {}", event);
CoreNode node = protoToNode(event.getNode()); CoreNode node = protoToNode(event.getNode());
controller.getNetworkGraph().setNodeLocation(node); controller.getNetworkGraph().setNodeLocation(node);
} }
private void handleExceptionEvents(Controller controller, CoreProto.ExceptionEvent event) { private void handleExceptionEvents(CoreProto.ExceptionEvent event) {
logger.info("exception event: {}", event); logger.info("exception event: {}", event);
} }
private void handleConfigEvents(Controller controller, CoreProto.ConfigEvent event) { private void handleConfigEvents(CoreProto.ConfigEvent event) {
logger.info("config event: {}", event); logger.info("config event: {}", event);
} }
private void handleLinkEvents(Controller controller, CoreProto.LinkEvent event) { private void handleLinkEvents(CoreProto.LinkEvent event) {
logger.info("link event: {}", event); logger.info("link event: {}", event);
CoreLink link = protoToLink(event.getLink()); CoreLink link = protoToLink(event.getLink());
MessageFlags flag = MessageFlags.get(event.getMessageTypeValue()); MessageFlags flag = MessageFlags.get(event.getMessageTypeValue());
@ -1239,7 +1279,7 @@ public class CoreGrpcClient implements ICoreClient {
controller.getNetworkGraph().getGraphViewer().repaint(); controller.getNetworkGraph().getGraphViewer().repaint();
} }
private void handleFileEvents(Controller controller, CoreProto.FileEvent event) { private void handleFileEvents(CoreProto.FileEvent event) {
logger.info("file event: {}", event); logger.info("file event: {}", event);
} }
} }

View file

@ -15,7 +15,7 @@ public class CoreLink {
private double throughput; private double throughput;
private boolean visible = true; private boolean visible = true;
private Integer messageType; private Integer messageType;
private Integer type = 1; private Integer type = LinkTypes.WIRED.getValue();
private Integer nodeOne; private Integer nodeOne;
private Integer nodeTwo; private Integer nodeTwo;
private CoreInterface interfaceOne; private CoreInterface interfaceOne;

View file

@ -28,6 +28,7 @@ public class CoreNode {
private String url; private String url;
private NodeType nodeType; private NodeType nodeType;
private String icon; private String icon;
private String image;
private boolean loaded = true; private boolean loaded = true;
private LayeredIcon graphIcon; private LayeredIcon graphIcon;
private RadioIcon radioIcon = new RadioIcon(); private RadioIcon radioIcon = new RadioIcon();

View file

@ -1,5 +1,7 @@
package com.core.data; package com.core.data;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -19,6 +21,8 @@ public class NodeType {
public static final int HUB = 5; public static final int HUB = 5;
public static final int WLAN = 6; public static final int WLAN = 6;
public static final int EMANE = 10; public static final int EMANE = 10;
public static final int DOCKER = 15;
public static final int LXC = 16;
@EqualsAndHashCode.Include @EqualsAndHashCode.Include
private final int id; private final int id;
private final int value; private final int value;
@ -27,21 +31,13 @@ public class NodeType {
private String model; private String model;
private String icon; private String icon;
// PHYSICAL = 1
// RJ45 = 7
// TUNNEL = 8
// KTUNNEL = 9
// EMANE = 10
// TAP_BRIDGE = 11
// PEER_TO_PEER = 12
// CONTROL_NET = 13
// EMANE_NET = 14;
static { static {
add(new NodeType(SWITCH, "lanswitch", "Switch", "/icons/switch-100.png")); add(new NodeType(SWITCH, "lanswitch", "Switch", "/icons/switch-100.png"));
add(new NodeType(HUB, "hub", "Hub", "/icons/hub-100.png")); add(new NodeType(HUB, "hub", "Hub", "/icons/hub-100.png"));
add(new NodeType(WLAN, "wlan", "WLAN", "/icons/wlan-100.png")); add(new NodeType(WLAN, "wlan", "WLAN", "/icons/wlan-100.png"));
add(new NodeType(EMANE, "wlan", "EMANE", "/icons/emane-100.png")); add(new NodeType(EMANE, "wlan", "EMANE", "/icons/emane-100.png"));
add(new NodeType(NodeType.DOCKER, null, "DockerNode", "/icons/dockernode-100.png"));
add(new NodeType(NodeType.LXC, null, "LxcNode", "/icons/lxcnode-100.png"));
} }
@ -53,6 +49,19 @@ public class NodeType {
this.icon = icon; this.icon = icon;
} }
public Label createLabel(int size) {
ImageView labelIcon = new ImageView(icon);
labelIcon.setFitWidth(size);
labelIcon.setFitHeight(size);
Label label = new Label(display, labelIcon);
label.setUserData(id);
return label;
}
public static boolean isDefault(NodeType nodeType) {
return nodeType.value == DEFAULT || nodeType.value == DOCKER || nodeType.value == LXC;
}
public static void add(NodeType nodeType) { public static void add(NodeType nodeType) {
ID_LOOKUP.put(nodeType.getId(), nodeType); ID_LOOKUP.put(nodeType.getId(), nodeType);
} }
@ -74,7 +83,7 @@ public class NodeType {
.filter(nodeType -> { .filter(nodeType -> {
boolean sameType = nodeType.getValue() == type; boolean sameType = nodeType.getValue() == type;
boolean sameModel = true; boolean sameModel = true;
if (!model.isEmpty()) { if (model != null && !model.isEmpty()) {
sameModel = model.equals(nodeType.getModel()); sameModel = model.equals(nodeType.getModel());
} }
return sameType && sameModel; return sameType && sameModel;

View file

@ -9,7 +9,8 @@ import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class Session { public class Session {
private Integer state; private Integer id;
private SessionState state;
private List<CoreNode> nodes = new ArrayList<>(); private List<CoreNode> nodes = new ArrayList<>();
private List<CoreLink> links = new ArrayList<>(); private List<CoreLink> links = new ArrayList<>();
} }

View file

@ -60,6 +60,8 @@ public class CorePopupGraphMousePlugin<V, E> extends EditingPopupGraphMousePlugi
ContextMenu contextMenu = new ContextMenu(); ContextMenu contextMenu = new ContextMenu();
switch (node.getType()) { switch (node.getType()) {
case NodeType.DEFAULT: case NodeType.DEFAULT:
case NodeType.DOCKER:
case NodeType.LXC:
contextMenu = new NodeContextMenu(controller, node); contextMenu = new NodeContextMenu(controller, node);
break; break;
case NodeType.WLAN: case NodeType.WLAN:

View file

@ -298,8 +298,8 @@ public class NetworkGraph {
Pair<CoreNode> endpoints = graph.getEndpoints(link); Pair<CoreNode> endpoints = graph.getEndpoints(link);
CoreNode nodeOne = endpoints.getFirst(); CoreNode nodeOne = endpoints.getFirst();
CoreNode nodeTwo = endpoints.getSecond(); CoreNode nodeTwo = endpoints.getSecond();
boolean nodeOneIsDefault = isNode(nodeOne); boolean nodeOneIsDefault = NodeType.isDefault(nodeOne.getNodeType());
boolean nodeTwoIsDefault = isNode(nodeTwo); boolean nodeTwoIsDefault = NodeType.isDefault(nodeTwo.getNodeType());
// check what we are linking together // check what we are linking together
IPAddress subnet = null; IPAddress subnet = null;
@ -360,7 +360,7 @@ public class NetworkGraph {
currentInterface = link.getInterfaceTwo(); currentInterface = link.getInterfaceTwo();
} }
if (isNode(currentNode)) { if (NodeType.isDefault(currentNode.getNodeType())) {
interfaces.add(currentInterface); interfaces.add(currentInterface);
} else { } else {
Set<CoreInterface> nextInterfaces = getNetworkInterfaces(currentNode, visited); Set<CoreInterface> nextInterfaces = getNetworkInterfaces(currentNode, visited);
@ -407,10 +407,6 @@ public class NetworkGraph {
} }
} }
private boolean isNode(CoreNode node) {
return node.getType() == NodeType.DEFAULT;
}
private CoreInterface createInterface(CoreNode node, int interfaceId, IPAddress subnet) { private CoreInterface createInterface(CoreNode node, int interfaceId, IPAddress subnet) {
CoreInterface coreInterface = new CoreInterface(); CoreInterface coreInterface = new CoreInterface();
coreInterface.setId(interfaceId); coreInterface.setId(interfaceId);
@ -429,8 +425,8 @@ public class NetworkGraph {
CoreInterface interfaceOne = link.getInterfaceOne(); CoreInterface interfaceOne = link.getInterfaceOne();
CoreNode nodeTwo = getVertex(link.getNodeTwo()); CoreNode nodeTwo = getVertex(link.getNodeTwo());
CoreInterface interfaceTwo = link.getInterfaceTwo(); CoreInterface interfaceTwo = link.getInterfaceTwo();
boolean nodeOneIsDefault = isNode(nodeOne); boolean nodeOneIsDefault = NodeType.isDefault(nodeOne.getNodeType());
boolean nodeTwoIsDefault = isNode(nodeTwo); boolean nodeTwoIsDefault = NodeType.isDefault(nodeTwo.getNodeType());
// check what we are unlinking // check what we are unlinking
Set<CoreInterface> interfaces; Set<CoreInterface> interfaces;
@ -461,17 +457,21 @@ public class NetworkGraph {
private void handleVertexAdded(GraphEvent.Vertex<CoreNode, CoreLink> vertexEvent) { private void handleVertexAdded(GraphEvent.Vertex<CoreNode, CoreLink> vertexEvent) {
CoreNode node = vertexEvent.getVertex(); CoreNode node = vertexEvent.getVertex();
if (!node.isLoaded()) { if (node.isLoaded()) {
return;
}
node.setNodeType(nodeType); node.setNodeType(nodeType);
if (node.getType() == NodeType.EMANE) { if (node.getType() == NodeType.EMANE) {
String emaneModel = controller.getNodeEmaneDialog().getModels().get(0); String emaneModel = controller.getNodeEmaneDialog().getModels().get(0);
node.setEmane(emaneModel); node.setEmane(emaneModel);
} else if (node.getType() == NodeType.DOCKER || node.getType() == NodeType.LXC) {
node.setImage("ubuntu");
} }
logger.info("adding user created node: {}", node); logger.info("adding user created node: {}", node);
nodeMap.put(node.getId(), node); nodeMap.put(node.getId(), node);
} }
}
private void handleVertexRemoved(GraphEvent.Vertex<CoreNode, CoreLink> vertexEvent) { private void handleVertexRemoved(GraphEvent.Vertex<CoreNode, CoreLink> vertexEvent) {
CoreNode node = vertexEvent.getVertex(); CoreNode node = vertexEvent.getVertex();
@ -506,7 +506,7 @@ public class NetworkGraph {
try { try {
controller.getCoreClient().deleteNode(node); controller.getCoreClient().deleteNode(node);
} catch (IOException ex) { } catch (IOException ex) {
logger.error("error deleting node"); logger.error("error deleting node", ex);
Toast.error(String.format("Error deleting node: %s", node.getName())); Toast.error(String.format("Error deleting node: %s", node.getName()));
} }
graphViewer.getPickedVertexState().pick(node, false); graphViewer.getPickedVertexState().pick(node, false);

View file

@ -40,6 +40,7 @@ public class GraphToolbar extends VBox {
private SVGGlyph stopIcon; private SVGGlyph stopIcon;
private JFXListView<Label> nodesList = new JFXListView<>(); private JFXListView<Label> nodesList = new JFXListView<>();
private JFXListView<Label> devicesList = new JFXListView<>(); private JFXListView<Label> devicesList = new JFXListView<>();
private JFXListView<Label> containersList = new JFXListView<>();
private JFXButton selectedEditButton; private JFXButton selectedEditButton;
private NodeType selectedNodeType; private NodeType selectedNodeType;
private boolean isEditing = false; private boolean isEditing = false;
@ -49,6 +50,7 @@ public class GraphToolbar extends VBox {
@FXML private ComboBox<String> graphModeCombo; @FXML private ComboBox<String> graphModeCombo;
@FXML private JFXButton nodesButton; @FXML private JFXButton nodesButton;
@FXML private JFXButton devicesButton; @FXML private JFXButton devicesButton;
@FXML private JFXButton containersButton;
public GraphToolbar(Controller controller) { public GraphToolbar(Controller controller) {
this.controller = controller; this.controller = controller;
@ -63,6 +65,7 @@ public class GraphToolbar extends VBox {
setupDrawingButton(); setupDrawingButton();
setupNodesButton(); setupNodesButton();
setupDevicesButton(); setupDevicesButton();
setupContainersButton();
// initial state // initial state
setSelected(true, pickingButton); setSelected(true, pickingButton);
@ -113,28 +116,20 @@ public class GraphToolbar extends VBox {
public void setupNodeTypes() { public void setupNodeTypes() {
// clear existing configuration // clear existing configuration
labelMap.clear(); for (Label label : nodesList.getItems()) {
int id = (int) label.getUserData();
labelMap.remove(id);
}
nodesList.getItems().clear(); nodesList.getItems().clear();
devicesList.getItems().clear();
// add current default nodes
for (NodeType nodeType : NodeType.getAll()) { for (NodeType nodeType : NodeType.getAll()) {
ImageView icon = new ImageView(nodeType.getIcon()); if (NodeType.DEFAULT == nodeType.getValue()) {
icon.setFitWidth(NODES_ICON_SIZE); addNodeType(nodeType.getValue(), nodeType.getModel(), nodesList);
icon.setFitHeight(NODES_ICON_SIZE);
Label label = new Label(nodeType.getDisplay(), icon);
label.setUserData(nodeType.getId());
labelMap.put(nodeType.getId(), label);
if (nodeType.getValue() == NodeType.DEFAULT) {
nodesList.getItems().add(label);
} else {
devicesList.getItems().add(label);
} }
} }
Comparator<Label> comparator = Comparator.comparing(Label::getText); Comparator<Label> comparator = Comparator.comparing(Label::getText);
nodesList.getItems().sort(comparator); nodesList.getItems().sort(comparator);
devicesList.getItems().sort(comparator);
// initial node // initial node
nodesList.getSelectionModel().selectFirst(); nodesList.getSelectionModel().selectFirst();
@ -143,9 +138,6 @@ public class GraphToolbar extends VBox {
selectedEditButton = nodesButton; selectedEditButton = nodesButton;
controller.getNetworkGraph().setNodeType(selectedNodeType); controller.getNetworkGraph().setNodeType(selectedNodeType);
updateButtonValues(nodesButton, selectedNodeLabel); updateButtonValues(nodesButton, selectedNodeLabel);
// initial device
updateButtonValues(devicesButton, devicesList.getItems().get(0));
} }
private void updateButtonValues(JFXButton button, Label label) { private void updateButtonValues(JFXButton button, Label label) {
@ -167,49 +159,53 @@ public class GraphToolbar extends VBox {
} }
private void setupNodesButton() { private void setupNodesButton() {
nodesButton.setTooltip(new Tooltip("Network Nodes (host, pc, etc)")); setupButtonSelection("CORE Nodes", nodesButton, nodesList);
nodesList.setOnMouseClicked(event -> { }
Label selectedLabel = nodesList.getSelectionModel().getSelectedItem();
private void setupDevicesButton() {
addNodeType(NodeType.HUB, "hub", devicesList);
addNodeType(NodeType.SWITCH, "lanswitch", devicesList);
addNodeType(NodeType.WLAN, "wlan", devicesList);
addNodeType(NodeType.EMANE, "wlan", devicesList);
devicesList.getSelectionModel().selectFirst();
updateButtonValues(devicesButton, devicesList.getSelectionModel().getSelectedItem());
setupButtonSelection("Network Nodes", devicesButton, devicesList);
}
private void setupContainersButton() {
addNodeType(NodeType.DOCKER, null, containersList);
addNodeType(NodeType.LXC, null, containersList);
containersList.getSelectionModel().selectFirst();
updateButtonValues(containersButton, containersList.getSelectionModel().getSelectedItem());
setupButtonSelection("Container Nodes", containersButton, containersList);
}
private void addNodeType(int type, String model, JFXListView<Label> list) {
NodeType nodeType = NodeType.find(type, model);
Label label = nodeType.createLabel(NODES_ICON_SIZE);
labelMap.put(nodeType.getId(), label);
list.getItems().add(label);
}
private void setupButtonSelection(String tooltipText, JFXButton button, JFXListView<Label> list) {
button.setTooltip(new Tooltip(tooltipText));
list.setOnMouseClicked(event -> {
Label selectedLabel = list.getSelectionModel().getSelectedItem();
if (selectedLabel == null) { if (selectedLabel == null) {
return; return;
} }
updateButtonValues(nodesButton, selectedLabel); updateButtonValues(button, selectedLabel);
selectedNodeType = NodeType.get((int) selectedLabel.getUserData()); selectedNodeType = NodeType.get((int) selectedLabel.getUserData());
logger.info("selected node type: {}", selectedNodeType);
setSelectedEditButton(nodesButton);
devicesList.getSelectionModel().clearSelection();
controller.getNetworkGraph().setNodeType(selectedNodeType); controller.getNetworkGraph().setNodeType(selectedNodeType);
setSelectedEditButton(button);
logger.info("node selected: {} - type: {}", selectedLabel, selectedNodeType); logger.info("node selected: {} - type: {}", selectedLabel, selectedNodeType);
setEditMode(); setEditMode();
}); });
JFXPopup popup = new JFXPopup(nodesList); JFXPopup popup = new JFXPopup(list);
nodesButton.setOnAction(event -> popup.show(nodesButton, JFXPopup.PopupVPosition.TOP, button.setOnAction(event -> popup.show(button, JFXPopup.PopupVPosition.TOP,
JFXPopup.PopupHPosition.LEFT, nodesButton.getWidth(), 0)); JFXPopup.PopupHPosition.LEFT, button.getWidth(), 0));
}
private void setupDevicesButton() {
devicesButton.setTooltip(new Tooltip("Device Nodes (WLAN, EMANE, Switch, etc)"));
devicesList.setOnMouseClicked(event -> {
Label selectedLabel = devicesList.getSelectionModel().getSelectedItem();
if (selectedLabel == null) {
return;
}
updateButtonValues(devicesButton, selectedLabel);
selectedNodeType = NodeType.get((int) selectedLabel.getUserData());
logger.info("selected node type: {}", selectedNodeType);
controller.getNetworkGraph().setNodeType(selectedNodeType);
setSelectedEditButton(devicesButton);
nodesList.getSelectionModel().clearSelection();
logger.info("device selected: {} - type: {}", selectedLabel, selectedNodeType);
setEditMode();
});
JFXPopup popup = new JFXPopup(devicesList);
devicesButton.setOnAction(event -> popup.show(devicesButton, JFXPopup.PopupVPosition.TOP,
JFXPopup.PopupHPosition.LEFT, devicesButton.getWidth(), 0));
} }
@FXML @FXML

View file

@ -54,6 +54,7 @@ public class NodeDetails extends ScrollPane {
addRow("Type", node.getNodeType().getDisplay(), true); addRow("Type", node.getNodeType().getDisplay(), true);
} }
addRow("EMANE", node.getEmane(), true); addRow("EMANE", node.getEmane(), true);
addRow("Image", node.getImage(), true);
addRow("X", node.getPosition().getX().toString(), true); addRow("X", node.getPosition().getX().toString(), true);
addRow("Y", node.getPosition().getY().toString(), true); addRow("Y", node.getPosition().getY().toString(), true);

View file

@ -10,6 +10,7 @@
<JFXButton fx:id="pickingButton" styleClass="toolbar-button" /> <JFXButton fx:id="pickingButton" styleClass="toolbar-button" />
<JFXButton fx:id="nodesButton" styleClass="toolbar-button" text="Nodes" /> <JFXButton fx:id="nodesButton" styleClass="toolbar-button" text="Nodes" />
<JFXButton fx:id="devicesButton" styleClass="toolbar-button" text="Devices" /> <JFXButton fx:id="devicesButton" styleClass="toolbar-button" text="Devices" />
<JFXButton fx:id="containersButton" styleClass="toolbar-button" text="Containers" />
<JFXButton fx:id="drawingButton" styleClass="toolbar-button" /> <JFXButton fx:id="drawingButton" styleClass="toolbar-button" />
</children> </children>
<padding> <padding>

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B