aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>2017-09-18 10:48:23 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2017-09-26 23:49:37 +0200
commitd7df6d3c31db2ca875d8dec2c0b873cc04b7738e (patch)
treebde89f8ddd10e4fba79a7f0094617cbdbbad8304
parentdf538630ea2ae47b725414257f65a8a9e28722bb (diff)
downloadsonarqube-d7df6d3c31db2ca875d8dec2c0b873cc04b7738e.tar.gz
sonarqube-d7df6d3c31db2ca875d8dec2c0b873cc04b7738e.zip
SONAR-9802 fail restarting attempts on cluster nodes
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java21
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java3
-rw-r--r--tests/src/test/java/org/sonarqube/tests/cluster/ClusterTest.java20
4 files changed, 50 insertions, 3 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java
index 3a5160d573a..00d5aaebdc0 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/RestartAction.java
@@ -28,6 +28,7 @@ import org.sonar.api.utils.log.Loggers;
import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.app.RestartFlagHolder;
import org.sonar.server.platform.Platform;
+import org.sonar.server.platform.WebServer;
import org.sonar.server.user.UserSession;
/**
@@ -42,13 +43,16 @@ public class RestartAction implements SystemWsAction {
private final Platform platform;
private final ProcessCommandWrapper processCommandWrapper;
private final RestartFlagHolder restartFlagHolder;
+ private final WebServer webServer;
- public RestartAction(UserSession userSession, Configuration config, Platform platform, ProcessCommandWrapper processCommandWrapper, RestartFlagHolder restartFlagHolder) {
+ public RestartAction(UserSession userSession, Configuration config, Platform platform, ProcessCommandWrapper processCommandWrapper, RestartFlagHolder restartFlagHolder,
+ WebServer webServer) {
this.userSession = userSession;
this.config = config;
this.platform = platform;
this.processCommandWrapper = processCommandWrapper;
this.restartFlagHolder = restartFlagHolder;
+ this.webServer = webServer;
}
@Override
@@ -62,6 +66,9 @@ public class RestartAction implements SystemWsAction {
@Override
public void handle(Request request, Response response) {
+ if (!webServer.isStandalone()) {
+ throw new IllegalArgumentException("Restart not allowed for cluster nodes");
+ }
if (config.getBoolean("sonar.web.dev").orElse(false)) {
LOGGER.info("Fast restarting WebServer...");
restartFlagHolder.set();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java
index 87195c8d5c6..059e2e0e064 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java
@@ -31,6 +31,7 @@ import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.app.RestartFlagHolder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.platform.Platform;
+import org.sonar.server.platform.WebServer;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.sonar.server.ws.WsTester;
@@ -38,6 +39,7 @@ import org.sonar.server.ws.WsTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class RestartActionTest {
@Rule
@@ -51,13 +53,15 @@ public class RestartActionTest {
private Platform platform = mock(Platform.class);
private ProcessCommandWrapper processCommandWrapper = mock(ProcessCommandWrapper.class);
private RestartFlagHolder restartFlagHolder = mock(RestartFlagHolder.class);
- private RestartAction sut = new RestartAction(userSessionRule, settings.asConfig(), platform, processCommandWrapper, restartFlagHolder);
+ private WebServer webServer = mock(WebServer.class);
+ private RestartAction sut = new RestartAction(userSessionRule, settings.asConfig(), platform, processCommandWrapper, restartFlagHolder, webServer);
private InOrder inOrder = Mockito.inOrder(platform, restartFlagHolder, processCommandWrapper);
private WsActionTester actionTester = new WsActionTester(sut);
@Test
public void restart_if_dev_mode() throws Exception {
+ when(webServer.isStandalone()).thenReturn(true);
settings.setProperty("sonar.web.dev", true);
SystemWs ws = new SystemWs(sut);
@@ -72,6 +76,7 @@ public class RestartActionTest {
@Test
public void restart_flag_is_unset_in_dev_mode_even_if_restart_fails() throws Exception {
+ when(webServer.isStandalone()).thenReturn(true);
settings.setProperty("sonar.web.dev", true);
RuntimeException toBeThrown = new RuntimeException("simulating platform.restart() failed");
doThrow(toBeThrown).when(platform).restart();
@@ -92,6 +97,7 @@ public class RestartActionTest {
@Test
public void request_fails_in_production_mode_with_ForbiddenException_when_user_is_not_logged_in() {
+ when(webServer.isStandalone()).thenReturn(true);
expectedException.expect(ForbiddenException.class);
actionTester.newRequest().execute();
@@ -99,6 +105,7 @@ public class RestartActionTest {
@Test
public void request_fails_in_production_mode_with_ForbiddenException_when_user_is_not_system_administrator() {
+ when(webServer.isStandalone()).thenReturn(true);
userSessionRule.logIn().setNonSystemAdministrator();
expectedException.expect(ForbiddenException.class);
@@ -107,7 +114,18 @@ public class RestartActionTest {
}
@Test
+ public void request_fails_in_cluster_mode_with_IllegalArgumentException() {
+ when(webServer.isStandalone()).thenReturn(false);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Restart not allowed for cluster nodes");
+
+ actionTester.newRequest().execute();
+ }
+
+ @Test
public void calls_ProcessCommandWrapper_requestForSQRestart_in_production_mode() throws Exception {
+ when(webServer.isStandalone()).thenReturn(true);
userSessionRule.logIn().setSystemAdministrator();
actionTester.newRequest().execute();
@@ -118,6 +136,7 @@ public class RestartActionTest {
@Test
public void logs_login_of_authenticated_user_requesting_the_restart_in_production_mode() throws Exception {
+ when(webServer.isStandalone()).thenReturn(true);
String login = "BigBother";
userSessionRule.logIn(login).setSystemAdministrator();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java
index 33490259467..593619663da 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java
@@ -27,6 +27,7 @@ import org.sonar.ce.http.CeHttpClientImpl;
import org.sonar.server.app.ProcessCommandWrapper;
import org.sonar.server.app.RestartFlagHolder;
import org.sonar.server.platform.Platform;
+import org.sonar.server.platform.WebServer;
import org.sonar.server.telemetry.TelemetryDataLoader;
import org.sonar.server.tester.AnonymousMockUserSession;
import org.sonar.server.user.UserSession;
@@ -41,7 +42,7 @@ public class SystemWsTest {
@Test
public void define() {
RestartAction action1 = new RestartAction(mock(UserSession.class), mock(Configuration.class), mock(Platform.class), mock(ProcessCommandWrapper.class),
- mock(RestartFlagHolder.class));
+ mock(RestartFlagHolder.class), mock(WebServer.class));
InfoAction action2 = new InfoAction(new AnonymousMockUserSession(), ceHttpClient, mock(TelemetryDataLoader.class));
SystemWs ws = new SystemWs(action1, action2);
WebService.Context context = new WebService.Context();
diff --git a/tests/src/test/java/org/sonarqube/tests/cluster/ClusterTest.java b/tests/src/test/java/org/sonarqube/tests/cluster/ClusterTest.java
index 5bf9ac21c7b..615c077fd95 100644
--- a/tests/src/test/java/org/sonarqube/tests/cluster/ClusterTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/cluster/ClusterTest.java
@@ -39,6 +39,7 @@ import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonarqube.ws.WsSystem;
import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.HttpException;
import static com.google.common.base.Preconditions.checkState;
import static org.assertj.core.api.Assertions.assertThat;
@@ -264,6 +265,25 @@ public class ClusterTest {
}
@Test
+ public void restart_action_is_not_allowed_for_cluster_nodes() throws Exception {
+ try (Cluster cluster = newCluster(2, 1)) {
+ cluster.getNodes().forEach(Node::start);
+ cluster.getAppNodes().forEach(Node::waitForStatusUp);
+
+ cluster.getAppNodes().forEach(node -> {
+ try {
+ node.wsClient().system().restart();
+ fail("The restart webservice must not succeed on cluster nodes");
+ } catch (HttpException e) {
+ // all good, we expected this!
+ assertThat(e.code()).isEqualTo(400);
+ assertThat(e.content()).contains("Restart not allowed for cluster nodes");
+ }
+ });
+ }
+ }
+
+ @Test
public void health_becomes_RED_when_all_search_nodes_go_down() throws Exception {
try (Cluster cluster = newCluster(2, 1)) {
cluster.getNodes().forEach(Node::start);