Skip to content

Commit

Permalink
initialize static instance of EmissaryServer (#1024)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpdahlke authored Jan 7, 2025
1 parent ac9d7f3 commit 1e9b231
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 80 deletions.
3 changes: 2 additions & 1 deletion src/main/java/emissary/admin/Startup.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -290,7 +291,7 @@ protected boolean localDirectorySetup(final Map<String, String> localDirectories

final long start = System.currentTimeMillis();
final Map<String, String> dirStarts = new HashMap<>();
EmissaryNode emissaryNode = new EmissaryNode();
EmissaryNode emissaryNode = EmissaryServer.getInstance().getNode();
for (final String thePlaceLocation : hostParameters) {

final String host = placeHost(thePlaceLocation);
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/emissary/command/ServerCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,8 @@ public void setupServer() throws EmissaryException {

@Override
protected void startService() {
try {
LOG.info("Running Emissary Server");
new EmissaryServer(this).startServer();
} catch (EmissaryException e) {
LOG.error("Unable to start server", e);
}
LOG.info("Running Emissary Server");
EmissaryServer.init(this).startServer();
}

@Override
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/emissary/directory/EmissaryNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,16 @@ public class EmissaryNode {

protected boolean strictStartupMode = false;

public EmissaryNode() {
this(DEFAULT_NODE_MODE);
}

/**
* 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(String 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
Expand All @@ -104,7 +109,6 @@ 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(Locale.getDefault()).replace(' ', '_');
this.nodeMode = System.getProperty("node.mode", DEFAULT_NODE_MODE).toLowerCase(Locale.getDefault());
this.nodeServiceType = System.getProperty(NODE_SERVICE_TYPE_PROPERTY, DEFAULT_NODE_SERVICE_TYPE);
this.strictStartupMode = Boolean.parseBoolean(System.getProperty(STRICT_STARTUP_MODE, String.valueOf(false)));
}
Expand Down Expand Up @@ -198,14 +202,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;
Expand Down
18 changes: 8 additions & 10 deletions src/main/java/emissary/pickup/WorkSpace.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,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<String> args = new ArrayList<>();
args.add("-b");
Expand All @@ -226,7 +226,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!");
Expand Down Expand Up @@ -292,16 +292,14 @@ public void stop() {
/**
* Shut down services that were started here
*/
@SuppressWarnings("CatchingUnchecked")
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);
}
Expand Down Expand Up @@ -525,8 +523,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.workSpaceName;
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/emissary/place/ServiceProviderPlace.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
97 changes: 59 additions & 38 deletions src/main/java/emissary/server/EmissaryServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,40 @@ public class EmissaryServer {

private final EmissaryNode emissaryNode;

public EmissaryServer(ServerCommand cmd) throws EmissaryException {
this(cmd, new EmissaryNode());
@SuppressWarnings("NonFinalStaticField")
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;
// 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;
this.emissaryNode = node;
}

public static EmissaryServer init(ServerCommand cmd) {
emissaryServer = new EmissaryServer(cmd);
return emissaryServer;
}

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");
// 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;
}

public static EmissaryServer getInstance() {
if (emissaryServer == null) {
throw new AssertionError("EmissaryServer has not yet been instantiated!");
}
return emissaryServer;
}

public EmissaryNode getNode() {
Expand Down Expand Up @@ -263,38 +279,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
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
public static void stopServer(final String name, final boolean quiet) {
stopServer(name, false, quiet);
}
Expand All @@ -306,10 +314,20 @@ public static void stopServer(final String name, final boolean quiet) {
* @param force force shutdown
* @param quiet be quiet about failures if true
*/
@Deprecated
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 {
Expand Down Expand Up @@ -392,28 +410,25 @@ 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");
}

/**
* Forcibly stop the server running under the default name
*/
public static void stopServerForce() {
stopServer(true, false);
stopServer(true);
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -459,7 +474,7 @@ public boolean isIdle() {
* Non-static way to stop a server
*/
public void stop() {
stopServer(getNamespaceName(), false);
stopServer(false);
}

/**
Expand All @@ -469,14 +484,15 @@ public Server getServer() {
return this.server;
}


@Deprecated
public synchronized String getNamespaceName() {
if (this.nameSpaceName == null) {
this.nameSpaceName = getDefaultNamespaceName();
}
return this.nameSpaceName;
}

@Deprecated
public static String getDefaultNamespaceName() {
return DEFAULT_NAMESPACE_NAME;
}
Expand All @@ -485,7 +501,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
public static boolean isStarted() {
return isStarted(getDefaultNamespaceName());
}
Expand All @@ -496,6 +514,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
public static boolean isStarted(final String name) {
boolean started = false;
try {
Expand All @@ -511,6 +530,7 @@ public static boolean isStarted(final String name) {
return started;
}

@Deprecated
public static boolean exists() {
try {
EmissaryServer.lookup();
Expand All @@ -521,13 +541,15 @@ public static boolean exists() {
return false;
}

@Deprecated
public static EmissaryServer lookup() throws NamespaceException {
return lookup(getDefaultNamespaceName());
}

/**
* Retreive instance from namespace using default name
* Retrieve instance from namespace using default name
*/
@Deprecated
public static EmissaryServer lookup(final String name) throws NamespaceException {
return (EmissaryServer) Namespace.lookup(name);
}
Expand Down Expand Up @@ -571,7 +593,6 @@ private void bindServer() throws AttributeInUseException {

LOG.debug("Binding {} ", DEFAULT_NAMESPACE_NAME);
Namespace.bind(getDefaultNamespaceName(), this);

}

private ContextHandler buildStaticHandler() {
Expand Down
Loading

0 comments on commit 1e9b231

Please sign in to comment.