aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-main
diff options
context:
space:
mode:
authorEric Hartmann <hartmann.eric@gmail.com>2017-09-11 15:37:47 +0200
committerEric Hartmann <hartmann.eric@gmail.Com>2017-09-14 17:55:38 +0200
commit061b6a5dcb5eac555630153f8d4fbfb81adff83a (patch)
tree9a7d5f7c02788e6e8148c3d6b911363393c1d5c2 /server/sonar-main
parentd37a06d8bb263713e3e2c99b977806a41dec15a6 (diff)
downloadsonarqube-061b6a5dcb5eac555630153f8d4fbfb81adff83a.tar.gz
sonarqube-061b6a5dcb5eac555630153f8d4fbfb81adff83a.zip
SONAR-9764 Add a dedicated message when there is no Elasticsearch master
Diffstat (limited to 'server/sonar-main')
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/process/EsProcessMonitor.java7
-rw-r--r--server/sonar-main/src/test/java/org/sonar/application/process/EsProcessMonitorTest.java49
2 files changed, 56 insertions, 0 deletions
diff --git a/server/sonar-main/src/main/java/org/sonar/application/process/EsProcessMonitor.java b/server/sonar-main/src/main/java/org/sonar/application/process/EsProcessMonitor.java
index ff049e69e67..e4730c7303d 100644
--- a/server/sonar-main/src/main/java/org/sonar/application/process/EsProcessMonitor.java
+++ b/server/sonar-main/src/main/java/org/sonar/application/process/EsProcessMonitor.java
@@ -34,6 +34,7 @@ import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
+import org.elasticsearch.discovery.MasterNotDiscoveredException;
import org.elasticsearch.transport.Netty4Plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,6 +55,7 @@ public class EsProcessMonitor extends AbstractProcessMonitor {
private final AtomicBoolean nodeUp = new AtomicBoolean(false);
private final AtomicBoolean nodeOperational = new AtomicBoolean(false);
+ private final AtomicBoolean firstMasterNotDiscoveredLog = new AtomicBoolean(true);
private final EsCommand esCommand;
private final EsConnector esConnector;
private AtomicReference<TransportClient> transportClient = new AtomicReference<>(null);
@@ -140,6 +142,11 @@ public class EsProcessMonitor extends AbstractProcessMonitor {
}
} catch (NoNodeAvailableException e) {
return CONNECTION_REFUSED;
+ } catch (MasterNotDiscoveredException e) {
+ if (firstMasterNotDiscoveredLog.getAndSet(false)) {
+ LOG.info("Elasticsearch is waiting for a master to be elected. Did you start all the search nodes ?");
+ }
+ return KO;
} catch (Exception e) {
LOG.error("Failed to check status", e);
return KO;
diff --git a/server/sonar-main/src/test/java/org/sonar/application/process/EsProcessMonitorTest.java b/server/sonar-main/src/test/java/org/sonar/application/process/EsProcessMonitorTest.java
index f1993b462f6..d0ef83444fc 100644
--- a/server/sonar-main/src/test/java/org/sonar/application/process/EsProcessMonitorTest.java
+++ b/server/sonar-main/src/test/java/org/sonar/application/process/EsProcessMonitorTest.java
@@ -19,17 +19,26 @@
*/
package org.sonar.application.process;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.AppenderBase;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
import org.elasticsearch.client.transport.NoNodeAvailableException;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
+import org.elasticsearch.discovery.MasterNotDiscoveredException;
import org.junit.Test;
+import org.slf4j.LoggerFactory;
import org.sonar.process.ProcessId;
import org.sonar.process.command.EsCommand;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -90,10 +99,50 @@ public class EsProcessMonitorTest {
assertThat(underTest.isOperational()).isFalse();
}
+ @Test
+ public void isOperational_must_log_once_when_master_is_not_elected() throws Exception {
+ MemoryAppender<ILoggingEvent> memoryAppender = new MemoryAppender<>();
+ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
+ lc.reset();
+ memoryAppender.setContext(lc);
+ memoryAppender.start();
+ lc.getLogger(EsProcessMonitor.class).addAppender(memoryAppender);
+
+ EsConnector esConnector = mock(EsConnector.class);
+ when(esConnector.getClusterHealthStatus(any()))
+ .thenThrow(new MasterNotDiscoveredException("Master not elected -test-"));
+
+ EsProcessMonitor underTest = new EsProcessMonitor(mock(Process.class), getEsCommand(), esConnector);
+ assertThat(underTest.isOperational()).isFalse();
+ assertThat(memoryAppender.events).isNotEmpty();
+ assertThat(memoryAppender.events)
+ .extracting(ILoggingEvent::getLevel, ILoggingEvent::getMessage)
+ .containsOnlyOnce(
+ tuple(Level.INFO, "Elasticsearch is waiting for a master to be elected. Did you start all the search nodes ?")
+ );
+
+ // Second call must not log another message
+ assertThat(underTest.isOperational()).isFalse();
+ assertThat(memoryAppender.events)
+ .extracting(ILoggingEvent::getLevel, ILoggingEvent::getMessage)
+ .containsOnlyOnce(
+ tuple(Level.INFO, "Elasticsearch is waiting for a master to be elected. Did you start all the search nodes ?")
+ );
+ }
+
private EsCommand getEsCommand() throws IOException {
Path tempDirectory = Files.createTempDirectory(getClass().getSimpleName());
return new EsCommand(ProcessId.ELASTICSEARCH, tempDirectory.toFile())
.setHost("localhost")
.setPort(new Random().nextInt(40000));
}
+
+ private class MemoryAppender<E> extends AppenderBase<E> {
+ private final List<E> events = new ArrayList();
+
+ @Override
+ protected void append(E eventObject) {
+ events.add(eventObject);
+ }
+ }
}