Skip to content

Commit

Permalink
EmissaryServer shutdown when unannounced places are started in strict…
Browse files Browse the repository at this point in the history
…-mode (#632)
  • Loading branch information
sambish5 authored Feb 28, 2024
1 parent c24aac8 commit 2b45ecf
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 28 deletions.
29 changes: 21 additions & 8 deletions src/main/java/emissary/admin/Startup.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class Startup {
protected final Set<String> failedPlaces = ConcurrentHashMap.newKeySet();

// Collection of the places as they finish coming up
protected final Map<String, String> places = new ConcurrentHashMap<>();
protected static final Map<String, String> places = new ConcurrentHashMap<>();

// Collection of places that are being started
protected final Set<String> placesToStart = ConcurrentHashMap.newKeySet();
Expand All @@ -70,8 +70,11 @@ public class Startup {
protected final Map<String, List<String>> pickupLists = new ConcurrentHashMap<>();

// sets to keep track of possible invisible place startup
protected Set<String> activeDirPlaces = new LinkedHashSet<>();
protected Set<String> placeAlreadyStarted = new LinkedHashSet<>();
protected static Set<String> activeDirPlaces = new LinkedHashSet<>();
protected static Set<String> placeAlreadyStarted = new LinkedHashSet<>();

// invisible place startups occurred in strict mode
protected static boolean invisPlacesStartedInStrictMode = false;

/**
* n return the full DNS name and port without the protocol part
Expand Down Expand Up @@ -169,8 +172,8 @@ public void start() throws EmissaryException {
// the pickup places here.
startPickUpPlaces();

if (!verifyNoInvisiblePlacesStarted()) {
// TODO: If invisible places are started, shutdown the EmissaryServer
if (!verifyNoInvisiblePlacesStarted() && node.isStrictStartupMode()) {
invisPlacesStartedInStrictMode = true;
}
}

Expand Down Expand Up @@ -245,7 +248,7 @@ void startMapOfPlaces(final Map<String, List<String>> m) {

if (hashListSize(m) > 0) {
for (final List<String> placeList : m.values()) {
final boolean status = placeSetup(directoryAction, this.localDirectories, this.places, placeList);
final boolean status = placeSetup(directoryAction, this.localDirectories, places, placeList);

if (!status) {
logger.warn("Startup: places setup failed!");
Expand Down Expand Up @@ -419,7 +422,7 @@ protected void stopAndWaitForPlaceCreation() {
numPlacesExpected = this.placesToStart.size();
}

numPlacesFound = this.places.size();
numPlacesFound = places.size();

if (numPlacesFound >= numPlacesExpected) {

Expand Down Expand Up @@ -512,7 +515,7 @@ private void sortPickupOrPlace(String theLocation, Map<String, List<String>> pla
*
* @return true if no invisible places started, false if yes
*/
public boolean verifyNoInvisiblePlacesStarted() {
public static boolean verifyNoInvisiblePlacesStarted() {
try {
IDirectoryPlace dirPlace = DirectoryPlace.lookup();
List<DirectoryEntry> dirEntries = dirPlace.getEntries();
Expand Down Expand Up @@ -551,4 +554,14 @@ public boolean verifyNoInvisiblePlacesStarted() {

return true;
}

// get invisibly started places
public static Set<String> getInvisPlaces() {
return activeDirPlaces;
}

// get if invisible places are started while in strict mode
public static boolean isInvisPlacesStartedInStrictMode() {
return invisPlacesStartedInStrictMode;
}
}
8 changes: 8 additions & 0 deletions src/main/java/emissary/server/EmissaryServer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package emissary.server;

import emissary.admin.Startup;
import emissary.client.EmissaryClient;
import emissary.client.EmissaryResponse;
import emissary.client.HTTPConnectionFactory;
Expand Down Expand Up @@ -194,6 +195,13 @@ public Server startServer() {
}

LOG.info("Started EmissaryServer at {}", serverLocation);

// check if invisible place start-ups occurred on strict server start-up, and shut down server if so.
if (Startup.isInvisPlacesStartedInStrictMode() && this.server.isStarted()) {
EmissaryServer.stopServer(true);
LOG.info("Server shut down due to invisible place startups on strict-mode: {}", Startup.getInvisPlaces());
}

return configuredServer;
} catch (Throwable t) {
String errorMsg = "Emissary server didn't start";
Expand Down
35 changes: 15 additions & 20 deletions src/test/java/emissary/admin/StartupTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,39 +60,34 @@ void testSortPlaces() throws IOException {
void testInvisPlaceStart() throws IOException {
// setup node, startup, and DirectoryPlace
EmissaryNode node = new EmissaryNode();
Startup startup = new Startup(node.getNodeConfigurator(), node);
String location = "http://" + node.getNodeName() + ":" + node.getNodePort();
dirStartUp();

// test if place is already started before startup
startup.activeDirPlaces.add(location + "/PlaceAlreadyStartedTest");
startup.placeAlreadyStarted.add(location + "/PlaceAlreadyStartedTest");
assertTrue(startup.verifyNoInvisiblePlacesStarted());
startup.activeDirPlaces.clear();
startup.placeAlreadyStarted.clear();
Startup.activeDirPlaces.add(location + "/PlaceAlreadyStartedTest");
Startup.placeAlreadyStarted.add(location + "/PlaceAlreadyStartedTest");
assertTrue(Startup.verifyNoInvisiblePlacesStarted());
Startup.activeDirPlaces.clear();
Startup.placeAlreadyStarted.clear();

// test if place is started up normally and is active dir
startup.places.put(location, DevNullPlace.class.getSimpleName());
startup.activeDirPlaces.add(DevNullPlace.class.getSimpleName());
assertTrue(startup.verifyNoInvisiblePlacesStarted());
startup.activeDirPlaces.clear();
startup.places.remove(location, DevNullPlace.class.getSimpleName());
Startup.places.put(location, DevNullPlace.class.getSimpleName());
Startup.activeDirPlaces.add(DevNullPlace.class.getSimpleName());
assertTrue(Startup.verifyNoInvisiblePlacesStarted());
Startup.activeDirPlaces.clear();
Startup.places.remove(location, DevNullPlace.class.getSimpleName());

// test unannounced place with active dir
startup.activeDirPlaces.add(location + "/PlaceStartUnannouncedTest");
assertFalse(startup.verifyNoInvisiblePlacesStarted());
startup.activeDirPlaces.clear();
Startup.activeDirPlaces.add(location + "/PlaceStartUnannouncedTest");
assertFalse(Startup.verifyNoInvisiblePlacesStarted());
Startup.activeDirPlaces.clear();

// teardown
dirTeardown();
}

@Test
void verifyNoInvisiblePlacesStartedHandlesNullLocalPlace() throws IOException {
// setup node, startup, and DirectoryPlace
EmissaryNode node = new EmissaryNode();
Startup startup = new Startup(node.getNodeConfigurator(), node);

void verifyNoInvisiblePlacesStartedHandlesNullLocalPlace() {
try (MockedStatic<DirectoryPlace> dirPlace = Mockito.mockStatic(DirectoryPlace.class)) {

DirectoryEntry entry = mock(DirectoryEntry.class);
Expand All @@ -106,7 +101,7 @@ void verifyNoInvisiblePlacesStartedHandlesNullLocalPlace() throws IOException {

dirPlace.when(DirectoryPlace::lookup).thenReturn(directoryPlace);

assertTrue(startup.verifyNoInvisiblePlacesStarted());
assertTrue(Startup.verifyNoInvisiblePlacesStarted());
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/test/java/emissary/server/EmissaryServerIT.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package emissary.server;

import emissary.admin.Startup;
import emissary.client.EmissaryClient;
import emissary.client.response.MapResponseEntity;
import emissary.command.ServerCommand;
import emissary.core.EmissaryException;
import emissary.directory.EmissaryNode;
import emissary.test.core.junit5.UnitTest;
import emissary.util.Version;

Expand All @@ -15,6 +18,7 @@
import java.util.concurrent.TimeUnit;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

class EmissaryServerIT extends UnitTest {

Expand Down Expand Up @@ -49,4 +53,15 @@ void testSSLWorks() throws Exception {
}
}

@Test
void testInvisPlacesOnStrictStartUp() throws EmissaryException {
ServerCommand cmd = ServerCommand.parse(ServerCommand.class, "--strict");
EmissaryServer server = new EmissaryServer(cmd);
EmissaryNode node = new EmissaryNode();
String location = "http://" + node.getNodeName() + ":" + node.getNodePort();
Startup.getInvisPlaces().add(location + "/PlaceStartUnannouncedTest");
server.startServer();
// make sure server is shutdown due to invis places on strict startup
assertFalse(server.isServerRunning());
}
}

0 comments on commit 2b45ecf

Please sign in to comment.