Merge branch 'rel/5.3' of git-ssh.web.boeing.com:Boeing-CORE/CORE into rel/5.3
This commit is contained in:
commit
f9402f53d5
22 changed files with 562 additions and 139 deletions
|
@ -8,6 +8,7 @@ import com.core.ui.*;
|
|||
import com.core.ui.dialogs.*;
|
||||
import com.core.utils.ConfigUtils;
|
||||
import com.core.utils.Configuration;
|
||||
import com.core.utils.NodeTypeConfig;
|
||||
import com.core.websocket.CoreWebSocket;
|
||||
import com.jfoenix.controls.JFXProgressBar;
|
||||
import javafx.application.Application;
|
||||
|
@ -50,6 +51,7 @@ public class Controller implements Initializable {
|
|||
private Application application;
|
||||
private Stage window;
|
||||
private Configuration configuration;
|
||||
private Map<String, Set<String>> defaultServices = new HashMap<>();
|
||||
|
||||
// core client utilities
|
||||
private ICoreClient coreClient = new CoreRestClient();
|
||||
|
@ -79,6 +81,7 @@ public class Controller implements Initializable {
|
|||
private GeoDialog geoDialog = new GeoDialog(this);
|
||||
private ConnectDialog connectDialog = new ConnectDialog(this);
|
||||
private GuiPreferencesDialog guiPreferencesDialog = new GuiPreferencesDialog(this);
|
||||
private NodeTypeCreateDialog nodeTypeCreateDialog = new NodeTypeCreateDialog(this);
|
||||
|
||||
public void connectToCore(String coreUrl) {
|
||||
coreWebSocket.stop();
|
||||
|
@ -100,6 +103,7 @@ public class Controller implements Initializable {
|
|||
Map<String, List<String>> serviceGroups = coreClient.getServices();
|
||||
logger.info("core services: {}", serviceGroups);
|
||||
nodeServicesDialog.setServices(serviceGroups);
|
||||
nodeTypeCreateDialog.setServices(serviceGroups);
|
||||
|
||||
logger.info("initial core session join");
|
||||
List<SessionOverview> sessions = coreClient.getSessions();
|
||||
|
@ -169,17 +173,21 @@ public class Controller implements Initializable {
|
|||
// update other components for new session
|
||||
graphToolbar.setRunButton(coreClient.isRunning());
|
||||
hooksDialog.updateHooks();
|
||||
nodeTypesDialog.updateDefaultServices();
|
||||
|
||||
// display first mobility script in player
|
||||
// update session default services
|
||||
setCoreDefaultServices();
|
||||
|
||||
// display first mobility script in player, if needed
|
||||
Map<Integer, MobilityConfig> mobilityConfigMap = coreClient.getMobilityConfigs();
|
||||
Optional<Integer> nodeIdOptional = mobilityConfigMap.keySet().stream().findFirst();
|
||||
if (nodeIdOptional.isPresent()) {
|
||||
Integer nodeId = nodeIdOptional.get();
|
||||
MobilityConfig mobilityConfig = mobilityConfigMap.get(nodeId);
|
||||
CoreNode node = networkGraph.getVertex(nodeId);
|
||||
mobilityPlayer.show(node, mobilityConfig);
|
||||
Platform.runLater(() -> bottom.getChildren().add(mobilityPlayer));
|
||||
if (node != null) {
|
||||
mobilityPlayer.show(node, mobilityConfig);
|
||||
Platform.runLater(() -> bottom.getChildren().add(mobilityPlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,6 +238,24 @@ public class Controller implements Initializable {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void setCoreDefaultServices() {
|
||||
try {
|
||||
coreClient.setDefaultServices(defaultServices);
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error updating core default services", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateNodeTypes() {
|
||||
graphToolbar.setupNodeTypes();
|
||||
setCoreDefaultServices();
|
||||
try {
|
||||
ConfigUtils.save(configuration);
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error saving configuration", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteNode(CoreNode node) {
|
||||
networkGraph.removeNode(node);
|
||||
CoreNode mobilityNode = mobilityDialog.getNode();
|
||||
|
@ -253,6 +279,7 @@ public class Controller implements Initializable {
|
|||
locationDialog.setOwner(window);
|
||||
connectDialog.setOwner(window);
|
||||
guiPreferencesDialog.setOwner(window);
|
||||
nodeTypeCreateDialog.setOwner(window);
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
@ -401,6 +428,11 @@ public class Controller implements Initializable {
|
|||
logger.info("controller initialize");
|
||||
swingNode.setContent(networkGraph.getGraphViewer());
|
||||
|
||||
// set node types / default services
|
||||
graphToolbar.setupNodeTypes();
|
||||
defaultServices = configuration.getNodeTypeConfigs().stream()
|
||||
.collect(Collectors.toMap(NodeTypeConfig::getModel, NodeTypeConfig::getServices));
|
||||
|
||||
// set graph toolbar
|
||||
borderPane.setLeft(graphToolbar);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.io.IOException;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ICoreClient {
|
||||
void setUrl(String url);
|
||||
|
@ -31,7 +32,9 @@ public interface ICoreClient {
|
|||
|
||||
Map<String, List<String>> getServices() throws IOException;
|
||||
|
||||
Map<String, List<String>> defaultServices() throws IOException;
|
||||
Map<String, List<String>> getDefaultServices() throws IOException;
|
||||
|
||||
boolean setDefaultServices(Map<String, Set<String>> defaults) throws IOException;
|
||||
|
||||
CoreService getService(CoreNode node, String serviceName) throws IOException;
|
||||
|
||||
|
@ -39,6 +42,14 @@ public interface ICoreClient {
|
|||
|
||||
String getServiceFile(CoreNode node, String serviceName, String fileName) throws IOException;
|
||||
|
||||
boolean startService(CoreNode node, String serviceName) throws IOException;
|
||||
|
||||
boolean stopService(CoreNode node, String serviceName) throws IOException;
|
||||
|
||||
boolean restartService(CoreNode node, String serviceName) throws IOException;
|
||||
|
||||
boolean validateService(CoreNode node, String serviceName) throws IOException;
|
||||
|
||||
boolean setServiceFile(CoreNode node, String serviceName, ServiceFile serviceFile) throws IOException;
|
||||
|
||||
List<ConfigGroup> getEmaneConfig(CoreNode node) throws IOException;
|
||||
|
|
|
@ -9,10 +9,7 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class CoreRestClient implements ICoreClient {
|
||||
|
@ -129,12 +126,18 @@ public class CoreRestClient implements ICoreClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> defaultServices() throws IOException {
|
||||
public Map<String, List<String>> getDefaultServices() throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/services/default", sessionId));
|
||||
GetDefaultServices getDefaultServices = WebUtils.getJson(url, GetDefaultServices.class);
|
||||
return getDefaultServices.getDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDefaultServices(Map<String, Set<String>> defaults) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/services/default", sessionId));
|
||||
return WebUtils.postJson(url, defaults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoreService getService(CoreNode node, String serviceName) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s", sessionId, node.getId(), serviceName));
|
||||
|
@ -156,6 +159,34 @@ public class CoreRestClient implements ICoreClient {
|
|||
return WebUtils.getJson(url, String.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startService(CoreNode node, String serviceName) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s/start", sessionId, node.getId(),
|
||||
serviceName));
|
||||
return WebUtils.putJson(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopService(CoreNode node, String serviceName) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s/stop", sessionId, node.getId(),
|
||||
serviceName));
|
||||
return WebUtils.putJson(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restartService(CoreNode node, String serviceName) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s/restart", sessionId, node.getId(),
|
||||
serviceName));
|
||||
return WebUtils.putJson(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateService(CoreNode node, String serviceName) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s/validate", sessionId, node.getId(),
|
||||
serviceName));
|
||||
return WebUtils.putJson(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setServiceFile(CoreNode node, String serviceName, ServiceFile serviceFile) throws IOException {
|
||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s/file", sessionId, node.getId(),
|
||||
|
|
|
@ -5,9 +5,7 @@ import lombok.EqualsAndHashCode;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Data
|
||||
|
@ -24,6 +22,7 @@ public class NodeType {
|
|||
@EqualsAndHashCode.Include
|
||||
private final int id;
|
||||
private final int value;
|
||||
private final Set<String> services = new TreeSet<>();
|
||||
private String display;
|
||||
private String model;
|
||||
private String icon;
|
||||
|
@ -39,13 +38,10 @@ public class NodeType {
|
|||
// EMANE_NET = 14;
|
||||
|
||||
static {
|
||||
addNodeType(new NodeType(DEFAULT, "host", "Host", "/icons/host-100.png"));
|
||||
addNodeType(new NodeType(DEFAULT, "PC", "PC", "/icons/pc-100.png"));
|
||||
addNodeType(new NodeType(DEFAULT, "mdr", "MDR", "/icons/router-100.png"));
|
||||
addNodeType(new NodeType(SWITCH, "lanswitch", "Switch", "/icons/switch-100.png"));
|
||||
addNodeType(new NodeType(HUB, "hub", "Hub", "/icons/hub-100.png"));
|
||||
addNodeType(new NodeType(WLAN, "wlan", "WLAN", "/icons/wlan-100.png"));
|
||||
addNodeType(new NodeType(EMANE, "wlan", "EMANE", "/icons/emane-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(WLAN, "wlan", "WLAN", "/icons/wlan-100.png"));
|
||||
add(new NodeType(EMANE, "wlan", "EMANE", "/icons/emane-100.png"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,10 +53,14 @@ public class NodeType {
|
|||
this.icon = icon;
|
||||
}
|
||||
|
||||
public static void addNodeType(NodeType nodeType) {
|
||||
public static void add(NodeType nodeType) {
|
||||
ID_LOOKUP.put(nodeType.getId(), nodeType);
|
||||
}
|
||||
|
||||
public static void remove(NodeType nodeType) {
|
||||
ID_LOOKUP.remove(nodeType.getId());
|
||||
}
|
||||
|
||||
public static NodeType get(Integer id) {
|
||||
return ID_LOOKUP.get(id);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.core.graph;
|
||||
|
||||
import com.core.Controller;
|
||||
import com.core.data.CoreNode;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.MenuItem;
|
||||
|
||||
abstract class AbstractNodeContextMenu extends GraphContextMenu {
|
||||
final CoreNode coreNode;
|
||||
|
||||
AbstractNodeContextMenu(Controller controller, CoreNode coreNode) {
|
||||
super(controller);
|
||||
this.coreNode = coreNode;
|
||||
}
|
||||
|
||||
void addMenuItem(String text, EventHandler<ActionEvent> handler) {
|
||||
MenuItem menuItem = new MenuItem(text);
|
||||
menuItem.setOnAction(handler);
|
||||
getItems().add(menuItem);
|
||||
}
|
||||
}
|
|
@ -9,17 +9,12 @@ import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;
|
|||
import edu.uci.ics.jung.algorithms.layout.Layout;
|
||||
import edu.uci.ics.jung.visualization.control.EditingPopupGraphMousePlugin;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CorePopupGraphMousePlugin<V, E> extends EditingPopupGraphMousePlugin<V, E> {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
@ -45,15 +40,13 @@ public class CorePopupGraphMousePlugin<V, E> extends EditingPopupGraphMousePlugi
|
|||
final CoreNode node = pickSupport.getVertex(graphLayout, p.getX(), p.getY());
|
||||
final CoreLink link = pickSupport.getEdge(graphLayout, p.getX(), p.getY());
|
||||
|
||||
ContextMenu contextMenu = new ContextMenu();
|
||||
|
||||
// edge picked
|
||||
final ContextMenu contextMenu;
|
||||
if (node != null) {
|
||||
List<MenuItem> menuItems = handleNodeContext(node);
|
||||
contextMenu.getItems().addAll(menuItems);
|
||||
contextMenu = handleNodeContext(node);
|
||||
} else if (link != null) {
|
||||
List<MenuItem> menuItems = handleLinkContext(link);
|
||||
contextMenu.getItems().addAll(menuItems);
|
||||
contextMenu = new LinkContextMenu(controller, link);
|
||||
} else {
|
||||
contextMenu = new ContextMenu();
|
||||
}
|
||||
|
||||
if (!contextMenu.getItems().isEmpty()) {
|
||||
|
@ -63,60 +56,23 @@ public class CorePopupGraphMousePlugin<V, E> extends EditingPopupGraphMousePlugi
|
|||
}
|
||||
}
|
||||
|
||||
private MenuItem createMenuItem(String text, EventHandler<ActionEvent> handler) {
|
||||
MenuItem menuItem = new MenuItem(text);
|
||||
menuItem.setOnAction(handler);
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
private List<MenuItem> handleNodeContext(final CoreNode node) {
|
||||
boolean isRunning = controller.getCoreClient().isRunning();
|
||||
|
||||
List<MenuItem> menuItems = new ArrayList<>();
|
||||
|
||||
private ContextMenu handleNodeContext(final CoreNode node) {
|
||||
ContextMenu contextMenu = new ContextMenu();
|
||||
switch (node.getType()) {
|
||||
case NodeType.DEFAULT:
|
||||
menuItems.add(createMenuItem("Services",
|
||||
event -> controller.getNodeServicesDialog().showDialog(node)));
|
||||
contextMenu = new NodeContextMenu(controller, node);
|
||||
break;
|
||||
case NodeType.WLAN:
|
||||
menuItems.add(createMenuItem("WLAN Settings",
|
||||
event -> controller.getNodeWlanDialog().showDialog(node)));
|
||||
menuItems.add(createMenuItem("Mobility",
|
||||
event -> controller.getMobilityDialog().showDialog(node)));
|
||||
menuItems.add(createMenuItem("Link MDRs",
|
||||
event -> networkGraph.linkMdrs(node)));
|
||||
contextMenu = new WlanContextMenu(controller, node);
|
||||
break;
|
||||
case NodeType.EMANE:
|
||||
menuItems.add(createMenuItem("EMANE Settings",
|
||||
event -> controller.getNodeEmaneDialog().showDialog(node)));
|
||||
menuItems.add(createMenuItem("Mobility",
|
||||
event -> controller.getMobilityDialog().showDialog(node)));
|
||||
menuItems.add(createMenuItem("Link MDRs",
|
||||
event -> networkGraph.linkMdrs(node)));
|
||||
contextMenu = new EmaneContextMenu(controller, node);
|
||||
break;
|
||||
default:
|
||||
logger.warn("no context menu for node: {}", node.getType());
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isRunning) {
|
||||
menuItems.add(createMenuItem("Delete Node",
|
||||
event -> controller.deleteNode(node)));
|
||||
}
|
||||
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
private List<MenuItem> handleLinkContext(final CoreLink link) {
|
||||
boolean isRunning = controller.getCoreClient().isRunning();
|
||||
|
||||
List<MenuItem> menuItems = new ArrayList<>();
|
||||
|
||||
if (!isRunning) {
|
||||
menuItems.add(createMenuItem("Delete Link",
|
||||
event -> networkGraph.removeLink(link)));
|
||||
}
|
||||
|
||||
return menuItems;
|
||||
return contextMenu;
|
||||
}
|
||||
}
|
||||
|
|
23
corefx/src/main/java/com/core/graph/EmaneContextMenu.java
Normal file
23
corefx/src/main/java/com/core/graph/EmaneContextMenu.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package com.core.graph;
|
||||
|
||||
import com.core.Controller;
|
||||
import com.core.data.CoreNode;
|
||||
|
||||
class EmaneContextMenu extends AbstractNodeContextMenu {
|
||||
EmaneContextMenu(Controller controller, CoreNode coreNode) {
|
||||
super(controller, coreNode);
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
addMenuItem("EMANE Settings",
|
||||
event -> controller.getNodeEmaneDialog().showDialog(coreNode));
|
||||
if (!controller.getCoreClient().isRunning()) {
|
||||
addMenuItem("Mobility",
|
||||
event -> controller.getMobilityDialog().showDialog(coreNode));
|
||||
addMenuItem("Link MDRs",
|
||||
event -> controller.getNetworkGraph().linkMdrs(coreNode));
|
||||
addMenuItem("Delete Node", event -> controller.deleteNode(coreNode));
|
||||
}
|
||||
}
|
||||
}
|
22
corefx/src/main/java/com/core/graph/GraphContextMenu.java
Normal file
22
corefx/src/main/java/com/core/graph/GraphContextMenu.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package com.core.graph;
|
||||
|
||||
import com.core.Controller;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
|
||||
abstract class GraphContextMenu extends ContextMenu {
|
||||
final Controller controller;
|
||||
|
||||
GraphContextMenu(Controller controller) {
|
||||
super();
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
void addMenuItem(String text, EventHandler<ActionEvent> handler) {
|
||||
MenuItem menuItem = new MenuItem(text);
|
||||
menuItem.setOnAction(handler);
|
||||
getItems().add(menuItem);
|
||||
}
|
||||
}
|
21
corefx/src/main/java/com/core/graph/LinkContextMenu.java
Normal file
21
corefx/src/main/java/com/core/graph/LinkContextMenu.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package com.core.graph;
|
||||
|
||||
import com.core.Controller;
|
||||
import com.core.data.CoreLink;
|
||||
|
||||
class LinkContextMenu extends GraphContextMenu {
|
||||
final CoreLink coreLink;
|
||||
|
||||
LinkContextMenu(Controller controller, CoreLink coreLink) {
|
||||
super(controller);
|
||||
this.coreLink = coreLink;
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
if (!controller.getCoreClient().isRunning()) {
|
||||
addMenuItem("Delete Link",
|
||||
event -> controller.getNetworkGraph().removeLink(coreLink));
|
||||
}
|
||||
}
|
||||
}
|
116
corefx/src/main/java/com/core/graph/NodeContextMenu.java
Normal file
116
corefx/src/main/java/com/core/graph/NodeContextMenu.java
Normal file
|
@ -0,0 +1,116 @@
|
|||
package com.core.graph;
|
||||
|
||||
import com.core.Controller;
|
||||
import com.core.data.CoreNode;
|
||||
import com.core.ui.Toast;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
class NodeContextMenu extends AbstractNodeContextMenu {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
||||
NodeContextMenu(Controller controller, CoreNode coreNode) {
|
||||
super(controller, coreNode);
|
||||
setup();
|
||||
}
|
||||
|
||||
private MenuItem createStartItem(String service) {
|
||||
MenuItem menuItem = new MenuItem("Start");
|
||||
menuItem.setOnAction(event -> {
|
||||
try {
|
||||
boolean result = controller.getCoreClient().startService(coreNode, service);
|
||||
if (result) {
|
||||
Toast.success("Started " + service);
|
||||
} else {
|
||||
Toast.error("Failure to start " + service);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error starting " + service, ex);
|
||||
}
|
||||
});
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
private MenuItem createStopItem(String service) {
|
||||
MenuItem menuItem = new MenuItem("Stop");
|
||||
menuItem.setOnAction(event -> {
|
||||
try {
|
||||
boolean result = controller.getCoreClient().stopService(coreNode, service);
|
||||
if (result) {
|
||||
Toast.success("Stopped " + service);
|
||||
} else {
|
||||
Toast.error("Failure to stop " + service);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error stopping " + service, ex);
|
||||
}
|
||||
});
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
private MenuItem createRestartItem(String service) {
|
||||
MenuItem menuItem = new MenuItem("Restart");
|
||||
menuItem.setOnAction(event -> {
|
||||
try {
|
||||
boolean result = controller.getCoreClient().restartService(coreNode, service);
|
||||
if (result) {
|
||||
Toast.success("Restarted " + service);
|
||||
} else {
|
||||
Toast.error("Failure to restart " + service);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error restarting " + service, ex);
|
||||
}
|
||||
});
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
private MenuItem createValidateItem(String service) {
|
||||
MenuItem menuItem = new MenuItem("Validate");
|
||||
menuItem.setOnAction(event -> {
|
||||
try {
|
||||
boolean result = controller.getCoreClient().validateService(coreNode, service);
|
||||
if (result) {
|
||||
Toast.success("Validated " + service);
|
||||
} else {
|
||||
Toast.error("Validation failed for " + service);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error validating " + service, ex);
|
||||
}
|
||||
});
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
if (controller.getCoreClient().isRunning()) {
|
||||
Set<String> services = coreNode.getServices();
|
||||
if (services.isEmpty()) {
|
||||
services = controller.getDefaultServices().getOrDefault(coreNode.getModel(), Collections.emptySet());
|
||||
}
|
||||
|
||||
if (!services.isEmpty()) {
|
||||
Menu menu = new Menu("Manage Services");
|
||||
for (String service : services) {
|
||||
Menu serviceMenu = new Menu(service);
|
||||
MenuItem startItem = createStartItem(service);
|
||||
MenuItem stopItem = createStopItem(service);
|
||||
MenuItem restartItem = createRestartItem(service);
|
||||
MenuItem validateItem = createValidateItem(service);
|
||||
serviceMenu.getItems().addAll(startItem, stopItem, restartItem, validateItem);
|
||||
menu.getItems().add(serviceMenu);
|
||||
}
|
||||
getItems().add(menu);
|
||||
}
|
||||
} else {
|
||||
addMenuItem("Services", event -> controller.getNodeServicesDialog().showDialog(coreNode));
|
||||
addMenuItem("Delete Node", event -> controller.deleteNode(coreNode));
|
||||
}
|
||||
}
|
||||
}
|
23
corefx/src/main/java/com/core/graph/WlanContextMenu.java
Normal file
23
corefx/src/main/java/com/core/graph/WlanContextMenu.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package com.core.graph;
|
||||
|
||||
import com.core.Controller;
|
||||
import com.core.data.CoreNode;
|
||||
|
||||
class WlanContextMenu extends AbstractNodeContextMenu {
|
||||
WlanContextMenu(Controller controller, CoreNode coreNode) {
|
||||
super(controller, coreNode);
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
addMenuItem("WLAN Settings",
|
||||
event -> controller.getNodeWlanDialog().showDialog(coreNode));
|
||||
if (!controller.getCoreClient().isRunning()) {
|
||||
addMenuItem("Mobility",
|
||||
event -> controller.getMobilityDialog().showDialog(coreNode));
|
||||
addMenuItem("Link MDRs",
|
||||
event -> controller.getNetworkGraph().linkMdrs(coreNode));
|
||||
addMenuItem("Delete Node", event -> controller.deleteNode(coreNode));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,7 +45,6 @@ public class GraphToolbar extends VBox {
|
|||
private boolean isEditing = false;
|
||||
@FXML private JFXButton runButton;
|
||||
@FXML private JFXButton pickingButton;
|
||||
@FXML private JFXButton editingButton;
|
||||
@FXML private JFXButton drawingButton;
|
||||
@FXML private ComboBox<String> graphModeCombo;
|
||||
@FXML private JFXButton nodesButton;
|
||||
|
@ -61,10 +60,7 @@ public class GraphToolbar extends VBox {
|
|||
stopIcon.setSize(ICON_SIZE);
|
||||
|
||||
setupPickingButton();
|
||||
setupEditingButton();
|
||||
setupDrawingButton();
|
||||
|
||||
setupNodeTypes();
|
||||
setupNodesButton();
|
||||
setupDevicesButton();
|
||||
|
||||
|
@ -84,24 +80,20 @@ public class GraphToolbar extends VBox {
|
|||
controller.getBottom().getChildren().remove(controller.getAnnotationToolbar());
|
||||
controller.getBorderPane().setRight(null);
|
||||
setSelected(true, pickingButton);
|
||||
setSelected(false, editingButton, drawingButton, selectedEditButton);
|
||||
setSelected(false, drawingButton, selectedEditButton);
|
||||
isEditing = false;
|
||||
});
|
||||
}
|
||||
|
||||
private void setupEditingButton() {
|
||||
SVGGlyph editIcon = IconUtils.get("mode_edit");
|
||||
editIcon.setSize(ICON_SIZE);
|
||||
editingButton.setGraphic(editIcon);
|
||||
editingButton.setTooltip(new Tooltip("Edit Graph"));
|
||||
editingButton.setOnAction(event -> {
|
||||
controller.getNetworkGraph().setMode(ModalGraphMouse.Mode.EDITING);
|
||||
controller.getBottom().getChildren().remove(controller.getAnnotationToolbar());
|
||||
controller.getBorderPane().setRight(null);
|
||||
setSelected(true, editingButton, selectedEditButton);
|
||||
setSelected(false, drawingButton, pickingButton);
|
||||
isEditing = true;
|
||||
});
|
||||
private void setEditMode() {
|
||||
controller.getNetworkGraph().setMode(ModalGraphMouse.Mode.EDITING);
|
||||
controller.getBottom().getChildren().remove(controller.getAnnotationToolbar());
|
||||
controller.getBorderPane().setRight(null);
|
||||
if (selectedEditButton != null) {
|
||||
setSelected(true, selectedEditButton);
|
||||
}
|
||||
setSelected(false, drawingButton, pickingButton);
|
||||
isEditing = true;
|
||||
}
|
||||
|
||||
private void setupDrawingButton() {
|
||||
|
@ -114,12 +106,17 @@ public class GraphToolbar extends VBox {
|
|||
controller.getBottom().getChildren().add(controller.getAnnotationToolbar());
|
||||
controller.getBorderPane().setRight(null);
|
||||
setSelected(true, drawingButton);
|
||||
setSelected(false, editingButton, pickingButton, selectedEditButton);
|
||||
setSelected(false, pickingButton, selectedEditButton);
|
||||
isEditing = false;
|
||||
});
|
||||
}
|
||||
|
||||
private void setupNodeTypes() {
|
||||
public void setupNodeTypes() {
|
||||
// clear existing configuration
|
||||
labelMap.clear();
|
||||
nodesList.getItems().clear();
|
||||
devicesList.getItems().clear();
|
||||
|
||||
for (NodeType nodeType : NodeType.getAll()) {
|
||||
ImageView icon = new ImageView(nodeType.getIcon());
|
||||
icon.setFitWidth(NODES_ICON_SIZE);
|
||||
|
@ -162,7 +159,9 @@ public class GraphToolbar extends VBox {
|
|||
JFXButton previous = selectedEditButton;
|
||||
selectedEditButton = button;
|
||||
if (isEditing) {
|
||||
setSelected(false, previous);
|
||||
if (previous != null) {
|
||||
setSelected(false, previous);
|
||||
}
|
||||
setSelected(true, selectedEditButton);
|
||||
}
|
||||
}
|
||||
|
@ -184,8 +183,11 @@ public class GraphToolbar extends VBox {
|
|||
});
|
||||
|
||||
JFXPopup popup = new JFXPopup(nodesList);
|
||||
nodesButton.setOnAction(event -> popup.show(nodesButton, JFXPopup.PopupVPosition.TOP,
|
||||
JFXPopup.PopupHPosition.LEFT, nodesButton.getWidth(), 0));
|
||||
nodesButton.setOnAction(event -> {
|
||||
setEditMode();
|
||||
popup.show(nodesButton, JFXPopup.PopupVPosition.TOP,
|
||||
JFXPopup.PopupHPosition.LEFT, nodesButton.getWidth(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
private void setupDevicesButton() {
|
||||
|
@ -205,8 +207,11 @@ public class GraphToolbar extends VBox {
|
|||
});
|
||||
|
||||
JFXPopup popup = new JFXPopup(devicesList);
|
||||
devicesButton.setOnAction(event -> popup.show(devicesButton, JFXPopup.PopupVPosition.TOP,
|
||||
JFXPopup.PopupHPosition.LEFT, devicesButton.getWidth(), 0));
|
||||
devicesButton.setOnAction(event -> {
|
||||
setEditMode();
|
||||
popup.show(devicesButton, JFXPopup.PopupVPosition.TOP,
|
||||
JFXPopup.PopupHPosition.LEFT, devicesButton.getWidth(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
@ -269,7 +274,8 @@ public class GraphToolbar extends VBox {
|
|||
if (isRunning) {
|
||||
Platform.runLater(() -> {
|
||||
pickingButton.fire();
|
||||
editingButton.setDisable(true);
|
||||
devicesButton.setDisable(true);
|
||||
nodesButton.setDisable(true);
|
||||
runButton.pseudoClassStateChanged(START_CLASS, false);
|
||||
runButton.pseudoClassStateChanged(STOP_CLASS, true);
|
||||
if (runButton.getGraphic() != stopIcon) {
|
||||
|
@ -279,7 +285,8 @@ public class GraphToolbar extends VBox {
|
|||
});
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
editingButton.setDisable(false);
|
||||
devicesButton.setDisable(false);
|
||||
nodesButton.setDisable(false);
|
||||
runButton.pseudoClassStateChanged(START_CLASS, true);
|
||||
runButton.pseudoClassStateChanged(STOP_CLASS, false);
|
||||
if (runButton.getGraphic() != startIcon) {
|
||||
|
|
|
@ -22,6 +22,9 @@ import javafx.scene.layout.GridPane;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class NodeDetails extends ScrollPane {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private static final int START_INDEX = 1;
|
||||
|
@ -100,16 +103,18 @@ public class NodeDetails extends ScrollPane {
|
|||
addInterface(coreInterface, linkedNode);
|
||||
}
|
||||
|
||||
|
||||
if (!node.getServices().isEmpty()) {
|
||||
// display custom or default node services
|
||||
Set<String> services = node.getServices();
|
||||
if (services.isEmpty()) {
|
||||
services = controller.getDefaultServices().getOrDefault(node.getModel(), Collections.emptySet());
|
||||
}
|
||||
if (!services.isEmpty()) {
|
||||
addSeparator();
|
||||
addLabel("Services");
|
||||
JFXListView<String> listView = new JFXListView<>();
|
||||
listView.setMouseTransparent(true);
|
||||
listView.setFocusTraversable(false);
|
||||
for (String service : node.getServices()) {
|
||||
listView.getItems().add(service);
|
||||
}
|
||||
listView.getItems().setAll(services);
|
||||
gridPane.add(listView, 0, index++, 2, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,8 @@ public class NodeEmaneDialog extends StageDialog {
|
|||
}
|
||||
|
||||
public void setModels(List<String> models) {
|
||||
modelCombo.getItems().clear();
|
||||
models.stream().sorted()
|
||||
.forEach(model -> modelCombo.getItems().add(model));
|
||||
models.sort(String::compareTo);
|
||||
modelCombo.getItems().setAll(models);
|
||||
modelCombo.getSelectionModel().selectFirst();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ public class NodeServicesDialog extends StageDialog {
|
|||
private static final Logger logger = LogManager.getLogger();
|
||||
private final Map<String, List<ServiceItem>> serviceItemGroups = new HashMap<>();
|
||||
private final Map<String, ServiceItem> serviceItemMap = new HashMap<>();
|
||||
// TODO: get this from core itself
|
||||
private final Map<String, Set<String>> defaultServices = new HashMap<>();
|
||||
private CoreNode node;
|
||||
private int index = 0;
|
||||
@FXML private GridPane gridPane;
|
||||
|
@ -47,12 +45,6 @@ public class NodeServicesDialog extends StageDialog {
|
|||
});
|
||||
addCancelButton();
|
||||
|
||||
defaultServices.put("mdr", new HashSet<>(Arrays.asList("zebra", "OSPFv3MDR", "IPForward")));
|
||||
defaultServices.put("PC", new HashSet<>(Arrays.asList("DefaultRoute")));
|
||||
defaultServices.put("prouter", new HashSet<>(Arrays.asList("zebra", "OSPFv2", "OSPFv3", "IPForward")));
|
||||
defaultServices.put("router", new HashSet<>(Arrays.asList("zebra", "OSPFv2", "OSPFv3", "IPForward")));
|
||||
defaultServices.put("host", new HashSet<>(Arrays.asList("DefaultRoute", "SSH")));
|
||||
|
||||
groupListView.getSelectionModel().selectedItemProperty().addListener((ov, previous, current) -> {
|
||||
if (current == null) {
|
||||
return;
|
||||
|
@ -137,7 +129,7 @@ public class NodeServicesDialog extends StageDialog {
|
|||
|
||||
Set<String> nodeServices = node.getServices();
|
||||
if (nodeServices.isEmpty()) {
|
||||
nodeServices = defaultServices.get(node.getModel());
|
||||
nodeServices = getController().getDefaultServices().get(node.getModel());
|
||||
}
|
||||
|
||||
for (List<ServiceItem> items : serviceItemGroups.values()) {
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package com.core.ui.dialogs;
|
||||
|
||||
import com.core.Controller;
|
||||
import com.core.data.NodeType;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.SelectionMode;
|
||||
import lombok.Data;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class NodeTypeCreateDialog extends StageDialog {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
@FXML private JFXListView<String> servicesListView;
|
||||
@FXML private JFXTextField modelTextField;
|
||||
@FXML private JFXTextField displayTextField;
|
||||
private Runnable onCreateHandler;
|
||||
|
||||
public NodeTypeCreateDialog(Controller controller) {
|
||||
super(controller, "/fxml/node_type_create_dialog.fxml");
|
||||
setTitle("Create Node Configuration");
|
||||
|
||||
JFXButton saveButton = createButton("Create");
|
||||
saveButton.setOnAction(event -> {
|
||||
onCreateHandler.run();
|
||||
close();
|
||||
});
|
||||
addCancelButton();
|
||||
|
||||
servicesListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
displayTextField.focusedProperty().addListener((obs, prev, current) -> {
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
|
||||
String model = modelTextField.getText();
|
||||
if (!model.isEmpty()) {
|
||||
displayTextField.setText(model.substring(0, 1).toUpperCase() + model.substring(1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public NodeType getCreatedNodeType() {
|
||||
NodeType nodeType = new NodeType(NodeType.DEFAULT, modelTextField.getText(), displayTextField.getText(),
|
||||
"/icons/host-100.png");
|
||||
nodeType.getServices().addAll(servicesListView.getSelectionModel().getSelectedItems());
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
public void setServices(Map<String, List<String>> serviceGroups) {
|
||||
List<String> services = new ArrayList<>();
|
||||
for (List<String> groupServices : serviceGroups.values()) {
|
||||
services.addAll(groupServices);
|
||||
}
|
||||
services.sort(String::compareTo);
|
||||
servicesListView.getItems().setAll(services);
|
||||
}
|
||||
|
||||
|
||||
public void showDialog(Runnable runnable) {
|
||||
onCreateHandler = runnable;
|
||||
modelTextField.setText("");
|
||||
displayTextField.setText("");
|
||||
servicesListView.getSelectionModel().clearSelection();
|
||||
show();
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.core.Controller;
|
|||
import com.core.data.CoreNode;
|
||||
import com.core.data.NodeType;
|
||||
import com.core.ui.Toast;
|
||||
import com.core.utils.NodeTypeConfig;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
|
@ -15,17 +16,14 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class NodeTypesDialog extends StageDialog {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private final Map<String, NodeType> nodeTypeMap = new HashMap<>();
|
||||
private NodeType selectedNodeType;
|
||||
private Map<String, List<String>> defaultServices = new HashMap<>();
|
||||
@FXML private JFXListView<String> listView;
|
||||
@FXML private JFXTextField modelTextField;
|
||||
@FXML private JFXTextField displayTextField;
|
||||
|
@ -40,7 +38,8 @@ public class NodeTypesDialog extends StageDialog {
|
|||
public NodeTypesDialog(Controller controller) {
|
||||
super(controller, "/fxml/node_types_dialog.fxml");
|
||||
setTitle("Node Configuration");
|
||||
addCancelButton();
|
||||
JFXButton closeButton = createButton("Close");
|
||||
closeButton.setOnAction(event -> close());
|
||||
|
||||
listView.getSelectionModel().selectedItemProperty().addListener((ov, prev, current) -> {
|
||||
if (current == null) {
|
||||
|
@ -53,14 +52,14 @@ public class NodeTypesDialog extends StageDialog {
|
|||
iconTextField.setText(nodeType.getIcon());
|
||||
iconImage.setImage(new Image(nodeType.getIcon()));
|
||||
selectedNodeType = nodeType;
|
||||
List<String> services = defaultServices.getOrDefault(nodeType.getModel(), Collections.emptyList());
|
||||
Set<String> services = nodeType.getServices();
|
||||
nodeServicesListView.getItems().setAll(services);
|
||||
});
|
||||
|
||||
iconButton.setOnAction(event -> {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Select Icon");
|
||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||
fileChooser.setInitialDirectory(new File(getController().getConfiguration().getIconPath()));
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("PNG", "*.png"));
|
||||
File file = fileChooser.showOpenDialog(controller.getWindow());
|
||||
if (file != null) {
|
||||
|
@ -84,15 +83,40 @@ public class NodeTypesDialog extends StageDialog {
|
|||
controller.getGraphToolbar().updateNodeType(selectedNodeType.getId(), iconPath);
|
||||
Toast.info(String.format("Node %s Updated", selectedNodeType.getDisplay()));
|
||||
});
|
||||
|
||||
deleteButton.setOnAction(event -> {
|
||||
String display = listView.getSelectionModel().getSelectedItem();
|
||||
NodeType nodeType = nodeTypeMap.get(display);
|
||||
NodeType.remove(nodeType);
|
||||
listView.getItems().remove(display);
|
||||
NodeTypeConfig nodeTypeConfig = createNodeTypeConfig(nodeType);
|
||||
getController().getDefaultServices().remove(nodeTypeConfig.getModel());
|
||||
getController().getConfiguration().getNodeTypeConfigs().remove(nodeTypeConfig);
|
||||
getController().updateNodeTypes();
|
||||
});
|
||||
|
||||
addButton.setOnAction(event -> {
|
||||
NodeTypeCreateDialog nodeTypeCreateDialog = getController().getNodeTypeCreateDialog();
|
||||
nodeTypeCreateDialog.showDialog(() -> {
|
||||
NodeType nodeType = nodeTypeCreateDialog.getCreatedNodeType();
|
||||
NodeType.add(nodeType);
|
||||
nodeTypeMap.put(nodeType.getDisplay(), nodeType);
|
||||
listView.getItems().add(nodeType.getDisplay());
|
||||
NodeTypeConfig nodeTypeConfig = createNodeTypeConfig(nodeType);
|
||||
getController().getDefaultServices().put(nodeTypeConfig.getModel(), nodeTypeConfig.getServices());
|
||||
getController().getConfiguration().getNodeTypeConfigs().add(nodeTypeConfig);
|
||||
getController().updateNodeTypes();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void updateDefaultServices() {
|
||||
try {
|
||||
defaultServices = getCoreClient().defaultServices();
|
||||
listView.getSelectionModel().selectFirst();
|
||||
} catch (IOException ex) {
|
||||
Toast.error("Error getting default services", ex);
|
||||
}
|
||||
private NodeTypeConfig createNodeTypeConfig(NodeType nodeType) {
|
||||
return new NodeTypeConfig(
|
||||
nodeType.getModel(),
|
||||
nodeType.getDisplay(),
|
||||
nodeType.getIcon(),
|
||||
nodeType.getServices()
|
||||
);
|
||||
}
|
||||
|
||||
public void showDialog() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.core.utils;
|
||||
|
||||
import com.core.data.NodeType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -9,6 +10,7 @@ import java.io.PrintWriter;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
public final class ConfigUtils {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
|
@ -18,6 +20,7 @@ public final class ConfigUtils {
|
|||
private static final Path CONFIG_FILE = Paths.get(HOME.toString(), CONFIG_FILE_NAME);
|
||||
private static final Path XML_DIR = Paths.get(HOME.toString(), "xml");
|
||||
private static final Path MOBILITY_DIR = Paths.get(HOME.toString(), "mobility");
|
||||
private static final Path ICON_DIR = Paths.get(HOME.toString(), "icons");
|
||||
|
||||
|
||||
private ConfigUtils() {
|
||||
|
@ -35,6 +38,27 @@ public final class ConfigUtils {
|
|||
return JsonUtils.read(new FileInputStream(CONFIG_FILE.toFile()), Configuration.class);
|
||||
}
|
||||
|
||||
private static List<NodeTypeConfig> createDefaults() throws IOException {
|
||||
return Arrays.asList(
|
||||
createDefault("host", "Host", "/icons/host-100.png", new TreeSet<>(Arrays.asList(
|
||||
"DefaultRoute", "SSH"
|
||||
))),
|
||||
createDefault("PC", "PC", "/icons/pc-100.png",
|
||||
new TreeSet<>(Collections.singletonList("DefaultRoute"))),
|
||||
createDefault("mdr", "MDR", "/icons/router-100.png", new TreeSet<>(Arrays.asList(
|
||||
"zebra", "OSPFv3MDR", "IPForward"
|
||||
)))
|
||||
);
|
||||
}
|
||||
|
||||
private static NodeTypeConfig createDefault(String model, String display, String icon,
|
||||
Set<String> services) throws IOException {
|
||||
String fileName = Paths.get(icon).getFileName().toString();
|
||||
Path iconPath = Paths.get(ICON_DIR.toString(), fileName);
|
||||
Files.copy(ConfigUtils.class.getResourceAsStream(icon), iconPath);
|
||||
return new NodeTypeConfig(model, display, iconPath.toUri().toString(), services);
|
||||
}
|
||||
|
||||
public static Configuration load() {
|
||||
try {
|
||||
if (!HOME.toFile().exists()) {
|
||||
|
@ -42,6 +66,7 @@ public final class ConfigUtils {
|
|||
Files.createDirectory(HOME);
|
||||
Files.createDirectory(XML_DIR);
|
||||
Files.createDirectory(MOBILITY_DIR);
|
||||
Files.createDirectory(ICON_DIR);
|
||||
}
|
||||
|
||||
Configuration configuration;
|
||||
|
@ -51,11 +76,29 @@ public final class ConfigUtils {
|
|||
configuration = readConfig();
|
||||
configuration.setXmlPath(XML_DIR.toString());
|
||||
configuration.setMobilityPath(MOBILITY_DIR.toString());
|
||||
configuration.setIconPath(ICON_DIR.toString());
|
||||
configuration.setNodeTypeConfigs(createDefaults());
|
||||
save(configuration);
|
||||
} else {
|
||||
configuration = readConfig();
|
||||
}
|
||||
|
||||
// initialize node types
|
||||
for (NodeTypeConfig nodeTypeConfig : configuration.getNodeTypeConfigs()) {
|
||||
NodeType nodeType = new NodeType(
|
||||
NodeType.DEFAULT,
|
||||
nodeTypeConfig.getModel(),
|
||||
nodeTypeConfig.getDisplay(),
|
||||
nodeTypeConfig.getIcon()
|
||||
);
|
||||
nodeType.getServices().addAll(nodeTypeConfig.getServices());
|
||||
NodeType.add(nodeType);
|
||||
}
|
||||
|
||||
// override configuration from command line
|
||||
String coreRest = System.getProperty("core-rest");
|
||||
configuration.setCoreRest(coreRest);
|
||||
|
||||
return configuration;
|
||||
} catch (IOException ex) {
|
||||
logger.error("error reading config file");
|
||||
|
|
|
@ -12,6 +12,7 @@ public class Configuration {
|
|||
private String coreRest;
|
||||
private String xmlPath;
|
||||
private String mobilityPath;
|
||||
private String iconPath;
|
||||
private String shellCommand;
|
||||
private List<NodeTypeConfig> nodeTypeConfigs = new ArrayList<>();
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package com.core.utils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class NodeTypeConfig {
|
||||
@EqualsAndHashCode.Include
|
||||
private String model;
|
||||
private String display;
|
||||
private String icon;
|
||||
private List<String> services = new ArrayList<>();
|
||||
private Set<String> services;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<children>
|
||||
<JFXButton id="run-button" fx:id="runButton" onAction="#onRunButtonAction" styleClass="toolbar-button" />
|
||||
<JFXButton fx:id="pickingButton" styleClass="toolbar-button" />
|
||||
<JFXButton fx:id="editingButton" styleClass="toolbar-button" />
|
||||
<JFXButton fx:id="nodesButton" styleClass="toolbar-button" text="Nodes" />
|
||||
<JFXButton fx:id="devicesButton" styleClass="toolbar-button" text="Devices" />
|
||||
<JFXButton fx:id="drawingButton" styleClass="toolbar-button" />
|
||||
|
|
18
corefx/src/main/resources/fxml/node_type_create_dialog.fxml
Normal file
18
corefx/src/main/resources/fxml/node_type_create_dialog.fxml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXListView?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
|
||||
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" spacing="10.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Label text="Model" />
|
||||
<JFXTextField fx:id="modelTextField" />
|
||||
<Label text="Display" />
|
||||
<JFXTextField fx:id="displayTextField" />
|
||||
<Label text="Services" />
|
||||
<JFXListView fx:id="servicesListView" VBox.vgrow="ALWAYS" />
|
||||
</children>
|
||||
</VBox>
|
Loading…
Reference in a new issue