Merge branch 'rel/5.3' of git-ssh.web.boeing.com:Boeing-CORE/CORE into rel/5.3

This commit is contained in:
bharnden 2018-11-22 00:14:09 -08:00
commit d522649489
39 changed files with 297 additions and 208 deletions

View file

@ -1,12 +1,13 @@
package com.core; package com.core;
import com.core.client.ICoreClient; import com.core.client.ICoreClient;
import com.core.client.rest.*; import com.core.client.rest.CoreRestClient;
import com.core.data.*; import com.core.data.*;
import com.core.graph.NetworkGraph; import com.core.graph.NetworkGraph;
import com.core.ui.*; 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.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;
@ -48,7 +49,7 @@ public class Controller implements Initializable {
private Application application; private Application application;
private Stage window; private Stage window;
private Properties properties; private Configuration configuration;
// core client utilities // core client utilities
private ICoreClient coreClient = new CoreRestClient(); private ICoreClient coreClient = new CoreRestClient();
@ -96,30 +97,30 @@ public class Controller implements Initializable {
} }
private void initialJoin() throws IOException { private void initialJoin() throws IOException {
GetServices services = coreClient.getServices(); Map<String, List<String>> serviceGroups = coreClient.getServices();
logger.info("core services: {}", services); logger.info("core services: {}", serviceGroups);
nodeServicesDialog.setServices(services); nodeServicesDialog.setServices(serviceGroups);
logger.info("initial core session join"); logger.info("initial core session join");
GetSessions response = coreClient.getSessions(); List<SessionOverview> sessions = coreClient.getSessions();
logger.info("existing sessions: {}", response); logger.info("existing sessions: {}", sessions);
Integer sessionId; Integer sessionId;
if (response.getSessions().isEmpty()) { if (sessions.isEmpty()) {
logger.info("creating initial session"); logger.info("creating initial session");
CreatedSession createdSession = coreClient.createSession(); SessionOverview sessionOverview = coreClient.createSession();
sessionId = createdSession.getId(); sessionId = sessionOverview.getId();
Toast.info(String.format("Created Session %s", sessionId)); Toast.info(String.format("Created Session %s", sessionId));
} else { } else {
GetSessionsData getSessionsData = response.getSessions().get(0); SessionOverview sessionOverview = sessions.get(0);
sessionId = getSessionsData.getId(); sessionId = sessionOverview.getId();
Toast.info(String.format("Joined Session %s", sessionId)); Toast.info(String.format("Joined Session %s", sessionId));
} }
joinSession(sessionId); joinSession(sessionId);
// set emane models // set emane models
List<String> emaneModels = coreClient.getEmaneModels().getModels(); List<String> emaneModels = coreClient.getEmaneModels();
nodeEmaneDialog.setModels(emaneModels); nodeEmaneDialog.setModels(emaneModels);
} }
@ -127,8 +128,12 @@ public class Controller implements Initializable {
// clear graph // clear graph
networkGraph.reset(); networkGraph.reset();
// clear out any previously set information
bottom.getChildren().remove(mobilityPlayer);
mobilityDialog.setNode(null);
// get session to join // get session to join
GetSession session = coreClient.getSession(joinId); Session session = coreClient.getSession(joinId);
SessionState sessionState = SessionState.get(session.getState()); SessionState sessionState = SessionState.get(session.getState());
// update client to use this session // update client to use this session
@ -164,13 +169,14 @@ 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 // display first mobility script in player
GetMobilityConfigs getMobilityConfigs = coreClient.getMobilityConfigs(); Map<Integer, MobilityConfig> mobilityConfigMap = coreClient.getMobilityConfigs();
Optional<Integer> nodeIdOptional = getMobilityConfigs.getConfigurations().keySet().stream().findFirst(); Optional<Integer> nodeIdOptional = mobilityConfigMap.keySet().stream().findFirst();
if (nodeIdOptional.isPresent()) { if (nodeIdOptional.isPresent()) {
Integer nodeId = nodeIdOptional.get(); Integer nodeId = nodeIdOptional.get();
MobilityConfig mobilityConfig = getMobilityConfigs.getConfigurations().get(nodeId); MobilityConfig mobilityConfig = mobilityConfigMap.get(nodeId);
CoreNode node = networkGraph.getVertex(nodeId); CoreNode node = networkGraph.getVertex(nodeId);
mobilityPlayer.show(node, mobilityConfig); mobilityPlayer.show(node, mobilityConfig);
Platform.runLater(() -> bottom.getChildren().add(mobilityPlayer)); Platform.runLater(() -> bottom.getChildren().add(mobilityPlayer));
@ -294,20 +300,27 @@ public class Controller implements Initializable {
private void onOpenXmlAction() { private void onOpenXmlAction() {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Session"); fileChooser.setTitle("Open Session");
String xmlPath = properties.getProperty(ConfigUtils.XML_PATH); fileChooser.setInitialDirectory(new File(configuration.getXmlPath()));
fileChooser.setInitialDirectory(new File(xmlPath));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML", "*.xml")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML", "*.xml"));
File file = fileChooser.showOpenDialog(window); try {
if (file != null) { File file = fileChooser.showOpenDialog(window);
logger.info("opening session xml: {}", file.getPath()); if (file != null) {
try { openXml(file);
CreatedSession createdSession = coreClient.openSession(file);
Integer sessionId = createdSession.getId();
joinSession(sessionId);
Toast.info(String.format("Joined Session %s", sessionId));
} catch (IOException ex) {
logger.error("error opening session xml", ex);
} }
} catch (IllegalArgumentException ex) {
Toast.error(String.format("Invalid XML directory: %s", configuration.getXmlPath()));
}
}
private void openXml(File file) {
logger.info("opening session xml: {}", file.getPath());
try {
SessionOverview sessionOverview = coreClient.openSession(file);
Integer sessionId = sessionOverview.getId();
joinSession(sessionId);
Toast.info(String.format("Joined Session %s", sessionId));
} catch (IOException ex) {
Toast.error("Error opening session xml", ex);
} }
} }
@ -316,8 +329,7 @@ public class Controller implements Initializable {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Save Session"); fileChooser.setTitle("Save Session");
fileChooser.setInitialFileName("session.xml"); fileChooser.setInitialFileName("session.xml");
String xmlPath = properties.getProperty(ConfigUtils.XML_PATH); fileChooser.setInitialDirectory(new File(configuration.getXmlPath()));
fileChooser.setInitialDirectory(new File(xmlPath));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML", "*.xml")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML", "*.xml"));
File file = fileChooser.showSaveDialog(window); File file = fileChooser.showSaveDialog(window);
if (file != null) { if (file != null) {
@ -325,7 +337,7 @@ public class Controller implements Initializable {
try { try {
coreClient.saveSession(file); coreClient.saveSession(file);
} catch (IOException ex) { } catch (IOException ex) {
logger.error("error saving session xml", ex); Toast.error("Error saving session xml", ex);
} }
} }
} }
@ -348,12 +360,11 @@ public class Controller implements Initializable {
@FXML @FXML
private void onSessionOptionsMenu(ActionEvent event) { private void onSessionOptionsMenu(ActionEvent event) {
try { try {
GetConfig config = coreClient.getSessionConfig(); List<ConfigGroup> configGroups = coreClient.getSessionConfig();
configDialog.showDialog("Session Options", config, () -> { configDialog.showDialog("Session Options", configGroups, () -> {
List<ConfigOption> options = configDialog.getOptions(); List<ConfigOption> options = configDialog.getOptions();
SetConfig setConfig = new SetConfig(options);
try { try {
boolean result = coreClient.setSessionConfig(setConfig); boolean result = coreClient.setSessionConfig(options);
if (result) { if (result) {
Toast.info("Session options saved"); Toast.info("Session options saved");
} else { } else {
@ -381,8 +392,8 @@ public class Controller implements Initializable {
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
coreWebSocket = new CoreWebSocket(this); coreWebSocket = new CoreWebSocket(this);
properties = ConfigUtils.load(); configuration = ConfigUtils.load();
String coreUrl = properties.getProperty(ConfigUtils.REST_URL); String coreUrl = configuration.getCoreRest();
logger.info("core rest: {}", coreUrl); logger.info("core rest: {}", coreUrl);
connectDialog.setCoreUrl(coreUrl); connectDialog.setCoreUrl(coreUrl);
connectToCore(coreUrl); connectToCore(coreUrl);

View file

@ -1,12 +1,14 @@
package com.core.client; package com.core.client;
import com.core.client.rest.*; import com.core.client.rest.ServiceFile;
import com.core.client.rest.WlanConfig;
import com.core.data.*; import com.core.data.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
public interface ICoreClient { public interface ICoreClient {
void setUrl(String url); void setUrl(String url);
@ -15,11 +17,11 @@ public interface ICoreClient {
void updateState(SessionState state); void updateState(SessionState state);
CreatedSession createSession() throws IOException; SessionOverview createSession() throws IOException;
GetSessions getSessions() throws IOException; List<SessionOverview> getSessions() throws IOException;
GetSession 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;
@ -27,7 +29,9 @@ public interface ICoreClient {
boolean setState(SessionState state) throws IOException; boolean setState(SessionState state) throws IOException;
GetServices getServices() throws IOException; Map<String, List<String>> getServices() throws IOException;
Map<String, List<String>> defaultServices() throws IOException;
CoreService getService(CoreNode node, String serviceName) throws IOException; CoreService getService(CoreNode node, String serviceName) throws IOException;
@ -37,13 +41,13 @@ public interface ICoreClient {
boolean setServiceFile(CoreNode node, String serviceName, ServiceFile serviceFile) throws IOException; boolean setServiceFile(CoreNode node, String serviceName, ServiceFile serviceFile) throws IOException;
GetConfig getEmaneConfig(CoreNode node) throws IOException; List<ConfigGroup> getEmaneConfig(CoreNode node) throws IOException;
GetEmaneModels getEmaneModels() throws IOException; List<String> getEmaneModels() throws IOException;
boolean setEmaneConfig(CoreNode node, List<ConfigOption> options) throws IOException; boolean setEmaneConfig(CoreNode node, List<ConfigOption> options) throws IOException;
GetConfig getEmaneModelConfig(Integer id, String model) throws IOException; List<ConfigGroup> getEmaneModelConfig(Integer id, String model) throws IOException;
boolean setEmaneModelConfig(Integer id, String model, List<ConfigOption> options) throws IOException; boolean setEmaneModelConfig(Integer id, String model, List<ConfigOption> options) throws IOException;
@ -51,11 +55,11 @@ public interface ICoreClient {
void saveSession(File file) throws IOException; void saveSession(File file) throws IOException;
CreatedSession openSession(File file) throws IOException; SessionOverview openSession(File file) throws IOException;
GetConfig getSessionConfig() throws IOException; List<ConfigGroup> getSessionConfig() throws IOException;
boolean setSessionConfig(SetConfig config) throws IOException; boolean setSessionConfig(List<ConfigOption> configOptions) throws IOException;
boolean createNode(CoreNode node) throws IOException; boolean createNode(CoreNode node) throws IOException;
@ -69,7 +73,7 @@ public interface ICoreClient {
boolean createHook(Hook hook) throws IOException; boolean createHook(Hook hook) throws IOException;
GetHooks getHooks() throws IOException; List<Hook> getHooks() throws IOException;
WlanConfig getWlanConfig(CoreNode node) throws IOException; WlanConfig getWlanConfig(CoreNode node) throws IOException;
@ -77,7 +81,7 @@ public interface ICoreClient {
String getTerminalCommand(CoreNode node) throws IOException; String getTerminalCommand(CoreNode node) throws IOException;
GetMobilityConfigs getMobilityConfigs() throws IOException; Map<Integer, MobilityConfig> getMobilityConfigs() throws IOException;
boolean setMobilityConfig(CoreNode node, MobilityConfig config) throws IOException; boolean setMobilityConfig(CoreNode node, MobilityConfig config) throws IOException;

View file

@ -41,27 +41,29 @@ public class CoreRestClient implements ICoreClient {
} }
@Override @Override
public CreatedSession createSession() throws IOException { public SessionOverview createSession() throws IOException {
String url = getUrl("sessions"); String url = getUrl("sessions");
return WebUtils.post(url, CreatedSession.class); return WebUtils.post(url, SessionOverview.class);
} }
public GetServices getServices() throws IOException { public Map<String, List<String>> getServices() throws IOException {
String url = getUrl("services"); String url = getUrl("services");
return WebUtils.getJson(url, GetServices.class); GetServices getServices = WebUtils.getJson(url, GetServices.class);
return getServices.getGroups();
} }
@Override @Override
public GetSession getSession(Integer sessionId) throws IOException { public Session getSession(Integer sessionId) throws IOException {
String path = String.format("sessions/%s", sessionId); String path = String.format("sessions/%s", sessionId);
String url = getUrl(path); String url = getUrl(path);
return WebUtils.getJson(url, GetSession.class); return WebUtils.getJson(url, Session.class);
} }
@Override @Override
public GetSessions getSessions() throws IOException { public List<SessionOverview> getSessions() throws IOException {
String url = getUrl("sessions"); String url = getUrl("sessions");
return WebUtils.getJson(url, GetSessions.class); GetSessions getSessions = WebUtils.getJson(url, GetSessions.class);
return getSessions.getSessions();
} }
@Override @Override
@ -126,6 +128,13 @@ public class CoreRestClient implements ICoreClient {
return WebUtils.postFile(url, file); return WebUtils.postFile(url, file);
} }
@Override
public Map<String, List<String>> defaultServices() throws IOException {
String url = getUrl(String.format("sessions/%s/services/default", sessionId));
GetDefaultServices getDefaultServices = WebUtils.getJson(url, GetDefaultServices.class);
return getDefaultServices.getDefaults();
}
@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));
@ -155,26 +164,29 @@ public class CoreRestClient implements ICoreClient {
} }
@Override @Override
public GetEmaneModels getEmaneModels() throws IOException { public List<String> getEmaneModels() throws IOException {
String url = getUrl(String.format("sessions/%s/emane/models", sessionId)); String url = getUrl(String.format("sessions/%s/emane/models", sessionId));
return WebUtils.getJson(url, GetEmaneModels.class); GetEmaneModels getEmaneModels = WebUtils.getJson(url, GetEmaneModels.class);
return getEmaneModels.getModels();
} }
@Override @Override
public GetConfig getEmaneModelConfig(Integer id, String model) throws IOException { public List<ConfigGroup> getEmaneModelConfig(Integer id, String model) throws IOException {
String url = getUrl(String.format("sessions/%s/emane/model/config", sessionId)); String url = getUrl(String.format("sessions/%s/emane/model/config", sessionId));
Map<String, String> args = new HashMap<>(); Map<String, String> args = new HashMap<>();
args.put("node", id.toString()); args.put("node", id.toString());
args.put("name", model); args.put("name", model);
return WebUtils.getJson(url, GetConfig.class, args); GetConfig getConfig = WebUtils.getJson(url, GetConfig.class, args);
return getConfig.getGroups();
} }
@Override @Override
public GetConfig getEmaneConfig(CoreNode node) throws IOException { public List<ConfigGroup> getEmaneConfig(CoreNode node) throws IOException {
String url = getUrl(String.format("sessions/%s/emane/config", sessionId)); String url = getUrl(String.format("sessions/%s/emane/config", sessionId));
Map<String, String> args = new HashMap<>(); Map<String, String> args = new HashMap<>();
args.put("node", node.getId().toString()); args.put("node", node.getId().toString());
return WebUtils.getJson(url, GetConfig.class, args); GetConfig getConfig = WebUtils.getJson(url, GetConfig.class, args);
return getConfig.getGroups();
} }
@Override @Override
@ -209,21 +221,23 @@ public class CoreRestClient implements ICoreClient {
} }
@Override @Override
public CreatedSession openSession(File file) throws IOException { public SessionOverview openSession(File file) throws IOException {
String url = getUrl("sessions/xml"); String url = getUrl("sessions/xml");
return WebUtils.postFile(url, file, CreatedSession.class); return WebUtils.postFile(url, file, SessionOverview.class);
} }
@Override @Override
public GetConfig getSessionConfig() throws IOException { public List<ConfigGroup> getSessionConfig() throws IOException {
String url = getUrl(String.format("sessions/%s/options", sessionId)); String url = getUrl(String.format("sessions/%s/options", sessionId));
return WebUtils.getJson(url, GetConfig.class); GetConfig getConfig = WebUtils.getJson(url, GetConfig.class);
return getConfig.getGroups();
} }
@Override @Override
public boolean setSessionConfig(SetConfig config) throws IOException { public boolean setSessionConfig(List<ConfigOption> configOptions) throws IOException {
String url = getUrl(String.format("sessions/%s/options", sessionId)); String url = getUrl(String.format("sessions/%s/options", sessionId));
return WebUtils.putJson(url, config); SetConfig setConfig = new SetConfig(configOptions);
return WebUtils.putJson(url, setConfig);
} }
@Override @Override
@ -275,9 +289,10 @@ public class CoreRestClient implements ICoreClient {
} }
@Override @Override
public GetHooks getHooks() throws IOException { public List<Hook> getHooks() throws IOException {
String url = getUrl(String.format("sessions/%s/hooks", sessionId)); String url = getUrl(String.format("sessions/%s/hooks", sessionId));
return WebUtils.getJson(url, GetHooks.class); GetHooks getHooks = WebUtils.getJson(url, GetHooks.class);
return getHooks.getHooks();
} }
@Override @Override
@ -311,9 +326,10 @@ public class CoreRestClient implements ICoreClient {
} }
@Override @Override
public GetMobilityConfigs getMobilityConfigs() throws IOException { public Map<Integer, MobilityConfig> getMobilityConfigs() throws IOException {
String url = getUrl(String.format("sessions/%s/mobility/configs", sessionId)); String url = getUrl(String.format("sessions/%s/mobility/configs", sessionId));
return WebUtils.getJson(url, GetMobilityConfigs.class); GetMobilityConfigs getMobilityConfigs = WebUtils.getJson(url, GetMobilityConfigs.class);
return getMobilityConfigs.getConfigurations();
} }
@Override @Override

View file

@ -1,10 +0,0 @@
package com.core.client.rest;
import lombok.Data;
@Data
public class CreatedSession {
private Integer id;
private Integer state;
private String url;
}

View file

@ -1,5 +1,6 @@
package com.core.client.rest; package com.core.client.rest;
import com.core.data.ConfigGroup;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -0,0 +1,16 @@
package com.core.client.rest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GetDefaultServices {
private Map<String, List<String>> defaults = new HashMap<>();
}

View file

@ -1,5 +1,6 @@
package com.core.client.rest; package com.core.client.rest;
import com.core.data.SessionOverview;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -9,5 +10,5 @@ import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class GetSessions { public class GetSessions {
private List<GetSessionsData> sessions = new ArrayList<>(); private List<SessionOverview> sessions = new ArrayList<>();
} }

View file

@ -1,5 +1,6 @@
package com.core.client.rest; package com.core.client.rest;
import com.core.data.ConfigOption;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;

View file

@ -1,5 +1,6 @@
package com.core.client.rest; package com.core.client.rest;
import com.core.data.ConfigOption;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -1,5 +1,6 @@
package com.core.client.rest; package com.core.client.rest;
import com.core.data.ConfigOption;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -1,4 +1,4 @@
package com.core.client.rest; package com.core.data;
import lombok.Data; import lombok.Data;

View file

@ -1,4 +1,4 @@
package com.core.client.rest; package com.core.data;
import lombok.Data; import lombok.Data;

View file

@ -1,7 +1,5 @@
package com.core.client.rest; package com.core.data;
import com.core.data.CoreNode;
import com.core.data.CoreLink;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -10,7 +8,7 @@ import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class GetSession { public class Session {
private Integer state; private Integer 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

@ -1,12 +1,13 @@
package com.core.client.rest; package com.core.data;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class GetSessionsData { public class SessionOverview {
private Integer id; private Integer id;
private Integer state; private Integer state;
private Integer nodes; private Integer nodes = 0;
private String url;
} }

View file

@ -3,7 +3,6 @@ package com.core.graph;
import com.core.Controller; import com.core.Controller;
import com.core.data.*; import com.core.data.*;
import com.core.ui.Toast; import com.core.ui.Toast;
import com.core.utils.ConfigUtils;
import com.core.utils.IconUtils; import com.core.utils.IconUtils;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import edu.uci.ics.jung.algorithms.layout.StaticLayout; import edu.uci.ics.jung.algorithms.layout.StaticLayout;
@ -72,7 +71,7 @@ public class NetworkGraph {
// node render properties // node render properties
renderContext.setVertexLabelTransformer(CoreNode::getName); renderContext.setVertexLabelTransformer(CoreNode::getName);
renderContext.setVertexShapeTransformer(node -> { renderContext.setVertexShapeTransformer(node -> {
double offset = -(IconUtils.ICON_SIZE / 2); double offset = -(IconUtils.ICON_SIZE / 2.0);
return new Ellipse2D.Double(offset, offset, IconUtils.ICON_SIZE, IconUtils.ICON_SIZE); return new Ellipse2D.Double(offset, offset, IconUtils.ICON_SIZE, IconUtils.ICON_SIZE);
}); });
renderContext.setVertexIconTransformer(vertex -> { renderContext.setVertexIconTransformer(vertex -> {
@ -118,7 +117,7 @@ public class NetworkGraph {
if (mouseEvent.getClickCount() == 2 && controller.getCoreClient().isRunning()) { if (mouseEvent.getClickCount() == 2 && controller.getCoreClient().isRunning()) {
try { try {
String shellCommand = controller.getProperties().getProperty(ConfigUtils.SHELL_COMMAND); String shellCommand = controller.getConfiguration().getShellCommand();
String terminalCommand = controller.getCoreClient().getTerminalCommand(node); String terminalCommand = controller.getCoreClient().getTerminalCommand(node);
terminalCommand = String.format("%s %s", shellCommand, terminalCommand); terminalCommand = String.format("%s %s", shellCommand, terminalCommand);
logger.info("launching node terminal: {}", terminalCommand); logger.info("launching node terminal: {}", terminalCommand);
@ -348,8 +347,8 @@ public class NetworkGraph {
public void addNode(CoreNode node) { public void addNode(CoreNode node) {
vertexId = Math.max(node.getId() + 1, node.getId()); vertexId = Math.max(node.getId() + 1, node.getId());
Double x = Math.abs(node.getPosition().getX()); double x = Math.abs(node.getPosition().getX());
Double y = Math.abs(node.getPosition().getY()); double y = Math.abs(node.getPosition().getY());
logger.info("adding session node: {}", node); logger.info("adding session node: {}", node);
graph.addVertex(node); graph.addVertex(node);
graphLayout.setLocation(node, x, y); graphLayout.setLocation(node, x, y);
@ -363,8 +362,8 @@ public class NetworkGraph {
node.getPosition().setY(nodeData.getPosition().getY()); node.getPosition().setY(nodeData.getPosition().getY());
// set graph node location // set graph node location
Double x = Math.abs(node.getPosition().getX()); double x = Math.abs(node.getPosition().getX());
Double y = Math.abs(node.getPosition().getY()); double y = Math.abs(node.getPosition().getY());
graphLayout.setLocation(node, x, y); graphLayout.setLocation(node, x, y);
graphViewer.repaint(); graphViewer.repaint();
} }

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.stage.Stage; import javafx.stage.Stage;
import lombok.Data; import lombok.Data;

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import com.jfoenix.controls.JFXToggleButton; import com.jfoenix.controls.JFXToggleButton;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.stage.Stage; import javafx.stage.Stage;

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import com.core.data.ConfigDataType; import com.core.data.ConfigDataType;
import javafx.stage.Stage; import javafx.stage.Stage;

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.stage.Stage; import javafx.stage.Stage;

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import javafx.scene.Node; import javafx.scene.Node;

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;

View file

@ -1,6 +1,6 @@
package com.core.ui.config; package com.core.ui.config;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import com.jfoenix.controls.JFXComboBox; import com.jfoenix.controls.JFXComboBox;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.stage.Stage; import javafx.stage.Stage;

View file

@ -1,9 +1,8 @@
package com.core.ui.dialogs; package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.client.rest.ConfigGroup; import com.core.data.ConfigGroup;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigOption;
import com.core.client.rest.GetConfig;
import com.core.ui.config.ConfigItemUtils; import com.core.ui.config.ConfigItemUtils;
import com.core.ui.config.IConfigItem; import com.core.ui.config.IConfigItem;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
@ -38,12 +37,12 @@ public class ConfigDialog extends StageDialog {
return configItems.stream().map(IConfigItem::getOption).collect(Collectors.toList()); return configItems.stream().map(IConfigItem::getOption).collect(Collectors.toList());
} }
public void showDialog(String title, GetConfig getConfig, Runnable runnable) { public void showDialog(String title, List<ConfigGroup> configGroups, Runnable runnable) {
setTitle(title); setTitle(title);
configItems.clear(); configItems.clear();
tabPane.getTabs().clear(); tabPane.getTabs().clear();
for (ConfigGroup group : getConfig.getGroups()) { for (ConfigGroup group : configGroups) {
String groupName = group.getName(); String groupName = group.getName();
Tab tab = new Tab(groupName); Tab tab = new Tab(groupName);
ScrollPane scrollPane = new ScrollPane(); ScrollPane scrollPane = new ScrollPane();

View file

@ -3,6 +3,7 @@ package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.ui.Toast; import com.core.ui.Toast;
import com.core.utils.ConfigUtils; import com.core.utils.ConfigUtils;
import com.core.utils.Configuration;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
@ -12,7 +13,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.IOException; import java.io.IOException;
import java.util.Properties;
public class GuiPreferencesDialog extends StageDialog { public class GuiPreferencesDialog extends StageDialog {
private static final Logger logger = LogManager.getLogger(); private static final Logger logger = LogManager.getLogger();
@ -30,12 +30,12 @@ public class GuiPreferencesDialog extends StageDialog {
} }
private EventHandler<ActionEvent> onSave = event -> { private EventHandler<ActionEvent> onSave = event -> {
Properties properties = getController().getProperties(); Configuration configuration = getController().getConfiguration();
properties.setProperty(ConfigUtils.XML_PATH, xmlFilePathTextField.getText()); configuration.setXmlPath(xmlFilePathTextField.getText());
properties.setProperty(ConfigUtils.MOBILITY_PATH, mobilityFilePathTextField.getText()); configuration.setMobilityPath(mobilityFilePathTextField.getText());
properties.setProperty(ConfigUtils.SHELL_COMMAND, shellCommandTextField.getText()); configuration.setShellCommand(shellCommandTextField.getText());
try { try {
ConfigUtils.save(properties); ConfigUtils.save(configuration);
Toast.success("Updated preferences"); Toast.success("Updated preferences");
} catch (IOException ex) { } catch (IOException ex) {
Toast.error("Failure to update preferences", ex); Toast.error("Failure to update preferences", ex);
@ -44,10 +44,10 @@ public class GuiPreferencesDialog extends StageDialog {
}; };
public void showDialog() { public void showDialog() {
Properties properties = getController().getProperties(); Configuration configuration = getController().getConfiguration();
xmlFilePathTextField.setText(properties.getProperty(ConfigUtils.XML_PATH)); xmlFilePathTextField.setText(configuration.getXmlPath());
mobilityFilePathTextField.setText(properties.getProperty(ConfigUtils.MOBILITY_PATH)); mobilityFilePathTextField.setText(configuration.getMobilityPath());
shellCommandTextField.setText(properties.getProperty(ConfigUtils.SHELL_COMMAND)); shellCommandTextField.setText(configuration.getShellCommand());
show(); show();
} }
} }

View file

@ -1,7 +1,6 @@
package com.core.ui.dialogs; package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.client.rest.GetHooks;
import com.core.data.Hook; import com.core.data.Hook;
import com.core.data.SessionState; import com.core.data.SessionState;
import com.core.ui.Toast; import com.core.ui.Toast;
@ -98,8 +97,8 @@ public class HooksDialog extends StageDialog {
// update hooks // update hooks
try { try {
GetHooks getHooks = getCoreClient().getHooks(); List<Hook> hooks = getCoreClient().getHooks();
for (Hook hook : getHooks.getHooks()) { for (Hook hook : hooks) {
SessionState state = SessionState.get(hook.getState()); SessionState state = SessionState.get(hook.getState());
hook.setStateDisplay(state.name()); hook.setStateDisplay(state.name());
hooksTable.getItems().add(hook); hooksTable.getItems().add(hook);

View file

@ -4,7 +4,6 @@ import com.core.Controller;
import com.core.data.CoreNode; import com.core.data.CoreNode;
import com.core.data.MobilityConfig; import com.core.data.MobilityConfig;
import com.core.ui.Toast; import com.core.ui.Toast;
import com.core.utils.ConfigUtils;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import com.jfoenix.controls.JFXToggleButton; import com.jfoenix.controls.JFXToggleButton;
@ -73,14 +72,19 @@ public class MobilityDialog extends StageDialog {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Select File"); fileChooser.setTitle("Select File");
String mobilityPath = getController().getProperties().getProperty(ConfigUtils.MOBILITY_PATH); String mobilityPath = getController().getConfiguration().getMobilityPath();
fileChooser.setInitialDirectory(new File(mobilityPath)); fileChooser.setInitialDirectory(new File(mobilityPath));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Mobility", fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Mobility",
"*.mobility")); "*.mobility"));
File file = fileChooser.showOpenDialog(getController().getWindow()); try {
if (file != null) { File file = fileChooser.showOpenDialog(getController().getWindow());
logger.info("opening session xml: {}", file.getPath()); if (file != null) {
textField.setText(file.getPath()); logger.info("opening session xml: {}", file.getPath());
textField.setText(file.getPath());
}
} catch (IllegalArgumentException ex) {
Toast.error(String.format("Invalid mobility directory: %s",
getController().getConfiguration().getMobilityPath()));
} }
} }

View file

@ -1,8 +1,8 @@
package com.core.ui.dialogs; package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.client.rest.ConfigOption; import com.core.data.ConfigGroup;
import com.core.client.rest.GetConfig; import com.core.data.ConfigOption;
import com.core.data.CoreNode; import com.core.data.CoreNode;
import com.core.ui.Toast; import com.core.ui.Toast;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
@ -50,10 +50,10 @@ public class NodeEmaneDialog extends StageDialog {
private void emaneButtonHandler(ActionEvent event) { private void emaneButtonHandler(ActionEvent event) {
try { try {
GetConfig getConfig = getCoreClient().getEmaneConfig(coreNode); List<ConfigGroup> configGroups = getCoreClient().getEmaneConfig(coreNode);
logger.debug("emane model config: {}", getConfig); logger.debug("emane model config: {}", configGroups);
String title = String.format("%s EMANE Config", coreNode.getName()); String title = String.format("%s EMANE Config", coreNode.getName());
getController().getConfigDialog().showDialog(title, getConfig, () -> { getController().getConfigDialog().showDialog(title, configGroups, () -> {
List<ConfigOption> options = getController().getConfigDialog().getOptions(); List<ConfigOption> options = getController().getConfigDialog().getOptions();
try { try {
getCoreClient().setEmaneConfig(coreNode, options); getCoreClient().setEmaneConfig(coreNode, options);
@ -73,10 +73,10 @@ public class NodeEmaneDialog extends StageDialog {
public void displayEmaneModelConfig(Integer id, String model) { public void displayEmaneModelConfig(Integer id, String model) {
try { try {
GetConfig getConfig = getCoreClient().getEmaneModelConfig(id, model); List<ConfigGroup> configGroups = getCoreClient().getEmaneModelConfig(id, model);
logger.debug("emane model config: {}", getConfig); logger.debug("emane model config: {}", configGroups);
String title = String.format("EMANE(%s) %s Config", id, model); String title = String.format("EMANE(%s) %s Config", id, model);
getController().getConfigDialog().showDialog(title, getConfig, () -> { getController().getConfigDialog().showDialog(title, configGroups, () -> {
List<ConfigOption> options = getController().getConfigDialog().getOptions(); List<ConfigOption> options = getController().getConfigDialog().getOptions();
try { try {
getCoreClient().setEmaneModelConfig(id, model, options); getCoreClient().setEmaneModelConfig(id, model, options);

View file

@ -1,7 +1,6 @@
package com.core.ui.dialogs; package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.client.rest.GetServices;
import com.core.data.CoreNode; import com.core.data.CoreNode;
import com.core.ui.ServiceItem; import com.core.ui.ServiceItem;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
@ -81,14 +80,14 @@ public class NodeServicesDialog extends StageDialog {
}); });
} }
public void setServices(GetServices getServices) { public void setServices(Map<String, List<String>> serviceGroups) {
serviceItemGroups.clear(); serviceItemGroups.clear();
getServices.getGroups().keySet().stream() serviceGroups.keySet().stream()
.sorted() .sorted()
.forEach(group -> { .forEach(group -> {
groupListView.getItems().add(group); groupListView.getItems().add(group);
getServices.getGroups().get(group).stream() serviceGroups.get(group).stream()
.sorted() .sorted()
.forEach(service -> { .forEach(service -> {
ServiceItem serviceItem = new ServiceItem(service); ServiceItem serviceItem = new ServiceItem(service);

View file

@ -15,13 +15,17 @@ 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.Map; import java.util.Map;
public class NodeTypesDialog extends StageDialog { 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;
@ -31,6 +35,7 @@ public class NodeTypesDialog extends StageDialog {
@FXML private JFXButton saveButton; @FXML private JFXButton saveButton;
@FXML private JFXButton addButton; @FXML private JFXButton addButton;
@FXML private JFXButton deleteButton; @FXML private JFXButton deleteButton;
@FXML private JFXListView<String> nodeServicesListView;
public NodeTypesDialog(Controller controller) { public NodeTypesDialog(Controller controller) {
super(controller, "/fxml/node_types_dialog.fxml"); super(controller, "/fxml/node_types_dialog.fxml");
@ -48,6 +53,8 @@ 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());
nodeServicesListView.getItems().setAll(services);
}); });
iconButton.setOnAction(event -> { iconButton.setOnAction(event -> {
@ -79,6 +86,15 @@ public class NodeTypesDialog extends StageDialog {
}); });
} }
public void updateDefaultServices() {
try {
defaultServices = getCoreClient().defaultServices();
listView.getSelectionModel().selectFirst();
} catch (IOException ex) {
Toast.error("Error getting default services", ex);
}
}
public void showDialog() { public void showDialog() {
listView.getItems().clear(); listView.getItems().clear();
nodeTypeMap.clear(); nodeTypeMap.clear();

View file

@ -1,8 +1,7 @@
package com.core.ui.dialogs; package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.client.rest.GetSessions; import com.core.data.SessionOverview;
import com.core.client.rest.GetSessionsData;
import com.core.data.SessionState; import com.core.data.SessionState;
import com.core.ui.Toast; import com.core.ui.Toast;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
@ -15,6 +14,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class SessionsDialog extends StageDialog { public class SessionsDialog extends StageDialog {
@ -55,17 +55,17 @@ public class SessionsDialog extends StageDialog {
private String state; private String state;
private Integer nodes; private Integer nodes;
public SessionRow(GetSessionsData getSessionsData) { public SessionRow(SessionOverview sessionOverview) {
id = getSessionsData.getId(); id = sessionOverview.getId();
state = SessionState.get(getSessionsData.getState()).name(); state = SessionState.get(sessionOverview.getState()).name();
nodes = getSessionsData.getNodes(); nodes = sessionOverview.getNodes();
} }
} }
public void showDialog() throws IOException { public void showDialog() throws IOException {
sessionsTable.getItems().clear(); sessionsTable.getItems().clear();
GetSessions getSessions = getCoreClient().getSessions(); List<SessionOverview> sessions = getCoreClient().getSessions();
sessionsTable.getItems().addAll(getSessions.getSessions().stream() sessionsTable.getItems().addAll(sessions.stream()
.map(SessionRow::new) .map(SessionRow::new)
.collect(Collectors.toList())); .collect(Collectors.toList()));

View file

@ -1,8 +1,7 @@
package com.core.ui.dialogs; package com.core.ui.dialogs;
import com.core.Controller; import com.core.Controller;
import com.core.client.rest.GetSessions; import com.core.data.SessionOverview;
import com.core.client.rest.GetSessionsData;
import com.core.data.SessionState; import com.core.data.SessionState;
import com.core.ui.Toast; import com.core.ui.Toast;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
@ -15,6 +14,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class SessionsFoenixDialog extends CoreFoenixDialog { public class SessionsFoenixDialog extends CoreFoenixDialog {
@ -52,17 +52,17 @@ public class SessionsFoenixDialog extends CoreFoenixDialog {
private String state; private String state;
private Integer nodes; private Integer nodes;
public SessionRow(GetSessionsData getSessionsData) { public SessionRow(SessionOverview sessionOverview) {
id = getSessionsData.getId(); id = sessionOverview.getId();
state = SessionState.get(getSessionsData.getState()).name(); state = SessionState.get(sessionOverview.getState()).name();
nodes = getSessionsData.getNodes(); nodes = sessionOverview.getNodes();
} }
} }
public void showDialog() throws IOException { public void showDialog() throws IOException {
sessionsTable.getItems().clear(); sessionsTable.getItems().clear();
GetSessions getSessions = getCoreClient().getSessions(); List<SessionOverview> sessions = getCoreClient().getSessions();
sessionsTable.getItems().addAll(getSessions.getSessions().stream() sessionsTable.getItems().addAll(sessions.stream()
.map(SessionRow::new) .map(SessionRow::new)
.collect(Collectors.toList())); .collect(Collectors.toList()));
getDialog().show(getController().getStackPane()); getDialog().show(getController().getStackPane());

View file

@ -4,36 +4,38 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
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.Properties;
public final class ConfigUtils { public final class ConfigUtils {
private static final Logger logger = LogManager.getLogger(); private static final Logger logger = LogManager.getLogger();
private static final String DEFAULT_CONFIG = "/config.properties"; private static final String CONFIG_FILE_NAME = "config.json";
private static final String DEFAULT_CONFIG = "/" + CONFIG_FILE_NAME;
private static final Path HOME = Paths.get(System.getProperty("user.home"), ".core"); private static final Path HOME = Paths.get(System.getProperty("user.home"), ".core");
private static final Path PROPERTIES_FILE = Paths.get(HOME.toString(), "config.properties"); 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");
// config fields
public static final String REST_URL = "core-rest";
public static final String XML_PATH = "xml-path";
public static final String MOBILITY_PATH = "mobility-path";
public static final String SHELL_COMMAND = "shell-command";
private ConfigUtils() { private ConfigUtils() {
} }
public static void save(Properties properties) throws IOException { public static void save(Configuration configuration) throws IOException {
properties.store(new FileOutputStream(PROPERTIES_FILE.toFile()), null); String fileData = JsonUtils.toPrettyString(configuration);
try (PrintWriter out = new PrintWriter(CONFIG_FILE.toFile())) {
out.println(fileData);
}
} }
public static Properties load() { private static Configuration readConfig() throws IOException {
return JsonUtils.read(new FileInputStream(CONFIG_FILE.toFile()), Configuration.class);
}
public static Configuration load() {
try { try {
if (!HOME.toFile().exists()) { if (!HOME.toFile().exists()) {
logger.info("creating core home directory"); logger.info("creating core home directory");
@ -42,28 +44,19 @@ public final class ConfigUtils {
Files.createDirectory(MOBILITY_DIR); Files.createDirectory(MOBILITY_DIR);
} }
Properties properties = new Properties(); Configuration configuration;
if (!PROPERTIES_FILE.toFile().exists()) { if (!CONFIG_FILE.toFile().exists()) {
logger.info("creating default configuration"); logger.info("creating default configuration");
Files.copy(ConfigUtils.class.getResourceAsStream(DEFAULT_CONFIG), PROPERTIES_FILE); Files.copy(ConfigUtils.class.getResourceAsStream(DEFAULT_CONFIG), CONFIG_FILE);
properties.load(new FileInputStream(PROPERTIES_FILE.toFile())); configuration = readConfig();
properties.setProperty(XML_PATH, XML_DIR.toString()); configuration.setXmlPath(XML_DIR.toString());
properties.setProperty(MOBILITY_PATH, MOBILITY_DIR.toString()); configuration.setMobilityPath(MOBILITY_DIR.toString());
save(properties); save(configuration);
} else { } else {
properties.load(new FileInputStream(PROPERTIES_FILE.toFile())); configuration = readConfig();
} }
// override values if provided return configuration;
for (String key : properties.stringPropertyNames()) {
String value = System.getProperty(key);
if (value != null) {
logger.info("command line config: {} - {}", key, value);
properties.setProperty(key, value);
}
}
return properties;
} catch (IOException ex) { } catch (IOException ex) {
logger.error("error reading config file"); logger.error("error reading config file");
throw new RuntimeException("configuration file did not exist"); throw new RuntimeException("configuration file did not exist");

View file

@ -0,0 +1,17 @@
package com.core.utils;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class Configuration {
private String coreRest;
private String xmlPath;
private String mobilityPath;
private String shellCommand;
private List<NodeTypeConfig> nodeTypeConfigs = new ArrayList<>();
}

View file

@ -39,6 +39,10 @@ public final class JsonUtils {
} }
} }
public static String toPrettyString(Object obj) throws JsonProcessingException {
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}
public static String toString(Object obj) throws JsonProcessingException { public static String toString(Object obj) throws JsonProcessingException {
return mapper.writeValueAsString(obj); return mapper.writeValueAsString(obj);
} }

View file

@ -0,0 +1,16 @@
package com.core.utils;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class NodeTypeConfig {
private String model;
private String display;
private String icon;
private List<String> services = new ArrayList<>();
}

View file

@ -0,0 +1,6 @@
{
"coreRest": "http://127.0.0.1:5000",
"xmlPath": null,
"mobilityPath": null,
"shellCommand": "gnome-terminal --window --"
}

View file

@ -1,2 +0,0 @@
core-rest=http://127.0.0.1:5000
shell-command=gnome-terminal --window --

View file

@ -18,17 +18,20 @@
<children> <children>
<MenuBar> <MenuBar>
<menus> <menus>
<Menu mnemonicParsing="false" text="Main"> <Menu mnemonicParsing="false" text="Menu">
<items> <items>
<MenuItem mnemonicParsing="false" onAction="#onCoreMenuConnect" text="Connection" /> <MenuItem mnemonicParsing="false" onAction="#onCoreMenuConnect" text="Connection" />
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem fx:id="saveXmlMenuItem" disable="true" mnemonicParsing="false" onAction="#onSaveXmlAction" text="Save XML" />
<MenuItem mnemonicParsing="false" onAction="#onOpenXmlAction" text="Open XML" />
</items>
</Menu>
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuNodeTypes" text="Nodes" />
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuBackground" text="Background" />
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuPreferences" text="Preferences" />
</items> </items>
</Menu> </Menu>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem fx:id="saveXmlMenuItem" disable="true" mnemonicParsing="false" onAction="#onSaveXmlAction" text="Save XML" />
<MenuItem mnemonicParsing="false" onAction="#onOpenXmlAction" text="Open XML" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Session"> <Menu mnemonicParsing="false" text="Session">
<items> <items>
<MenuItem mnemonicParsing="false" onAction="#onJoinSessionMenu" text="Join" /> <MenuItem mnemonicParsing="false" onAction="#onJoinSessionMenu" text="Join" />
@ -36,13 +39,6 @@
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuLocation" text="Location" /> <MenuItem mnemonicParsing="false" onAction="#onOptionsMenuLocation" text="Location" />
<MenuItem mnemonicParsing="false" onAction="#onSessionOptionsMenu" text="Options" /> <MenuItem mnemonicParsing="false" onAction="#onSessionOptionsMenu" text="Options" />
</items> </items>
</Menu>
<Menu mnemonicParsing="false" text="Options">
<items>
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuNodeTypes" text="Nodes" />
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuBackground" text="Background" />
<MenuItem mnemonicParsing="false" onAction="#onOptionsMenuPreferences" text="Preferences" />
</items>
</Menu> </Menu>
<Menu mnemonicParsing="false" text="Help"> <Menu mnemonicParsing="false" text="Help">
<items> <items>

View file

@ -11,7 +11,7 @@
<?import javafx.scene.layout.RowConstraints?> <?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<GridPane hgap="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" vgap="10.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.171"> <GridPane hgap="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" vgap="10.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="33.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="33.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
@ -66,6 +66,8 @@
<JFXButton fx:id="iconButton" maxWidth="1.7976931348623157E308" styleClass="core-button" text="Find" GridPane.columnIndex="1" /> <JFXButton fx:id="iconButton" maxWidth="1.7976931348623157E308" styleClass="core-button" text="Find" GridPane.columnIndex="1" />
</children> </children>
</GridPane> </GridPane>
<Label text="Services" />
<JFXListView fx:id="nodeServicesListView" VBox.vgrow="ALWAYS" />
</children> </children>
<GridPane.margin> <GridPane.margin>
<Insets /> <Insets />