From 22de37df374080badd901f648c3eb1801dc87190 Mon Sep 17 00:00:00 2001 From: Jason Dahlke Date: Wed, 28 Aug 2024 19:27:23 +0000 Subject: [PATCH 1/3] update command validation for mode values --- clipboard | 44 +++++++++++++++++++ .../java/emissary/command/ServerCommand.java | 10 ++--- .../validator/ServerModeValidator.java | 4 +- 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 clipboard diff --git a/clipboard b/clipboard new file mode 100644 index 0000000000..621e8a1119 --- /dev/null +++ b/clipboard @@ -0,0 +1,44 @@ +]$ ./emissary server -m junk -q +18:56:19.596 [main] ERROR emissary.command.validator.ServerModeValidator -- Unknown mode: junk +Command threw an exception: [server, -m, junk] +picocli.CommandLine$ParameterException: Could not invoke private void emissary.command.ServerCommand.setMode(java.lang.String) with junk (java.lang.IllegalArgumentException: Unknown mode: junk) + at picocli.CommandLine$Model$MethodBinding.createParameterException(CommandLine.java:12154) + at picocli.CommandLine$Model$MethodBinding.set(CommandLine.java:12147) + at picocli.CommandLine$Model$ArgSpec.setValue(CommandLine.java:9211) + at picocli.CommandLine$Interpreter.applyValueToSingleValuedField(CommandLine.java:14298) + at picocli.CommandLine$Interpreter.applyOption(CommandLine.java:14143) + at picocli.CommandLine$Interpreter.processStandaloneOption(CommandLine.java:14009) + at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:13829) + at picocli.CommandLine$Interpreter.parse(CommandLine.java:13564) + at picocli.CommandLine$Interpreter.processSubcommand(CommandLine.java:13873) + at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:13769) + at picocli.CommandLine$Interpreter.parse(CommandLine.java:13564) + at picocli.CommandLine$Interpreter.parse(CommandLine.java:13532) + at picocli.CommandLine$Interpreter.parse(CommandLine.java:13427) + at picocli.CommandLine.parseArgs(CommandLine.java:1552) + at emissary.Emissary.execute(Emissary.java:99) + at emissary.Emissary.main(Emissary.java:164) +Caused by: java.lang.IllegalArgumentException: Unknown mode: junk + at emissary.command.validator.ServerModeValidator.validate(ServerModeValidator.java:17) + at emissary.command.ServerCommand.setMode(ServerCommand.java:35) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:566) + at picocli.CommandLine$Model$MethodBinding.set(CommandLine.java:12142) + ... 14 common frames omitted + + +]$ ./emissary server -m junk -q +Emissary Version: 8.10.0-SNAPSHOT - built on 2024-08-28T19:14:53+0000 - git hash: 8c963e1 +2024-08-28T19:19:39.807 [localhost-8001] ERROR emissary.command.validator.ServerModeValidator - - Unknown mode: junk +2024-08-28T19:19:39.809 [localhost-8001] ERROR emissary.Emissary - - Command threw an exception: [server, -m, junk, -q] +java.lang.IllegalArgumentException: Unknown mode: junk + at emissary.command.validator.ServerModeValidator.validate(ServerModeValidator.java:17) + at emissary.command.ServerCommand.setupServer(ServerCommand.java:110) + at emissary.command.ServerCommand.setupCommand(ServerCommand.java:85) + at emissary.command.EmissaryCommand.setup(EmissaryCommand.java:14) + at emissary.command.ServiceCommand.run(ServiceCommand.java:93) + at emissary.Emissary.execute(Emissary.java:113) + at emissary.Emissary.main(Emissary.java:164) + diff --git a/src/main/java/emissary/command/ServerCommand.java b/src/main/java/emissary/command/ServerCommand.java index d2aa1fb83b..8762a82a61 100644 --- a/src/main/java/emissary/command/ServerCommand.java +++ b/src/main/java/emissary/command/ServerCommand.java @@ -27,14 +27,8 @@ public class ServerCommand extends ServiceCommand { public static final int DEFAULT_PORT = 8001; - private String mode = "standalone"; - @Option(names = {"-m", "--mode"}, description = "mode: standalone or cluster\nDefault: ${DEFAULT-VALUE}", defaultValue = "standalone") - private void setMode(String value) { - ServerModeValidator smv = new ServerModeValidator(); - smv.validate("mode", value); - mode = value; - } + private String mode = "standalone"; @Option(names = "--staticDir", description = "path to static assets, loaded from classpath otherwise", converter = ProjectBaseConverter.class) private Path staticDir; @@ -113,6 +107,8 @@ public void setupServer() throws EmissaryException { flavorSet.add(f.toUpperCase()); } + ServerModeValidator.validate(getMode()); + if (flavorSet.contains("STANDALONE") && flavorSet.contains("CLUSTER")) { throw new IllegalArgumentException("Can not run a server in both STANDALONE and CLUSTER"); } else { diff --git a/src/main/java/emissary/command/validator/ServerModeValidator.java b/src/main/java/emissary/command/validator/ServerModeValidator.java index 5642ea004c..2e05607c58 100644 --- a/src/main/java/emissary/command/validator/ServerModeValidator.java +++ b/src/main/java/emissary/command/validator/ServerModeValidator.java @@ -7,7 +7,7 @@ public class ServerModeValidator { private static final Logger LOG = LoggerFactory.getLogger(ServerModeValidator.class); - public void validate(String name, String value) { + public static void validate(String value) { switch (value) { case "cluster": case "standalone": @@ -18,4 +18,6 @@ public void validate(String name, String value) { } } + /** This class is not meant to be instantiated. */ + private ServerModeValidator() {} } From 27320995aef3fa578768a546f82e26d0fdd4e742 Mon Sep 17 00:00:00 2001 From: Jason Dahlke Date: Wed, 28 Aug 2024 22:41:35 +0000 Subject: [PATCH 2/3] change to use enum --- clipboard | 44 ------------------- .../java/emissary/command/ServerCommand.java | 26 +++++------ .../converter/ServerModeConverter.java | 20 +++++++++ .../validator/ServerModeValidator.java | 23 ---------- .../command/validator/package-info.java | 4 -- .../java/emissary/directory/EmissaryNode.java | 27 +++++++----- .../java/emissary/server/EmissaryServer.java | 6 +-- 7 files changed, 46 insertions(+), 104 deletions(-) delete mode 100644 clipboard create mode 100644 src/main/java/emissary/command/converter/ServerModeConverter.java delete mode 100644 src/main/java/emissary/command/validator/ServerModeValidator.java delete mode 100644 src/main/java/emissary/command/validator/package-info.java diff --git a/clipboard b/clipboard deleted file mode 100644 index 621e8a1119..0000000000 --- a/clipboard +++ /dev/null @@ -1,44 +0,0 @@ -]$ ./emissary server -m junk -q -18:56:19.596 [main] ERROR emissary.command.validator.ServerModeValidator -- Unknown mode: junk -Command threw an exception: [server, -m, junk] -picocli.CommandLine$ParameterException: Could not invoke private void emissary.command.ServerCommand.setMode(java.lang.String) with junk (java.lang.IllegalArgumentException: Unknown mode: junk) - at picocli.CommandLine$Model$MethodBinding.createParameterException(CommandLine.java:12154) - at picocli.CommandLine$Model$MethodBinding.set(CommandLine.java:12147) - at picocli.CommandLine$Model$ArgSpec.setValue(CommandLine.java:9211) - at picocli.CommandLine$Interpreter.applyValueToSingleValuedField(CommandLine.java:14298) - at picocli.CommandLine$Interpreter.applyOption(CommandLine.java:14143) - at picocli.CommandLine$Interpreter.processStandaloneOption(CommandLine.java:14009) - at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:13829) - at picocli.CommandLine$Interpreter.parse(CommandLine.java:13564) - at picocli.CommandLine$Interpreter.processSubcommand(CommandLine.java:13873) - at picocli.CommandLine$Interpreter.processArguments(CommandLine.java:13769) - at picocli.CommandLine$Interpreter.parse(CommandLine.java:13564) - at picocli.CommandLine$Interpreter.parse(CommandLine.java:13532) - at picocli.CommandLine$Interpreter.parse(CommandLine.java:13427) - at picocli.CommandLine.parseArgs(CommandLine.java:1552) - at emissary.Emissary.execute(Emissary.java:99) - at emissary.Emissary.main(Emissary.java:164) -Caused by: java.lang.IllegalArgumentException: Unknown mode: junk - at emissary.command.validator.ServerModeValidator.validate(ServerModeValidator.java:17) - at emissary.command.ServerCommand.setMode(ServerCommand.java:35) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:566) - at picocli.CommandLine$Model$MethodBinding.set(CommandLine.java:12142) - ... 14 common frames omitted - - -]$ ./emissary server -m junk -q -Emissary Version: 8.10.0-SNAPSHOT - built on 2024-08-28T19:14:53+0000 - git hash: 8c963e1 -2024-08-28T19:19:39.807 [localhost-8001] ERROR emissary.command.validator.ServerModeValidator - - Unknown mode: junk -2024-08-28T19:19:39.809 [localhost-8001] ERROR emissary.Emissary - - Command threw an exception: [server, -m, junk, -q] -java.lang.IllegalArgumentException: Unknown mode: junk - at emissary.command.validator.ServerModeValidator.validate(ServerModeValidator.java:17) - at emissary.command.ServerCommand.setupServer(ServerCommand.java:110) - at emissary.command.ServerCommand.setupCommand(ServerCommand.java:85) - at emissary.command.EmissaryCommand.setup(EmissaryCommand.java:14) - at emissary.command.ServiceCommand.run(ServiceCommand.java:93) - at emissary.Emissary.execute(Emissary.java:113) - at emissary.Emissary.main(Emissary.java:164) - diff --git a/src/main/java/emissary/command/ServerCommand.java b/src/main/java/emissary/command/ServerCommand.java index 8762a82a61..ca06e31b0c 100644 --- a/src/main/java/emissary/command/ServerCommand.java +++ b/src/main/java/emissary/command/ServerCommand.java @@ -2,9 +2,9 @@ import emissary.client.EmissaryResponse; import emissary.command.converter.ProjectBaseConverter; -import emissary.command.validator.ServerModeValidator; +import emissary.command.converter.ServerModeConverter; import emissary.core.EmissaryException; -import emissary.core.EmissaryRuntimeException; +import emissary.directory.EmissaryNode; import emissary.server.EmissaryServer; import emissary.server.api.Pause; @@ -27,8 +27,9 @@ public class ServerCommand extends ServiceCommand { public static final int DEFAULT_PORT = 8001; - @Option(names = {"-m", "--mode"}, description = "mode: standalone or cluster\nDefault: ${DEFAULT-VALUE}", defaultValue = "standalone") - private String mode = "standalone"; + @Option(names = {"-m", "--mode"}, description = "mode: standalone or cluster\nDefault: ${DEFAULT-VALUE}", converter = ServerModeConverter.class, + defaultValue = "standalone") + private EmissaryNode.EmissaryMode mode; @Option(names = "--staticDir", description = "path to static assets, loaded from classpath otherwise", converter = ProjectBaseConverter.class) private Path staticDir; @@ -52,7 +53,7 @@ public int getDefaultPort() { return DEFAULT_PORT; } - public String getMode() { + public EmissaryNode.EmissaryMode getMode() { return mode; } @@ -81,20 +82,15 @@ public boolean shouldStrictMode() { public void setupCommand() { setupHttp(); reinitLogback(); - try { - setupServer(); - } catch (EmissaryException e) { - LOG.error("Got an exception", e); - throw new EmissaryRuntimeException(e); - } + setupServer(); } - public void setupServer() throws EmissaryException { + public void setupServer() { String flavorMode; if (getFlavor() == null) { - flavorMode = getMode().toUpperCase(); + flavorMode = getMode().toString(); } else { - flavorMode = getMode().toUpperCase() + "," + getFlavor(); + flavorMode = getMode().toString() + "," + getFlavor(); } if (shouldStrictMode()) { @@ -107,8 +103,6 @@ public void setupServer() throws EmissaryException { flavorSet.add(f.toUpperCase()); } - ServerModeValidator.validate(getMode()); - if (flavorSet.contains("STANDALONE") && flavorSet.contains("CLUSTER")) { throw new IllegalArgumentException("Can not run a server in both STANDALONE and CLUSTER"); } else { diff --git a/src/main/java/emissary/command/converter/ServerModeConverter.java b/src/main/java/emissary/command/converter/ServerModeConverter.java new file mode 100644 index 0000000000..76245c510f --- /dev/null +++ b/src/main/java/emissary/command/converter/ServerModeConverter.java @@ -0,0 +1,20 @@ +package emissary.command.converter; + +import emissary.directory.EmissaryNode; + +import picocli.CommandLine.ITypeConverter; + +public class ServerModeConverter implements ITypeConverter { + + @Override + public EmissaryNode.EmissaryMode convert(String s) throws Exception { + switch (s.toLowerCase()) { + case "cluster": + return EmissaryNode.EmissaryMode.CLUSTER; + case "standalone": + return EmissaryNode.EmissaryMode.STANDALONE; + default: + throw new IllegalArgumentException("Unknown mode: " + s); + } + } +} diff --git a/src/main/java/emissary/command/validator/ServerModeValidator.java b/src/main/java/emissary/command/validator/ServerModeValidator.java deleted file mode 100644 index 2e05607c58..0000000000 --- a/src/main/java/emissary/command/validator/ServerModeValidator.java +++ /dev/null @@ -1,23 +0,0 @@ -package emissary.command.validator; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ServerModeValidator { - - private static final Logger LOG = LoggerFactory.getLogger(ServerModeValidator.class); - - public static void validate(String value) { - switch (value) { - case "cluster": - case "standalone": - break; - default: - LOG.error("Unknown mode: {}", value); - throw new IllegalArgumentException("Unknown mode: " + value); - } - } - - /** This class is not meant to be instantiated. */ - private ServerModeValidator() {} -} diff --git a/src/main/java/emissary/command/validator/package-info.java b/src/main/java/emissary/command/validator/package-info.java deleted file mode 100644 index 4e89fb2a6d..0000000000 --- a/src/main/java/emissary/command/validator/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides classes to validate parameters {@link emissary.command.EmissaryCommand}s. - */ -package emissary.command.validator; diff --git a/src/main/java/emissary/directory/EmissaryNode.java b/src/main/java/emissary/directory/EmissaryNode.java index 1e487d2ac7..1ae8c62d4d 100644 --- a/src/main/java/emissary/directory/EmissaryNode.java +++ b/src/main/java/emissary/directory/EmissaryNode.java @@ -63,9 +63,9 @@ public class EmissaryNode { /** Property that determines if server will shut down in the event a place fails to start */ public static final String STRICT_STARTUP_MODE = "strict.mode"; - // types are feeder, worker, standalone - // TODO: make an enum for these - private static final String DEFAULT_NODE_MODE = "standalone"; + public enum EmissaryMode { + STANDALONE, CLUSTER; + } @Nullable protected String nodeName = null; @@ -75,19 +75,23 @@ public class EmissaryNode { // this is the OS for all practical purposes @Nullable protected String nodeType = null; - @Nullable - protected String nodeMode = null; // probably better as nodeType, but that requires a refactor + protected EmissaryMode nodeMode; protected boolean nodeNameIsDefault = false; @Nullable protected String nodeServiceType = null; protected boolean strictStartupMode = false; + public EmissaryNode() { + this(EmissaryMode.STANDALONE); + } + /** * Construct the node. The node name and port are from system properties. The node type is based on the os.name in this * implementation */ - public EmissaryNode() { + public EmissaryNode(EmissaryMode nodeMode) { + this.nodeMode = nodeMode; this.nodeName = System.getProperty(NODE_NAME_PROPERTY); if (this.nodeName == null) { // Use IP Address for default node name since it is @@ -103,11 +107,14 @@ public EmissaryNode() { this.nodeScheme = System.getProperty(NODE_SCHEME_PROPERTY, "http"); this.nodePort = Integer.getInteger(NODE_PORT_PROPERTY, -1).intValue(); this.nodeType = System.getProperty("os.name", DEFAULT_NODE_TYPE).toLowerCase().replace(' ', '_'); - this.nodeMode = System.getProperty("node.mode", DEFAULT_NODE_MODE).toLowerCase(); this.nodeServiceType = System.getProperty(NODE_SERVICE_TYPE_PROPERTY, DEFAULT_NODE_SERVICE_TYPE); this.strictStartupMode = Boolean.parseBoolean(System.getProperty(STRICT_STARTUP_MODE, String.valueOf(false))); } + public EmissaryMode getNodeMode() { + return nodeMode; + } + /** * The node name */ @@ -168,11 +175,7 @@ public boolean isValidStandalone() { * True if this node appears to be a stand-alone (non P2P) node */ public boolean isStandalone() { - return isValidStandalone() && getNodeMode().equals("standalone"); - } - - private Object getNodeMode() { - return nodeMode; + return isValidStandalone() && getNodeMode().equals(EmissaryMode.STANDALONE); } public boolean isStrictStartupMode() { diff --git a/src/main/java/emissary/server/EmissaryServer.java b/src/main/java/emissary/server/EmissaryServer.java index 9253962d90..f30efe0513 100644 --- a/src/main/java/emissary/server/EmissaryServer.java +++ b/src/main/java/emissary/server/EmissaryServer.java @@ -93,16 +93,12 @@ public class EmissaryServer { private final EmissaryNode emissaryNode; public EmissaryServer(ServerCommand cmd) throws EmissaryException { - this(cmd, new EmissaryNode()); + this(cmd, new EmissaryNode(cmd.getMode())); } @VisibleForTesting public EmissaryServer(ServerCommand cmd, EmissaryNode node) throws EmissaryException { this.cmd = cmd; - // See if we are an emissary node, but first setup node type - if (cmd.getMode() != null) { - System.setProperty("node.mode", cmd.getMode()); // TODO: clean this crap up - } emissaryNode = node; if (!emissaryNode.isValid()) { From 475b7c79879cee6a8f36c1964359d71ed3d7ad67 Mon Sep 17 00:00:00 2001 From: Jason Dahlke Date: Sat, 31 Aug 2024 02:59:53 +0000 Subject: [PATCH 3/3] work to make EmissaryServer no longer require namespace binding --- src/main/java/emissary/admin/Startup.java | 3 +- .../java/emissary/command/ServerCommand.java | 13 ++- .../java/emissary/directory/EmissaryNode.java | 4 +- src/main/java/emissary/pickup/WorkSpace.java | 17 ++-- .../emissary/place/ServiceProviderPlace.java | 6 +- .../java/emissary/server/EmissaryServer.java | 88 ++++++++++++------- .../emissary/server/EmissaryServerIT.java | 6 +- .../java/emissary/server/api/PeersIT.java | 41 +++------ .../test/core/junit5/FunctionalTest.java | 4 +- .../emissary/test/core/junit5/UnitTest.java | 5 +- 10 files changed, 98 insertions(+), 89 deletions(-) diff --git a/src/main/java/emissary/admin/Startup.java b/src/main/java/emissary/admin/Startup.java index f25a87a58a..1df7104935 100755 --- a/src/main/java/emissary/admin/Startup.java +++ b/src/main/java/emissary/admin/Startup.java @@ -14,6 +14,7 @@ import emissary.pickup.PickUpPlace; import emissary.place.CoordinationPlace; import emissary.place.IServiceProviderPlace; +import emissary.server.EmissaryServer; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -287,7 +288,7 @@ protected boolean localDirectorySetup(final Map localDirectories final long start = System.currentTimeMillis(); final Map dirStarts = new HashMap<>(); - EmissaryNode emissaryNode = new EmissaryNode(); + EmissaryNode emissaryNode = EmissaryServer.getInstance().getNode(); for (final String thePlaceLocation : hostParameters) { final String host = placeHost(thePlaceLocation); diff --git a/src/main/java/emissary/command/ServerCommand.java b/src/main/java/emissary/command/ServerCommand.java index ca06e31b0c..bd8ef1a925 100644 --- a/src/main/java/emissary/command/ServerCommand.java +++ b/src/main/java/emissary/command/ServerCommand.java @@ -3,7 +3,6 @@ import emissary.client.EmissaryResponse; import emissary.command.converter.ProjectBaseConverter; import emissary.command.converter.ServerModeConverter; -import emissary.core.EmissaryException; import emissary.directory.EmissaryNode; import emissary.server.EmissaryServer; import emissary.server.api.Pause; @@ -112,12 +111,12 @@ public void setupServer() { @Override protected void startService() { - try { - LOG.info("Running Emissary Server"); - new EmissaryServer(this).startServer(); - } catch (EmissaryException e) { - LOG.error("Unable to start server", e); - } + // try { + LOG.info("Running Emissary Server"); + EmissaryServer.init(this).startServer(); + // } catch (EmissaryException e) { + // LOG.error("Unable to start server", e); + // } } @Override diff --git a/src/main/java/emissary/directory/EmissaryNode.java b/src/main/java/emissary/directory/EmissaryNode.java index 1ae8c62d4d..6f4fbaa433 100644 --- a/src/main/java/emissary/directory/EmissaryNode.java +++ b/src/main/java/emissary/directory/EmissaryNode.java @@ -200,14 +200,14 @@ public Configurator getNodeConfigurator() throws IOException { } /** - * Get the peer configuration stream for this noed + * Get the peer configuration stream for this node */ public Configurator getPeerConfigurator() throws IOException { if (isStandalone()) { // return a configurator here with just standalone, don't actually read the peer.cfg // This is a hack until we can TODO: refactor all this so standalone doesn't need peers // maybe even warn if there is a peer.cfg - logger.debug("Node is standalone, ignoring any peer.cfg and only constructing one rendevous peer with the local node"); + logger.debug("Node is standalone, ignoring any peer.cfg and only constructing one rendezvous peer with the local node"); Configurator cfg = new ServiceConfigGuide(); cfg.addEntry("RENDEZVOUS_PEER", this.asUrlKey()); return cfg; diff --git a/src/main/java/emissary/pickup/WorkSpace.java b/src/main/java/emissary/pickup/WorkSpace.java index 13459a0afe..6108f6686b 100755 --- a/src/main/java/emissary/pickup/WorkSpace.java +++ b/src/main/java/emissary/pickup/WorkSpace.java @@ -193,13 +193,13 @@ public WorkSpace(FeedCommand feedCommand) { this.outbound = new PriorityQueue<>(11, this.feedCommand.getSort()); } - configure(); startJetty(); + register(); initializeService(); } protected void startJetty() { - if (!EmissaryServer.isStarted()) { + if (!EmissaryServer.isInitialized() || !EmissaryServer.getInstance().isServerRunning()) { // TODO investigate passing the feedCommand object directly to the serverCommand List args = new ArrayList<>(); args.add("-b"); @@ -224,7 +224,7 @@ protected void startJetty() { try { // To ensure the feed command starts correctly, depends on a node-{feedCommand.getPort}.cfg file ServerCommand cmd = BaseCommand.parse(ServerCommand.class, args); - Server server = new EmissaryServer(cmd).startServer(); + Server server = EmissaryServer.init(cmd).startServer(); final boolean jettyStatus = server.isStarted(); if (!jettyStatus) { logger.error("Cannot start the Workspace due to EmissaryServer not starting!"); @@ -293,13 +293,10 @@ public void stop() { public void shutDown() { stop(); if (this.jettyStartedHere) { - final EmissaryNode node = new EmissaryNode(); + final EmissaryNode node = EmissaryServer.getInstance().getNode(); if (node.isValid()) { try { - final EmissaryServer s = EmissaryServer.lookup(); - s.getServer().stop(); - } catch (NamespaceException ex) { - logger.error("Cannot find jetty server", ex); + EmissaryServer.getInstance().stop(); } catch (Exception ex) { logger.error("Jetty cannot be shutdown", ex); } @@ -523,8 +520,8 @@ public void setPattern(@Nullable final String thePattern) throws Exception { /** * Configure the Processor. The *.cfg file is optional */ - protected void configure() { - final EmissaryNode node = new EmissaryNode(); + protected void register() { + final EmissaryNode node = EmissaryServer.getInstance().getNode(); if (node.isValid()) { this.workSpaceUrl = node.getNodeScheme() + "://" + node.getNodeName() + ":" + node.getNodePort() + "/" + this.WORK_SPACE_NAME; } else { diff --git a/src/main/java/emissary/place/ServiceProviderPlace.java b/src/main/java/emissary/place/ServiceProviderPlace.java index 59ac8f5693..a0be484a1d 100755 --- a/src/main/java/emissary/place/ServiceProviderPlace.java +++ b/src/main/java/emissary/place/ServiceProviderPlace.java @@ -332,14 +332,14 @@ protected void setupPlace(@Nullable String theDir, String placeLocation) throws * @return true if it worked */ private boolean localizeDirectory(@Nullable String theDir) { - // Get a local (non proxy) copy of the directory if possible! + // Get a local (non-proxy) copy of the directory if possible! // Looking up both if nothing is provided if (theDir == null) { try { localDirPlace = DirectoryPlace.lookup(); dirPlace = localDirPlace.toString(); } catch (EmissaryException ex) { - if (EmissaryServer.exists() && !(this instanceof DirectoryPlace)) { + if (EmissaryServer.getInstance().isServerRunning() && !(this instanceof DirectoryPlace)) { logger.warn("Unable to find DirectoryPlace in local namespace", ex); return false; } @@ -422,7 +422,7 @@ protected void configureServicePlace(@Nullable String placeLocation) throws IOEx keys.add(placeLocation); // save as first in list locationPart = KeyManipulator.getServiceLocation(placeLocation); } else if (!placeLocation.contains("://")) { - EmissaryNode node = new EmissaryNode(); + EmissaryNode node = EmissaryServer.getInstance().getNode(); locationPart = "http://" + node.getNodeName() + ":" + node.getNodePort() + "/" + placeLocation; } diff --git a/src/main/java/emissary/server/EmissaryServer.java b/src/main/java/emissary/server/EmissaryServer.java index f30efe0513..968a5631c3 100644 --- a/src/main/java/emissary/server/EmissaryServer.java +++ b/src/main/java/emissary/server/EmissaryServer.java @@ -92,20 +92,39 @@ public class EmissaryServer { private final EmissaryNode emissaryNode; - public EmissaryServer(ServerCommand cmd) throws EmissaryException { - this(cmd, new EmissaryNode(cmd.getMode())); + private static EmissaryServer emissaryServer; + + private EmissaryServer(ServerCommand cmd) { + this.cmd = cmd; + this.emissaryNode = new EmissaryNode(cmd.getMode()); } - @VisibleForTesting - public EmissaryServer(ServerCommand cmd, EmissaryNode node) throws EmissaryException { + // there should be a better way to set a custom peer.cfg than this + private EmissaryServer(ServerCommand cmd, EmissaryNode node) { this.cmd = cmd; - emissaryNode = node; + this.emissaryNode = node; + } + + public static EmissaryServer init(ServerCommand cmd) { + emissaryServer = new EmissaryServer(cmd); + return emissaryServer; + } + + // there should be a better way to set a custom peer.cfg than this + public static EmissaryServer init(ServerCommand cmd, EmissaryNode node) { + emissaryServer = new EmissaryServer(cmd, node); + return emissaryServer; + } + + public static boolean isInitialized() { + return emissaryServer != null; + } - if (!emissaryNode.isValid()) { - LOG.error("Not an emissary node, no emissary services required."); - LOG.error("Try setting -D{}=value to configure an emissary node", EmissaryNode.NODE_NAME_PROPERTY); - throw new EmissaryException("Not an emissary node, no emissary services required"); + public static EmissaryServer getInstance() { + if (emissaryServer == null) { + throw new AssertionError("EmissaryServer has not yet been instantiated!"); } + return emissaryServer; } public EmissaryNode getNode() { @@ -259,38 +278,30 @@ public static void unpause(boolean silent) throws NamespaceException { } /** - * Stop the server running under the default name + * Stop the server */ public static void stopServer() { stopServer(false); } - /** - * Stop the server running under the default name - * - * @param quiet be quiet about failures if true - */ - public static void stopServer(final boolean quiet) { - stopServer(false, quiet); - } - /** * Stop the server running under the default name * * @param force force shutdown * @param quiet be quiet about failures if true */ + @Deprecated(forRemoval = true) public static void stopServer(final boolean force, final boolean quiet) { stopServer(getDefaultNamespaceName(), force, quiet); } - /** * Stop the server if it is running and remove it from the namespace * * @param name the namespace name of the server * @param quiet be quiet about failures if true */ + @Deprecated(forRemoval = true) public static void stopServer(final String name, final boolean quiet) { stopServer(name, false, quiet); } @@ -302,10 +313,20 @@ public static void stopServer(final String name, final boolean quiet) { * @param force force shutdown * @param quiet be quiet about failures if true */ + @Deprecated(forRemoval = true) public static void stopServer(final String name, final boolean force, final boolean quiet) { + stopServer(force); + } + + /** + * Stop the server with an optional force flag + * + * @param force force shutdown + */ + public static void stopServer(final boolean force) { // TODO pull these out to methods and test them - LOG.info("Beginning shutdown of EmissaryServer {}", name); + LOG.info("Beginning shutdown of EmissaryServer"); logThreadDump("Thread dump before anything"); try { @@ -388,21 +409,18 @@ public static void stopServer(final String name, final boolean force, final bool logThreadDump("Thread dump before stopping jetty server"); try { - EmissaryServer s = EmissaryServer.lookup(name); - s.getServer().stop(); - } catch (NamespaceException e) { - LOG.error("Unable to lookup {} ", name, e); + EmissaryServer.getInstance().getServer().stop(); } catch (InterruptedException e) { LOG.warn("Interrupted! Expected?"); Thread.currentThread().interrupt(); } catch (Exception e) { - LOG.warn("Unable to stop server {} ", name, e); + LOG.warn("Unable to stop EmissaryServer", e); } - LOG.debug("Unbinding name: {}", name); - Namespace.unbind(name); + LOG.debug("Unbinding name: {}", getDefaultNamespaceName()); + Namespace.unbind(getDefaultNamespaceName()); Namespace.clear(); - LOG.info("Emissary named {} completely stopped.", name); + LOG.info("EmissaryServer completely stopped"); } /** @@ -465,7 +483,7 @@ public Server getServer() { return this.server; } - + @Deprecated(forRemoval = true) public synchronized String getNamespaceName() { if (this.nameSpaceName == null) { this.nameSpaceName = getDefaultNamespaceName(); @@ -473,6 +491,7 @@ public synchronized String getNamespaceName() { return this.nameSpaceName; } + @Deprecated(forRemoval = true) public static String getDefaultNamespaceName() { return DEFAULT_NAMESPACE_NAME; } @@ -481,7 +500,9 @@ public static String getDefaultNamespaceName() { * Check if server is running * * @return true if it is in the namespace and is started + * @deprecated use {@link #isServerRunning()} */ + @Deprecated(forRemoval = true) public static boolean isStarted() { return isStarted(getDefaultNamespaceName()); } @@ -492,6 +513,7 @@ public static boolean isStarted() { * @param name the namespace name to use as a key * @return true if it is in the namespace and is started */ + @Deprecated(forRemoval = true) public static boolean isStarted(final String name) { boolean started = false; try { @@ -507,6 +529,7 @@ public static boolean isStarted(final String name) { return started; } + @Deprecated(forRemoval = true) public static boolean exists() { try { EmissaryServer.lookup(); @@ -517,13 +540,15 @@ public static boolean exists() { return false; } + @Deprecated(forRemoval = true) public static EmissaryServer lookup() throws NamespaceException { return lookup(getDefaultNamespaceName()); } /** - * Retreive instance from namespace using default name + * Retrieve instance from namespace using default name */ + @Deprecated(forRemoval = true) public static EmissaryServer lookup(final String name) throws NamespaceException { return (EmissaryServer) Namespace.lookup(name); } @@ -567,7 +592,6 @@ private void bindServer() throws AttributeInUseException { LOG.debug("Binding {} ", DEFAULT_NAMESPACE_NAME); Namespace.bind(getDefaultNamespaceName(), this); - } private ContextHandler buildStaticHandler() { diff --git a/src/test/java/emissary/server/EmissaryServerIT.java b/src/test/java/emissary/server/EmissaryServerIT.java index dd262379c1..d137bc97ea 100644 --- a/src/test/java/emissary/server/EmissaryServerIT.java +++ b/src/test/java/emissary/server/EmissaryServerIT.java @@ -25,7 +25,7 @@ class EmissaryServerIT extends UnitTest { @Test void testThreadPoolStuff() throws Exception { ServerCommand cmd = ServerCommand.parse(ServerCommand.class, "-h", "host1", "-p", "3001"); - EmissaryServer server = new EmissaryServer(cmd); + EmissaryServer server = EmissaryServer.init(cmd); Server jettyServer = server.configureServer(); QueuedThreadPool pool = (QueuedThreadPool) jettyServer.getThreadPool(); assertEquals(10, pool.getMinThreads()); @@ -38,7 +38,7 @@ void testThreadPoolStuff() throws Exception { @Test void testSSLWorks() throws Exception { ServerCommand cmd = ServerCommand.parse(ServerCommand.class, "-p", "3443", "--ssl", "--disableSniHostCheck"); - EmissaryServer server = new EmissaryServer(cmd); + EmissaryServer server = EmissaryServer.init(cmd); try { server.startServer(); EmissaryClient client = new EmissaryClient(); @@ -56,7 +56,7 @@ void testSSLWorks() throws Exception { @Test void testInvisPlacesOnStrictStartUp() throws EmissaryException { ServerCommand cmd = ServerCommand.parse(ServerCommand.class, "--strict"); - EmissaryServer server = new EmissaryServer(cmd); + EmissaryServer server = EmissaryServer.init(cmd); EmissaryNode node = new EmissaryNode(); String location = "http://" + node.getNodeName() + ":" + node.getNodePort(); Startup.getInvisPlaces().add(location + "/PlaceStartUnannouncedTest"); diff --git a/src/test/java/emissary/server/api/PeersIT.java b/src/test/java/emissary/server/api/PeersIT.java index 1217e0ae3d..6088ecf663 100644 --- a/src/test/java/emissary/server/api/PeersIT.java +++ b/src/test/java/emissary/server/api/PeersIT.java @@ -30,7 +30,10 @@ class PeersIT extends EndpointTestBase { - public static final String DIRNAME = "http://" + TestEmissaryNode.TEST_NODE_PORT + "/DirectoryPlace"; + public static final int TEST_PORT = 123456; + public static final String TEST_NODE = "localhost"; + public static final String TEST_NODE_PORT = TEST_NODE + ":" + TEST_PORT; + public static final String DIRNAME = "http://" + TEST_NODE_PORT + "/DirectoryPlace"; public static final String SELF = "*.*.*.http://localhost:9999/DirectoryPlace"; public static final String PEER1 = "*.*.*.http://remoteHost:8888/DirectoryPlace"; public static final String PEER2 = "*.*.*.http://remoteHost2:8888/DirectoryPlace"; @@ -38,16 +41,15 @@ class PeersIT extends EndpointTestBase { @BeforeEach public void setup() throws Exception { - EmissaryNode emissaryNode = new TestEmissaryNode(); - DirectoryPlace directoryPlace = new DirectoryPlace(DIRNAME, emissaryNode); - directoryPlace.addPeerDirectories(PEERS, false); - Namespace.bind(DIRNAME, directoryPlace); - String projectBase = System.getenv(ConfigUtil.PROJECT_BASE_ENV); - ServerCommand cmd = ServerCommand.parse(ServerCommand.class, "-b ", projectBase, "-m", "cluster"); + ServerCommand cmd = ServerCommand.parse(ServerCommand.class, "-b ", projectBase, "-m", "cluster", "-p", "123456"); cmd.setupServer(); - EmissaryServer server = new EmissaryServer(cmd, emissaryNode); + EmissaryServer server = EmissaryServer.init(cmd, new TestEmissaryNode(EmissaryNode.EmissaryMode.CLUSTER)); Namespace.bind("EmissaryServer", server); + + DirectoryPlace directoryPlace = new DirectoryPlace(DIRNAME, server.getNode()); + directoryPlace.addPeerDirectories(PEERS, false); + Namespace.bind(DIRNAME, directoryPlace); } @AfterEach @@ -66,7 +68,7 @@ void peers() { PeersResponseEntity entity = response.readEntity(PeersResponseEntity.class); assertEquals(0, entity.getErrors().size()); assertTrue(CollectionUtils.isEmpty(entity.getCluster())); - assertEquals(TestEmissaryNode.TEST_NODE_PORT, entity.getLocal().getHost()); + assertEquals(TEST_NODE_PORT, entity.getLocal().getHost()); assertTrue(entity.getLocal().getPeers().containsAll(PEERS)); } @@ -105,29 +107,12 @@ void peersNoDirectoryPlace() throws NamespaceException { } static class TestEmissaryNode extends EmissaryNode { - public static final int TEST_PORT = 123456; - public static final String TEST_NODE = "localhost"; - public static final String TEST_NODE_PORT = TEST_NODE + ":" + TEST_PORT; - public TestEmissaryNode() { + public TestEmissaryNode(EmissaryNode.EmissaryMode mode) { + super(mode); nodeNameIsDefault = true; } - @Override - public int getNodePort() { - return TEST_PORT; - } - - @Override - public String getNodeName() { - return TEST_NODE; - } - - @Override - public boolean isStandalone() { - return false; - } - @Override public Configurator getPeerConfigurator() throws IOException { // just go get this from the src/test/resources directory diff --git a/src/test/java/emissary/test/core/junit5/FunctionalTest.java b/src/test/java/emissary/test/core/junit5/FunctionalTest.java index 0257f336bd..958c9b2bad 100644 --- a/src/test/java/emissary/test/core/junit5/FunctionalTest.java +++ b/src/test/java/emissary/test/core/junit5/FunctionalTest.java @@ -83,7 +83,7 @@ protected void startJetty(int port) throws Exception { try { ServerCommand cmd = ServerCommand.parse(ServerCommand.class, args); - jserver = new EmissaryServer(cmd); + jserver = EmissaryServer.init(cmd); jetty = jserver.startServer(); } catch (Exception ignored) { // Ignore @@ -160,7 +160,7 @@ protected void demolishServer() { if (jserver != null && jserver.isServerRunning()) { jserver.stop(); jetty = null; - assertFalse(EmissaryServer.isStarted(), "Server did not stop and unbind"); + assertFalse(EmissaryServer.getInstance().isServerRunning(), "Server did not stop and unbind"); jserver = null; } diff --git a/src/test/java/emissary/test/core/junit5/UnitTest.java b/src/test/java/emissary/test/core/junit5/UnitTest.java index fbcc7e43e2..d319f6202a 100644 --- a/src/test/java/emissary/test/core/junit5/UnitTest.java +++ b/src/test/java/emissary/test/core/junit5/UnitTest.java @@ -3,6 +3,7 @@ import emissary.command.ServerCommand; import emissary.config.ConfigUtil; import emissary.core.EmissaryException; +import emissary.server.EmissaryServer; import emissary.util.ThreadDump; import emissary.util.io.ResourceReader; @@ -109,7 +110,9 @@ public static synchronized void setupSystemProperties() { } // setup the environment stuff try { - ServerCommand.parse(ServerCommand.class, "-m", "cluster").setupCommand(); + ServerCommand command = ServerCommand.parse(ServerCommand.class, "-m", "cluster"); + command.setupCommand(); + EmissaryServer.init(command); } catch (EmissaryException e) { fail("Unable to setup Emissary environment", e); }