@@ -393,13 +393,12 @@ subprojects { | |||
entry 'jetty-server' | |||
entry 'jetty-servlet' | |||
} | |||
dependency('org.elasticsearch.client:elasticsearch-rest-high-level-client:7.13.3') { | |||
dependency('org.elasticsearch.client:elasticsearch-rest-high-level-client:7.14.1') { | |||
exclude 'commons-logging:commons-logging' | |||
} | |||
dependency 'org.elasticsearch.plugin:transport-netty4-client:7.13.3' | |||
dependency 'org.elasticsearch.plugin:transport-netty4-client:7.14.1' | |||
dependency 'org.elasticsearch:mocksocket:1.0' | |||
//analysis-common need to stay at 7.10.2 as it hasn't been published to mvn central | |||
dependency 'org.codelibs.elasticsearch.module:analysis-common:7.10.2' | |||
dependency 'org.codelibs.elasticsearch.module:analysis-common:7.14.1' | |||
dependency 'org.eclipse.jgit:org.eclipse.jgit:5.11.0.202103091610-r' | |||
dependency 'org.tmatesoft.svnkit:svnkit:1.10.1' | |||
dependency 'org.hamcrest:hamcrest-all:1.3' |
@@ -11,5 +11,5 @@ org.gradle.vfs.watch=true | |||
# https://www.elastic.co/downloads/elasticsearch-no-jdk | |||
elasticsearchDownloadUrlPath=https://artifacts.elastic.co/downloads/elasticsearch/ | |||
elasticsearchDownloadRepoxUrlPath=https://repox.jfrog.io/artifactory/sonarsource-bucket/sonarqube/elasticsearch/ | |||
elasticsearchDownloadUrlFile=elasticsearch-7.13.3-no-jdk-linux-x86_64.tar.gz | |||
elasticsearchDownloadSha512=b79c249b7fa181d56a62ae9997f14dac8a1bd64199573bc08a75dd344241d762f05405f391746492ad3843f097a79980a21ef99173c6c1eebe8d51541f20c01b | |||
elasticsearchDownloadUrlFile=elasticsearch-7.14.1-no-jdk-linux-x86_64.tar.gz | |||
elasticsearchDownloadSha512=77dca78ba865ae74863b3b2a3cd61e8a8e4478cd02eb020184dbf89fa32cf145a6bbd1d11a1cb88c2236a3b8cdb8b0047e3c0f1a40f609f31b898c905b2c211d |
@@ -41,7 +41,7 @@ import org.elasticsearch.cluster.health.ClusterHealthStatus; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; | |||
import static org.elasticsearch.core.TimeValue.timeValueSeconds; | |||
public class EsConnectorImpl implements EsConnector { | |||
private static final String ES_USERNAME = "elastic"; |
@@ -20,6 +20,7 @@ | |||
package org.sonar.application.process; | |||
import java.util.concurrent.atomic.AtomicBoolean; | |||
import org.elasticsearch.ElasticsearchException; | |||
import org.elasticsearch.ElasticsearchStatusException; | |||
import org.elasticsearch.cluster.health.ClusterHealthStatus; | |||
import org.elasticsearch.rest.RestStatus; | |||
@@ -96,6 +97,13 @@ public class EsManagedProcess extends AbstractManagedProcess { | |||
} | |||
} | |||
return KO; | |||
} catch (ElasticsearchException e) { | |||
if (e.status() == RestStatus.INTERNAL_SERVER_ERROR && e.getMessage().contains("Connection refused")) { | |||
return CONNECTION_REFUSED; | |||
} else { | |||
LOG.error("Failed to check status", e); | |||
} | |||
return KO; | |||
} catch (Exception e) { | |||
LOG.error("Failed to check status", e); | |||
return KO; |
@@ -56,6 +56,24 @@ public class EsConnectorImplTest { | |||
" \"error\" : \"i-have-a-bad-feelings-about-this\"" + | |||
"}"; | |||
private static final String ES_INFO_RESPONSE = "{" | |||
+ " \"name\" : \"sonarqube\"," | |||
+ " \"cluster_name\" : \"sonarqube\"," | |||
+ " \"cluster_uuid\" : \"6Oj9lFIyQVa_d5HgQWqQpA\"," | |||
+ " \"version\" : {" | |||
+ " \"number\" : \"7.14.1\"," | |||
+ " \"build_flavor\" : \"default\"," | |||
+ " \"build_type\" : \"tar\"," | |||
+ " \"build_hash\" : \"66b55ebfa59c92c15db3f69a335d500018b3331e\"," | |||
+ " \"build_date\" : \"2021-08-26T09:01:05.390870785Z\"," | |||
+ " \"build_snapshot\" : false," | |||
+ " \"lucene_version\" : \"8.9.0\"," | |||
+ " \"minimum_wire_compatibility_version\" : \"6.8.0\"," | |||
+ " \"minimum_index_compatibility_version\" : \"6.0.0-beta1\"" | |||
+ " }," | |||
+ " \"tagline\" : \"You Know, for Search\"" | |||
+ "}"; | |||
@Rule | |||
public MockWebServer mockWebServer = new MockWebServer(); | |||
@@ -95,10 +113,16 @@ public class EsConnectorImplTest { | |||
} | |||
private void mockServerResponse(int httpCode, String jsonResponse) { | |||
mockWebServer.enqueue(new MockResponse() | |||
.setResponseCode(200) | |||
.setBody(ES_INFO_RESPONSE) | |||
.setHeader("Content-Type", "application/json") | |||
.setHeader("X-elastic-product", "Elasticsearch")); | |||
mockWebServer.enqueue(new MockResponse() | |||
.setResponseCode(httpCode) | |||
.setBody(jsonResponse) | |||
.setHeader("Content-Type", "application/json")); | |||
.setHeader("Content-Type", "application/json") | |||
.setHeader("X-elastic-product", "Elasticsearch")); | |||
} | |||
} |
@@ -26,6 +26,7 @@ import ch.qos.logback.core.AppenderBase; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Optional; | |||
import org.elasticsearch.ElasticsearchException; | |||
import org.elasticsearch.ElasticsearchStatusException; | |||
import org.elasticsearch.cluster.health.ClusterHealthStatus; | |||
import org.elasticsearch.rest.RestStatus; | |||
@@ -103,6 +104,24 @@ public class EsManagedProcessTest { | |||
assertThat(underTest.isOperational()).isFalse(); | |||
} | |||
@Test | |||
public void isOperational_should_return_false_if_ElasticsearchException_with_connection_refused_thrown() { | |||
EsConnector esConnector = mock(EsConnector.class); | |||
when(esConnector.getClusterHealthStatus()) | |||
.thenThrow(new ElasticsearchException("Connection refused")); | |||
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector); | |||
assertThat(underTest.isOperational()).isFalse(); | |||
} | |||
@Test | |||
public void isOperational_should_return_false_if_ElasticsearchException_thrown() { | |||
EsConnector esConnector = mock(EsConnector.class); | |||
when(esConnector.getClusterHealthStatus()) | |||
.thenThrow(new ElasticsearchException("test")); | |||
EsManagedProcess underTest = new EsManagedProcess(mock(Process.class), ProcessId.ELASTICSEARCH, esConnector); | |||
assertThat(underTest.isOperational()).isFalse(); | |||
} | |||
@Test | |||
public void isOperational_must_log_once_when_master_is_not_elected() { | |||
MemoryAppender<ILoggingEvent> memoryAppender = new MemoryAppender<>(); | |||
@@ -122,20 +141,18 @@ public class EsManagedProcessTest { | |||
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 ?") | |||
); | |||
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 ?") | |||
); | |||
tuple(Level.INFO, "Elasticsearch is waiting for a master to be elected. Did you start all the search nodes ?")); | |||
} | |||
private static class MemoryAppender<E> extends AppenderBase<E> { | |||
private final List<E> events = new ArrayList(); | |||
private final List<E> events = new ArrayList<>(); | |||
@Override | |||
protected void append(E eventObject) { |
@@ -52,7 +52,7 @@ import org.elasticsearch.cluster.metadata.IndexMetadata; | |||
import org.elasticsearch.common.document.DocumentField; | |||
import org.elasticsearch.common.unit.ByteSizeUnit; | |||
import org.elasticsearch.common.unit.ByteSizeValue; | |||
import org.elasticsearch.common.unit.TimeValue; | |||
import org.elasticsearch.core.TimeValue; | |||
import org.elasticsearch.search.SearchHit; | |||
import org.elasticsearch.search.sort.SortOrder; | |||
import org.sonar.api.utils.log.Logger; |
@@ -35,7 +35,7 @@ import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.elasticsearch.action.search.SearchResponse; | |||
import org.elasticsearch.action.search.SearchScrollRequest; | |||
import org.elasticsearch.common.unit.TimeValue; | |||
import org.elasticsearch.core.TimeValue; | |||
import org.elasticsearch.search.SearchHit; | |||
import org.elasticsearch.search.SearchHits; | |||
import org.elasticsearch.search.aggregations.bucket.terms.Terms; |
@@ -33,7 +33,7 @@ import org.apache.commons.lang.StringUtils; | |||
import org.apache.lucene.search.join.ScoreMode; | |||
import org.elasticsearch.action.search.SearchRequest; | |||
import org.elasticsearch.action.search.SearchResponse; | |||
import org.elasticsearch.common.unit.TimeValue; | |||
import org.elasticsearch.core.TimeValue; | |||
import org.elasticsearch.index.query.BoolQueryBuilder; | |||
import org.elasticsearch.index.query.Operator; | |||
import org.elasticsearch.index.query.QueryBuilder; |
@@ -25,7 +25,7 @@ import org.elasticsearch.action.search.ClearScrollRequest; | |||
import org.elasticsearch.action.search.SearchRequest; | |||
import org.elasticsearch.action.search.SearchResponse; | |||
import org.elasticsearch.action.search.SearchScrollRequest; | |||
import org.elasticsearch.common.unit.TimeValue; | |||
import org.elasticsearch.core.TimeValue; | |||
import org.elasticsearch.search.SearchHit; | |||
import org.elasticsearch.search.builder.SearchSourceBuilder; | |||
import org.elasticsearch.search.sort.SortOrder; |
@@ -31,7 +31,7 @@ import org.elasticsearch.action.search.SearchScrollRequest; | |||
import org.elasticsearch.client.Requests; | |||
import org.elasticsearch.client.indices.CreateIndexRequest; | |||
import org.elasticsearch.client.indices.GetIndexRequest; | |||
import org.elasticsearch.common.unit.TimeValue; | |||
import org.elasticsearch.core.TimeValue; | |||
import org.junit.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; |
@@ -65,7 +65,7 @@ import org.elasticsearch.cluster.health.ClusterHealthStatus; | |||
import org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings; | |||
import org.elasticsearch.common.Strings; | |||
import org.elasticsearch.common.settings.Settings; | |||
import org.elasticsearch.common.unit.TimeValue; | |||
import org.elasticsearch.core.TimeValue; | |||
import org.elasticsearch.discovery.DiscoveryModule; | |||
import org.elasticsearch.env.Environment; | |||
import org.elasticsearch.env.NodeEnvironment; |
@@ -224,8 +224,8 @@ zip.doFirst { | |||
} | |||
// Check the size of the archive | |||
zip.doLast { | |||
def minLength = 274000000 | |||
def maxLength = 295000000 | |||
def minLength = 295000000 | |||
def maxLength = 310000000 | |||
def length = archiveFile.get().asFile.length() | |||
if (length < minLength) |