corefx - updates to allow creation and saving of custom node types, the gui controls the daemon, instead of pulling, also added icons directory
This commit is contained in:
parent
d522649489
commit
7e2a79335c
12 changed files with 251 additions and 40 deletions
|
@ -8,6 +8,7 @@ import com.core.ui.*;
|
||||||
import com.core.ui.dialogs.*;
|
import com.core.ui.dialogs.*;
|
||||||
import com.core.utils.ConfigUtils;
|
import com.core.utils.ConfigUtils;
|
||||||
import com.core.utils.Configuration;
|
import com.core.utils.Configuration;
|
||||||
|
import com.core.utils.NodeTypeConfig;
|
||||||
import com.core.websocket.CoreWebSocket;
|
import com.core.websocket.CoreWebSocket;
|
||||||
import com.jfoenix.controls.JFXProgressBar;
|
import com.jfoenix.controls.JFXProgressBar;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
@ -79,6 +80,7 @@ public class Controller implements Initializable {
|
||||||
private GeoDialog geoDialog = new GeoDialog(this);
|
private GeoDialog geoDialog = new GeoDialog(this);
|
||||||
private ConnectDialog connectDialog = new ConnectDialog(this);
|
private ConnectDialog connectDialog = new ConnectDialog(this);
|
||||||
private GuiPreferencesDialog guiPreferencesDialog = new GuiPreferencesDialog(this);
|
private GuiPreferencesDialog guiPreferencesDialog = new GuiPreferencesDialog(this);
|
||||||
|
private NodeTypeCreateDialog nodeTypeCreateDialog = new NodeTypeCreateDialog(this);
|
||||||
|
|
||||||
public void connectToCore(String coreUrl) {
|
public void connectToCore(String coreUrl) {
|
||||||
coreWebSocket.stop();
|
coreWebSocket.stop();
|
||||||
|
@ -100,6 +102,7 @@ public class Controller implements Initializable {
|
||||||
Map<String, List<String>> serviceGroups = coreClient.getServices();
|
Map<String, List<String>> serviceGroups = coreClient.getServices();
|
||||||
logger.info("core services: {}", serviceGroups);
|
logger.info("core services: {}", serviceGroups);
|
||||||
nodeServicesDialog.setServices(serviceGroups);
|
nodeServicesDialog.setServices(serviceGroups);
|
||||||
|
nodeTypeCreateDialog.setServices(serviceGroups);
|
||||||
|
|
||||||
logger.info("initial core session join");
|
logger.info("initial core session join");
|
||||||
List<SessionOverview> sessions = coreClient.getSessions();
|
List<SessionOverview> sessions = coreClient.getSessions();
|
||||||
|
@ -169,9 +172,11 @@ public class Controller implements Initializable {
|
||||||
// update other components for new session
|
// update other components for new session
|
||||||
graphToolbar.setRunButton(coreClient.isRunning());
|
graphToolbar.setRunButton(coreClient.isRunning());
|
||||||
hooksDialog.updateHooks();
|
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();
|
Map<Integer, MobilityConfig> mobilityConfigMap = coreClient.getMobilityConfigs();
|
||||||
Optional<Integer> nodeIdOptional = mobilityConfigMap.keySet().stream().findFirst();
|
Optional<Integer> nodeIdOptional = mobilityConfigMap.keySet().stream().findFirst();
|
||||||
if (nodeIdOptional.isPresent()) {
|
if (nodeIdOptional.isPresent()) {
|
||||||
|
@ -230,6 +235,30 @@ public class Controller implements Initializable {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setCoreDefaultServices() {
|
||||||
|
try {
|
||||||
|
Map<String, List<String>> defaults = configuration.getNodeTypeConfigs().stream()
|
||||||
|
.collect(Collectors.toMap(NodeTypeConfig::getModel, NodeTypeConfig::getServices));
|
||||||
|
coreClient.setDefaultServices(defaults);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Toast.error("Error updating core default services", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateNodeTypes() {
|
||||||
|
graphToolbar.setupNodeTypes();
|
||||||
|
Map<String, Set<String>> defaults = configuration.getNodeTypeConfigs().stream()
|
||||||
|
.collect(Collectors.toMap(NodeTypeConfig::getModel,
|
||||||
|
nodeTypeConfig -> new HashSet<>(nodeTypeConfig.getServices())));
|
||||||
|
nodeServicesDialog.setDefaultServices(defaults);
|
||||||
|
setCoreDefaultServices();
|
||||||
|
try {
|
||||||
|
ConfigUtils.save(configuration);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Toast.error("Error saving configuration", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteNode(CoreNode node) {
|
public void deleteNode(CoreNode node) {
|
||||||
networkGraph.removeNode(node);
|
networkGraph.removeNode(node);
|
||||||
CoreNode mobilityNode = mobilityDialog.getNode();
|
CoreNode mobilityNode = mobilityDialog.getNode();
|
||||||
|
@ -253,6 +282,7 @@ public class Controller implements Initializable {
|
||||||
locationDialog.setOwner(window);
|
locationDialog.setOwner(window);
|
||||||
connectDialog.setOwner(window);
|
connectDialog.setOwner(window);
|
||||||
guiPreferencesDialog.setOwner(window);
|
guiPreferencesDialog.setOwner(window);
|
||||||
|
nodeTypeCreateDialog.setOwner(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -401,6 +431,13 @@ public class Controller implements Initializable {
|
||||||
logger.info("controller initialize");
|
logger.info("controller initialize");
|
||||||
swingNode.setContent(networkGraph.getGraphViewer());
|
swingNode.setContent(networkGraph.getGraphViewer());
|
||||||
|
|
||||||
|
// set node types / default services
|
||||||
|
graphToolbar.setupNodeTypes();
|
||||||
|
Map<String, Set<String>> defaults = configuration.getNodeTypeConfigs().stream()
|
||||||
|
.collect(Collectors.toMap(NodeTypeConfig::getModel,
|
||||||
|
nodeTypeConfig -> new HashSet<>(nodeTypeConfig.getServices())));
|
||||||
|
nodeServicesDialog.setDefaultServices(defaults);
|
||||||
|
|
||||||
// set graph toolbar
|
// set graph toolbar
|
||||||
borderPane.setLeft(graphToolbar);
|
borderPane.setLeft(graphToolbar);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,9 @@ public interface ICoreClient {
|
||||||
|
|
||||||
Map<String, List<String>> getServices() throws IOException;
|
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, List<String>> defaults) throws IOException;
|
||||||
|
|
||||||
CoreService getService(CoreNode node, String serviceName) throws IOException;
|
CoreService getService(CoreNode node, String serviceName) throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -129,12 +129,18 @@ public class CoreRestClient implements ICoreClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
String url = getUrl(String.format("sessions/%s/services/default", sessionId));
|
||||||
GetDefaultServices getDefaultServices = WebUtils.getJson(url, GetDefaultServices.class);
|
GetDefaultServices getDefaultServices = WebUtils.getJson(url, GetDefaultServices.class);
|
||||||
return getDefaultServices.getDefaults();
|
return getDefaultServices.getDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setDefaultServices(Map<String, List<String>> defaults) throws IOException {
|
||||||
|
String url = getUrl(String.format("sessions/%s/services/default", sessionId));
|
||||||
|
return WebUtils.postJson(url, defaults);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CoreService getService(CoreNode node, String serviceName) throws IOException {
|
public CoreService getService(CoreNode node, String serviceName) throws IOException {
|
||||||
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s", sessionId, node.getId(), serviceName));
|
String url = getUrl(String.format("sessions/%s/nodes/%s/services/%s", sessionId, node.getId(), serviceName));
|
||||||
|
|
|
@ -5,9 +5,7 @@ import lombok.EqualsAndHashCode;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -24,6 +22,7 @@ public class NodeType {
|
||||||
@EqualsAndHashCode.Include
|
@EqualsAndHashCode.Include
|
||||||
private final int id;
|
private final int id;
|
||||||
private final int value;
|
private final int value;
|
||||||
|
private final List<String> services = new ArrayList<>();
|
||||||
private String display;
|
private String display;
|
||||||
private String model;
|
private String model;
|
||||||
private String icon;
|
private String icon;
|
||||||
|
@ -39,13 +38,10 @@ public class NodeType {
|
||||||
// EMANE_NET = 14;
|
// EMANE_NET = 14;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
addNodeType(new NodeType(DEFAULT, "host", "Host", "/icons/host-100.png"));
|
add(new NodeType(SWITCH, "lanswitch", "Switch", "/icons/switch-100.png"));
|
||||||
addNodeType(new NodeType(DEFAULT, "PC", "PC", "/icons/pc-100.png"));
|
add(new NodeType(HUB, "hub", "Hub", "/icons/hub-100.png"));
|
||||||
addNodeType(new NodeType(DEFAULT, "mdr", "MDR", "/icons/router-100.png"));
|
add(new NodeType(WLAN, "wlan", "WLAN", "/icons/wlan-100.png"));
|
||||||
addNodeType(new NodeType(SWITCH, "lanswitch", "Switch", "/icons/switch-100.png"));
|
add(new NodeType(EMANE, "wlan", "EMANE", "/icons/emane-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"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,10 +53,14 @@ public class NodeType {
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addNodeType(NodeType nodeType) {
|
public static void add(NodeType nodeType) {
|
||||||
ID_LOOKUP.put(nodeType.getId(), nodeType);
|
ID_LOOKUP.put(nodeType.getId(), nodeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void remove(NodeType nodeType) {
|
||||||
|
ID_LOOKUP.remove(nodeType.getId());
|
||||||
|
}
|
||||||
|
|
||||||
public static NodeType get(Integer id) {
|
public static NodeType get(Integer id) {
|
||||||
return ID_LOOKUP.get(id);
|
return ID_LOOKUP.get(id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,6 @@ public class GraphToolbar extends VBox {
|
||||||
setupPickingButton();
|
setupPickingButton();
|
||||||
setupEditingButton();
|
setupEditingButton();
|
||||||
setupDrawingButton();
|
setupDrawingButton();
|
||||||
|
|
||||||
setupNodeTypes();
|
|
||||||
setupNodesButton();
|
setupNodesButton();
|
||||||
setupDevicesButton();
|
setupDevicesButton();
|
||||||
|
|
||||||
|
@ -119,7 +117,12 @@ public class GraphToolbar extends VBox {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupNodeTypes() {
|
public void setupNodeTypes() {
|
||||||
|
// clear existing configuration
|
||||||
|
labelMap.clear();
|
||||||
|
nodesList.getItems().clear();
|
||||||
|
devicesList.getItems().clear();
|
||||||
|
|
||||||
for (NodeType nodeType : NodeType.getAll()) {
|
for (NodeType nodeType : NodeType.getAll()) {
|
||||||
ImageView icon = new ImageView(nodeType.getIcon());
|
ImageView icon = new ImageView(nodeType.getIcon());
|
||||||
icon.setFitWidth(NODES_ICON_SIZE);
|
icon.setFitWidth(NODES_ICON_SIZE);
|
||||||
|
|
|
@ -19,7 +19,6 @@ public class NodeServicesDialog extends StageDialog {
|
||||||
private static final Logger logger = LogManager.getLogger();
|
private static final Logger logger = LogManager.getLogger();
|
||||||
private final Map<String, List<ServiceItem>> serviceItemGroups = new HashMap<>();
|
private final Map<String, List<ServiceItem>> serviceItemGroups = new HashMap<>();
|
||||||
private final Map<String, ServiceItem> serviceItemMap = 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 final Map<String, Set<String>> defaultServices = new HashMap<>();
|
||||||
private CoreNode node;
|
private CoreNode node;
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
|
@ -47,12 +46,6 @@ public class NodeServicesDialog extends StageDialog {
|
||||||
});
|
});
|
||||||
addCancelButton();
|
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) -> {
|
groupListView.getSelectionModel().selectedItemProperty().addListener((ov, previous, current) -> {
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -80,6 +73,11 @@ public class NodeServicesDialog extends StageDialog {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDefaultServices(Map<String, Set<String>> defaultServices) {
|
||||||
|
this.defaultServices.clear();
|
||||||
|
this.defaultServices.putAll(defaultServices);
|
||||||
|
}
|
||||||
|
|
||||||
public void setServices(Map<String, List<String>> serviceGroups) {
|
public void setServices(Map<String, List<String>> serviceGroups) {
|
||||||
serviceItemGroups.clear();
|
serviceItemGroups.clear();
|
||||||
|
|
||||||
|
|
|
@ -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.CoreNode;
|
||||||
import com.core.data.NodeType;
|
import com.core.data.NodeType;
|
||||||
import com.core.ui.Toast;
|
import com.core.ui.Toast;
|
||||||
|
import com.core.utils.NodeTypeConfig;
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import com.jfoenix.controls.JFXListView;
|
import com.jfoenix.controls.JFXListView;
|
||||||
import com.jfoenix.controls.JFXTextField;
|
import com.jfoenix.controls.JFXTextField;
|
||||||
|
@ -15,8 +16,6 @@ import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -25,7 +24,6 @@ public class NodeTypesDialog extends StageDialog {
|
||||||
private static final Logger logger = LogManager.getLogger();
|
private static final Logger logger = LogManager.getLogger();
|
||||||
private final Map<String, NodeType> nodeTypeMap = new HashMap<>();
|
private final Map<String, NodeType> nodeTypeMap = new HashMap<>();
|
||||||
private NodeType selectedNodeType;
|
private NodeType selectedNodeType;
|
||||||
private Map<String, List<String>> defaultServices = new HashMap<>();
|
|
||||||
@FXML private JFXListView<String> listView;
|
@FXML private JFXListView<String> listView;
|
||||||
@FXML private JFXTextField modelTextField;
|
@FXML private JFXTextField modelTextField;
|
||||||
@FXML private JFXTextField displayTextField;
|
@FXML private JFXTextField displayTextField;
|
||||||
|
@ -40,7 +38,8 @@ public class NodeTypesDialog extends StageDialog {
|
||||||
public NodeTypesDialog(Controller controller) {
|
public NodeTypesDialog(Controller controller) {
|
||||||
super(controller, "/fxml/node_types_dialog.fxml");
|
super(controller, "/fxml/node_types_dialog.fxml");
|
||||||
setTitle("Node Configuration");
|
setTitle("Node Configuration");
|
||||||
addCancelButton();
|
JFXButton closeButton = createButton("Close");
|
||||||
|
closeButton.setOnAction(event -> close());
|
||||||
|
|
||||||
listView.getSelectionModel().selectedItemProperty().addListener((ov, prev, current) -> {
|
listView.getSelectionModel().selectedItemProperty().addListener((ov, prev, current) -> {
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
|
@ -53,14 +52,14 @@ public class NodeTypesDialog extends StageDialog {
|
||||||
iconTextField.setText(nodeType.getIcon());
|
iconTextField.setText(nodeType.getIcon());
|
||||||
iconImage.setImage(new Image(nodeType.getIcon()));
|
iconImage.setImage(new Image(nodeType.getIcon()));
|
||||||
selectedNodeType = nodeType;
|
selectedNodeType = nodeType;
|
||||||
List<String> services = defaultServices.getOrDefault(nodeType.getModel(), Collections.emptyList());
|
List<String> services = nodeType.getServices();
|
||||||
nodeServicesListView.getItems().setAll(services);
|
nodeServicesListView.getItems().setAll(services);
|
||||||
});
|
});
|
||||||
|
|
||||||
iconButton.setOnAction(event -> {
|
iconButton.setOnAction(event -> {
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
fileChooser.setTitle("Select Icon");
|
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"));
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("PNG", "*.png"));
|
||||||
File file = fileChooser.showOpenDialog(controller.getWindow());
|
File file = fileChooser.showOpenDialog(controller.getWindow());
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
|
@ -84,15 +83,38 @@ public class NodeTypesDialog extends StageDialog {
|
||||||
controller.getGraphToolbar().updateNodeType(selectedNodeType.getId(), iconPath);
|
controller.getGraphToolbar().updateNodeType(selectedNodeType.getId(), iconPath);
|
||||||
Toast.info(String.format("Node %s Updated", selectedNodeType.getDisplay()));
|
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().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().getConfiguration().getNodeTypeConfigs().add(nodeTypeConfig);
|
||||||
|
getController().updateNodeTypes();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDefaultServices() {
|
private NodeTypeConfig createNodeTypeConfig(NodeType nodeType) {
|
||||||
try {
|
return new NodeTypeConfig(
|
||||||
defaultServices = getCoreClient().defaultServices();
|
nodeType.getModel(),
|
||||||
listView.getSelectionModel().selectFirst();
|
nodeType.getDisplay(),
|
||||||
} catch (IOException ex) {
|
nodeType.getIcon(),
|
||||||
Toast.error("Error getting default services", ex);
|
nodeType.getServices()
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDialog() {
|
public void showDialog() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.core.utils;
|
package com.core.utils;
|
||||||
|
|
||||||
|
import com.core.data.NodeType;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@ -9,6 +10,9 @@ import java.io.PrintWriter;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class ConfigUtils {
|
public final class ConfigUtils {
|
||||||
private static final Logger logger = LogManager.getLogger();
|
private static final Logger logger = LogManager.getLogger();
|
||||||
|
@ -18,6 +22,7 @@ public final class ConfigUtils {
|
||||||
private static final Path CONFIG_FILE = Paths.get(HOME.toString(), CONFIG_FILE_NAME);
|
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 XML_DIR = Paths.get(HOME.toString(), "xml");
|
||||||
private static final Path MOBILITY_DIR = Paths.get(HOME.toString(), "mobility");
|
private static final Path MOBILITY_DIR = Paths.get(HOME.toString(), "mobility");
|
||||||
|
private static final Path ICON_DIR = Paths.get(HOME.toString(), "icons");
|
||||||
|
|
||||||
|
|
||||||
private ConfigUtils() {
|
private ConfigUtils() {
|
||||||
|
@ -35,6 +40,27 @@ public final class ConfigUtils {
|
||||||
return JsonUtils.read(new FileInputStream(CONFIG_FILE.toFile()), Configuration.class);
|
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", Arrays.asList(
|
||||||
|
"DefaultRoute", "SSH"
|
||||||
|
)),
|
||||||
|
createDefault("PC", "PC", "/icons/pc-100.png",
|
||||||
|
Collections.singletonList("DefaultRoute")),
|
||||||
|
createDefault("mdr", "MDR", "/icons/router-100.png", Arrays.asList(
|
||||||
|
"zebra", "OSPFv3MDR", "IPForward"
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NodeTypeConfig createDefault(String model, String display, String icon,
|
||||||
|
List<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() {
|
public static Configuration load() {
|
||||||
try {
|
try {
|
||||||
if (!HOME.toFile().exists()) {
|
if (!HOME.toFile().exists()) {
|
||||||
|
@ -42,6 +68,7 @@ public final class ConfigUtils {
|
||||||
Files.createDirectory(HOME);
|
Files.createDirectory(HOME);
|
||||||
Files.createDirectory(XML_DIR);
|
Files.createDirectory(XML_DIR);
|
||||||
Files.createDirectory(MOBILITY_DIR);
|
Files.createDirectory(MOBILITY_DIR);
|
||||||
|
Files.createDirectory(ICON_DIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Configuration configuration;
|
Configuration configuration;
|
||||||
|
@ -51,11 +78,30 @@ public final class ConfigUtils {
|
||||||
configuration = readConfig();
|
configuration = readConfig();
|
||||||
configuration.setXmlPath(XML_DIR.toString());
|
configuration.setXmlPath(XML_DIR.toString());
|
||||||
configuration.setMobilityPath(MOBILITY_DIR.toString());
|
configuration.setMobilityPath(MOBILITY_DIR.toString());
|
||||||
|
configuration.setIconPath(ICON_DIR.toString());
|
||||||
|
configuration.setNodeTypeConfigs(createDefaults());
|
||||||
save(configuration);
|
save(configuration);
|
||||||
} else {
|
} else {
|
||||||
configuration = readConfig();
|
configuration = readConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize node types
|
||||||
|
for (NodeTypeConfig nodeTypeConfig : configuration.getNodeTypeConfigs()) {
|
||||||
|
NodeType nodeType = new NodeType(
|
||||||
|
NodeType.DEFAULT,
|
||||||
|
nodeTypeConfig.getModel(),
|
||||||
|
nodeTypeConfig.getDisplay(),
|
||||||
|
nodeTypeConfig.getIcon()
|
||||||
|
);
|
||||||
|
nodeTypeConfig.getServices().sort(String::compareTo);
|
||||||
|
nodeType.getServices().addAll(nodeTypeConfig.getServices());
|
||||||
|
NodeType.add(nodeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// override configuration from command line
|
||||||
|
String coreRest = System.getProperty("core-rest");
|
||||||
|
configuration.setCoreRest(coreRest);
|
||||||
|
|
||||||
return configuration;
|
return configuration;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.error("error reading config file");
|
logger.error("error reading config file");
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class Configuration {
|
||||||
private String coreRest;
|
private String coreRest;
|
||||||
private String xmlPath;
|
private String xmlPath;
|
||||||
private String mobilityPath;
|
private String mobilityPath;
|
||||||
|
private String iconPath;
|
||||||
private String shellCommand;
|
private String shellCommand;
|
||||||
private List<NodeTypeConfig> nodeTypeConfigs = new ArrayList<>();
|
private List<NodeTypeConfig> nodeTypeConfigs = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
package com.core.utils;
|
package com.core.utils;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
public class NodeTypeConfig {
|
public class NodeTypeConfig {
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
private String model;
|
private String model;
|
||||||
private String display;
|
private String display;
|
||||||
private String icon;
|
private String icon;
|
||||||
private List<String> services = new ArrayList<>();
|
private List<String> services;
|
||||||
}
|
}
|
||||||
|
|
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