Browse Source

SONAR-10300 Forbid system properties in api/settings

tags/7.5
Julien Lancelot 6 years ago
parent
commit
e737a37b28
No account linked to committer's email address
100 changed files with 1341 additions and 955 deletions
  1. 2
    2
      server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
  2. 14
    12
      server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
  3. 7
    7
      server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java
  4. 3
    1
      server/sonar-db-core/src/test/java/org/sonar/db/CoreTestDb.java
  5. 2
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java
  6. 8
    18
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java
  7. 128
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DeleteSettingsDefinedInSonarDotProperties.java
  8. 24
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/package-info.java
  9. 1
    1
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java
  10. 14
    11
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java
  11. 131
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DeleteSettingsDefinedInSonarDotPropertiesTest.java
  12. 11
    0
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/DeleteSettingsDefinedInSonarDotPropertiesTest/properties.sql
  13. 9
    9
      server/sonar-main/src/main/java/org/sonar/application/AppFileSystem.java
  14. 10
    10
      server/sonar-main/src/main/java/org/sonar/application/AppReloaderImpl.java
  15. 10
    6
      server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java
  16. 6
    6
      server/sonar-main/src/main/java/org/sonar/application/cluster/health/SearchNodeHealthProvider.java
  17. 41
    30
      server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java
  18. 4
    3
      server/sonar-main/src/main/java/org/sonar/application/config/AppSettingsLoaderImpl.java
  19. 24
    24
      server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java
  20. 10
    10
      server/sonar-main/src/main/java/org/sonar/application/config/FileSystemSettings.java
  21. 12
    11
      server/sonar-main/src/main/java/org/sonar/application/config/JdbcSettings.java
  22. 10
    6
      server/sonar-main/src/main/java/org/sonar/application/es/EsInstallation.java
  23. 19
    15
      server/sonar-main/src/main/java/org/sonar/application/es/EsSettings.java
  24. 4
    3
      server/sonar-main/src/main/java/org/sonar/application/process/StopRequestWatcherImpl.java
  25. 14
    10
      server/sonar-main/src/test/java/org/sonar/application/AppFileSystemTest.java
  26. 4
    5
      server/sonar-main/src/test/java/org/sonar/application/AppLoggingTest.java
  27. 11
    8
      server/sonar-main/src/test/java/org/sonar/application/AppReloaderImplTest.java
  28. 10
    10
      server/sonar-main/src/test/java/org/sonar/application/AppStateFactoryTest.java
  29. 18
    20
      server/sonar-main/src/test/java/org/sonar/application/SchedulerImplTest.java
  30. 20
    21
      server/sonar-main/src/test/java/org/sonar/application/cluster/health/SearchNodeHealthProviderTest.java
  31. 30
    32
      server/sonar-main/src/test/java/org/sonar/application/config/ClusterSettingsLoopbackTest.java
  32. 51
    52
      server/sonar-main/src/test/java/org/sonar/application/config/ClusterSettingsTest.java
  33. 14
    15
      server/sonar-main/src/test/java/org/sonar/application/config/FileSystemSettingsTest.java
  34. 17
    16
      server/sonar-main/src/test/java/org/sonar/application/config/JdbcSettingsTest.java
  35. 39
    36
      server/sonar-main/src/test/java/org/sonar/application/es/EsInstallationTest.java
  36. 61
    50
      server/sonar-main/src/test/java/org/sonar/application/es/EsSettingsTest.java
  37. 2
    2
      server/sonar-main/src/test/java/org/sonar/application/process/StopRequestWatcherImplTest.java
  38. 112
    82
      server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java
  39. 2
    2
      server/sonar-process/src/main/java/org/sonar/process/cluster/hz/HazelcastMemberBuilder.java
  40. 2
    2
      server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java
  41. 2
    0
      server/sonar-process/src/test/java/org/sonar/process/ProcessPropertiesTest.java
  42. 3
    3
      server/sonar-process/src/test/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderTest.java
  43. 17
    17
      server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java
  44. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java
  45. 4
    3
      server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java
  46. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/authentication/JwtSerializer.java
  47. 22
    32
      server/sonar-server/src/main/java/org/sonar/server/authentication/SsoAuthenticator.java
  48. 3
    2
      server/sonar-server/src/main/java/org/sonar/server/badge/ws/ProjectBadgesWsModule.java
  49. 11
    10
      server/sonar-server/src/main/java/org/sonar/server/es/EsClientProvider.java
  50. 4
    4
      server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
  51. 8
    8
      server/sonar-server/src/main/java/org/sonar/server/health/NodeHealthProviderImpl.java
  52. 7
    4
      server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java
  53. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/platform/ServerIdManager.java
  54. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/platform/ServerLogging.java
  55. 1
    1
      server/sonar-server/src/main/java/org/sonar/server/platform/WebServer.java
  56. 4
    4
      server/sonar-server/src/main/java/org/sonar/server/platform/WebServerImpl.java
  57. 12
    15
      server/sonar-server/src/main/java/org/sonar/server/platform/db/EmbeddedDatabase.java
  58. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/platform/db/EmbeddedDatabaseFactory.java
  59. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SettingsSection.java
  60. 6
    4
      server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/StandaloneSystemSection.java
  61. 6
    4
      server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/cluster/NodeSystemSection.java
  62. 2
    12
      server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java
  63. 6
    2
      server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java
  64. 8
    3
      server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java
  65. 13
    1
      server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java
  66. 4
    0
      server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java
  67. 15
    8
      server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryClient.java
  68. 7
    5
      server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java
  69. 24
    9
      server/sonar-server/src/main/java/org/sonar/server/ui/ws/GlobalAction.java
  70. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/ui/ws/SettingsAction.java
  71. 6
    3
      server/sonar-server/src/main/java/org/sonar/server/user/SecurityRealmFactory.java
  72. 4
    3
      server/sonar-server/src/main/java/org/sonar/server/util/OkHttpClientProvider.java
  73. 2
    2
      server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java
  74. 9
    7
      server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java
  75. 2
    2
      server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java
  76. 3
    4
      server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java
  77. 23
    22
      server/sonar-server/src/test/java/org/sonar/server/es/EsClientProviderTest.java
  78. 13
    13
      server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java
  79. 14
    14
      server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthProviderImplTest.java
  80. 2
    2
      server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java
  81. 3
    3
      server/sonar-server/src/test/java/org/sonar/server/platform/db/EmbeddedDatabaseFactoryTest.java
  82. 28
    30
      server/sonar-server/src/test/java/org/sonar/server/platform/db/EmbeddedDatabaseTest.java
  83. 10
    7
      server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/cluster/NodeSystemSectionTest.java
  84. 6
    4
      server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java
  85. 3
    3
      server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java
  86. 2
    2
      server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java
  87. 16
    0
      server/sonar-server/src/test/java/org/sonar/server/setting/ws/ResetActionTest.java
  88. 17
    0
      server/sonar-server/src/test/java/org/sonar/server/setting/ws/SetActionTest.java
  89. 17
    1
      server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java
  90. 5
    3
      server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryClientTest.java
  91. 18
    3
      server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java
  92. 11
    9
      server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java
  93. 3
    3
      server/sonar-server/src/test/java/org/sonar/server/ui/ws/SettingsActionTest.java
  94. 5
    5
      server/sonar-server/src/test/java/org/sonar/server/user/SecurityRealmFactoryTest.java
  95. 4
    4
      sonar-application/src/main/java/org/sonar/application/App.java
  96. 0
    17
      sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java
  97. 0
    63
      sonar-core/src/main/java/org/sonar/core/config/TelemetryProperties.java
  98. 0
    2
      sonar-core/src/main/java/org/sonar/core/config/WebConstants.java
  99. 1
    12
      sonar-core/src/test/java/org/sonar/core/config/CorePropertyDefinitionsTest.java
  100. 0
    0
      sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java

+ 2
- 2
server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java View File

@@ -76,7 +76,6 @@ import org.sonar.db.DbClient;
import org.sonar.db.DefaultDatabase;
import org.sonar.db.purge.PurgeProfiler;
import org.sonar.process.NetworkUtilsImpl;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.logging.LogbackHelper;
import org.sonar.server.component.ComponentFinder;
@@ -160,6 +159,7 @@ import org.sonar.server.webhook.WebhookModule;
import org.sonarqube.ws.Rules;

import static java.util.Objects.requireNonNull;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;

public class ComputeEngineContainerImpl implements ComputeEngineContainer {

@@ -436,7 +436,7 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
// cleaning
CeCleaningModule.class);

if (props.valueAsBoolean(ProcessProperties.CLUSTER_ENABLED)) {
if (props.valueAsBoolean(CLUSTER_ENABLED.getKey())) {
container.add(
// system health
CeDistributedInformationImpl.class,

+ 14
- 12
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java View File

@@ -31,7 +31,6 @@ import org.junit.rules.TemporaryFolder;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.MutablePicoContainer;
import org.sonar.api.CoreProperties;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
import org.sonar.ce.CeDistributedInformationImpl;
@@ -49,9 +48,12 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonar.process.ProcessEntryPoint.PROPERTY_PROCESS_INDEX;
import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH;
import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.PATH_HOME;
import static org.sonar.process.ProcessProperties.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.JDBC_PASSWORD;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.JDBC_USERNAME;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;

public class ComputeEngineContainerImplTest {
private static final int CONTAINER_ITSELF = 1;
@@ -110,7 +112,7 @@ public class ComputeEngineContainerImplTest {
);
assertThat(picoContainer.getParent().getParent().getComponentAdapters()).hasSize(
CONTAINER_ITSELF
+ 14 // MigrationConfigurationModule
+ 15 // MigrationConfigurationModule
+ 17 // level 2
);
assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
@@ -118,7 +120,7 @@ public class ComputeEngineContainerImplTest {
+ 26 // level 1
+ 52 // content of DaoModule
+ 3 // content of EsSearchModule
+ 67 // content of CorePropertyDefinitions
+ 60 // content of CorePropertyDefinitions
+ 1 // StopFlagContainer
);
assertThat(
@@ -140,14 +142,14 @@ public class ComputeEngineContainerImplTest {
File homeDir = tempFolder.newFolder();
File dataDir = new File(homeDir, "data");
File tmpDir = new File(homeDir, "tmp");
properties.setProperty(PATH_HOME, homeDir.getAbsolutePath());
properties.setProperty(PATH_DATA, dataDir.getAbsolutePath());
properties.setProperty(PATH_TEMP, tmpDir.getAbsolutePath());
properties.setProperty(PATH_HOME.getKey(), homeDir.getAbsolutePath());
properties.setProperty(PATH_DATA.getKey(), dataDir.getAbsolutePath());
properties.setProperty(PATH_TEMP.getKey(), tmpDir.getAbsolutePath());
properties.setProperty(PROPERTY_PROCESS_INDEX, valueOf(ProcessId.COMPUTE_ENGINE.getIpcIndex()));
properties.setProperty(PROPERTY_SHARED_PATH, tmpDir.getAbsolutePath());
properties.setProperty(DatabaseProperties.PROP_URL, db.getUrl());
properties.setProperty(DatabaseProperties.PROP_USER, "sonar");
properties.setProperty(DatabaseProperties.PROP_PASSWORD, "sonar");
properties.setProperty(JDBC_URL.getKey(), db.getUrl());
properties.setProperty(JDBC_USERNAME.getKey(), "sonar");
properties.setProperty(JDBC_PASSWORD.getKey(), "sonar");
return properties;
}


+ 7
- 7
server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java View File

@@ -32,7 +32,6 @@ import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.dialect.Dialect;
@@ -43,6 +42,7 @@ import org.sonar.db.profiling.ProfiledDataSource;
import org.sonar.process.logging.LogbackHelper;

import static java.lang.String.format;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;

/**
* @since 2.12
@@ -54,7 +54,7 @@ public class DefaultDatabase implements Database {
private static final String DEFAULT_URL = "jdbc:h2:tcp://localhost/sonar";
private static final String SONAR_JDBC = "sonar.jdbc.";
private static final String SONAR_JDBC_DIALECT = "sonar.jdbc.dialect";
private static final String SONAR_JDBC_URL = "sonar.jdbc.url";
private static final String SONAR_JDBC_DRIVER = "sonar.jdbc.driverClassName";

private final LogbackHelper logbackHelper;
private final Settings settings;
@@ -83,16 +83,16 @@ public class DefaultDatabase implements Database {
void initSettings() {
properties = new Properties();
completeProperties(settings, properties, SONAR_JDBC);
completeDefaultProperty(properties, DatabaseProperties.PROP_URL, DEFAULT_URL);
completeDefaultProperty(properties, JDBC_URL.getKey(), DEFAULT_URL);
doCompleteProperties(properties);

dialect = DialectUtils.find(properties.getProperty(SONAR_JDBC_DIALECT), properties.getProperty(SONAR_JDBC_URL));
properties.setProperty(DatabaseProperties.PROP_DRIVER, dialect.getDefaultDriverClassName());
dialect = DialectUtils.find(properties.getProperty(SONAR_JDBC_DIALECT), properties.getProperty(JDBC_URL.getKey()));
properties.setProperty(SONAR_JDBC_DRIVER, dialect.getDefaultDriverClassName());
}

private void initDataSource() throws Exception {
// but it's correctly caught by start()
LOG.info("Create JDBC data source for {}", properties.getProperty(DatabaseProperties.PROP_URL, DEFAULT_URL));
LOG.info("Create JDBC data source for {}", properties.getProperty(JDBC_URL.getKey()), DEFAULT_URL);
BasicDataSource basicDataSource = (BasicDataSource) BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties));
datasource = new ProfiledDataSource(basicDataSource, NullConnectionInterceptor.INSTANCE);
datasource.setConnectionInitSqls(dialect.getConnectionInitStatements());
@@ -180,6 +180,6 @@ public class DefaultDatabase implements Database {

@Override
public String toString() {
return format("Database[%s]", properties != null ? properties.getProperty(SONAR_JDBC_URL) : "?");
return format("Database[%s]", properties != null ? properties.getProperty(JDBC_URL.getKey()) : "?");
}
}

+ 3
- 1
server/sonar-db-core/src/test/java/org/sonar/db/CoreTestDb.java View File

@@ -43,6 +43,8 @@ import org.sonar.api.utils.log.Loggers;
import org.sonar.db.dialect.H2;
import org.sonar.process.logging.LogbackHelper;

import static org.sonar.process.ProcessProperties.Property.JDBC_USERNAME;

/**
* This class should be call using @ClassRule in order to create the schema once (if @Rule is used
* the schema will be recreated before each test).
@@ -74,7 +76,7 @@ class CoreTestDb {
if (settings.hasKey("orchestrator.configUrl")) {
loadOrchestratorSettings(settings);
}
String login = settings.getString("sonar.jdbc.username");
String login = settings.getString(JDBC_USERNAME.getKey());
for (String key : settings.getKeysStartingWith("sonar.jdbc")) {
LOG.info(key + ": " + settings.getString(key));
}

+ 2
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java View File

@@ -34,6 +34,7 @@ import org.sonar.server.platform.db.migration.version.v65.DbVersion65;
import org.sonar.server.platform.db.migration.version.v66.DbVersion66;
import org.sonar.server.platform.db.migration.version.v67.DbVersion67;
import org.sonar.server.platform.db.migration.version.v70.DbVersion70;
import org.sonar.server.platform.db.migration.version.v71.DbVersion71;

public class MigrationConfigurationModule extends Module {
@Override
@@ -51,6 +52,7 @@ public class MigrationConfigurationModule extends Module {
DbVersion66.class,
DbVersion67.class,
DbVersion70.class,
DbVersion71.class,

// migration steps
MigrationStepRegistryImpl.class,

sonar-core/src/main/java/org/sonar/core/config/WebProperties.java → server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71.java View File

@@ -17,26 +17,16 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.config;
package org.sonar.server.platform.db.migration.version.v71;

import java.util.List;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.server.platform.db.migration.step.MigrationStepRegistry;
import org.sonar.server.platform.db.migration.version.DbVersion;

import static java.util.Arrays.asList;
public class DbVersion71 implements DbVersion {

public final class WebProperties {

private WebProperties() {
}

public static List<PropertyDefinition> all() {
return asList(
PropertyDefinition.builder(WebConstants.SONARCLOUD_ENABLED)
.defaultValue("false")
.name("Enable SonarCloud look&feel")
.type(PropertyType.BOOLEAN)
.hidden()
.build());
@Override
public void addSteps(MigrationStepRegistry registry) {
registry
.add(2000, "Delete settings defined in sonar.properties from PROPERTIES table", DeleteSettingsDefinedInSonarDotProperties.class);
}
}

+ 128
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/DeleteSettingsDefinedInSonarDotProperties.java View File

@@ -0,0 +1,128 @@
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.platform.db.migration.version.v71;

import com.google.common.base.Joiner;
import java.sql.SQLException;
import java.util.List;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.Database;
import org.sonar.server.platform.db.migration.step.DataChange;
import org.sonar.server.platform.db.migration.step.MassUpdate;
import org.sonar.server.platform.db.migration.step.SqlStatement;

import static java.util.Arrays.asList;

public class DeleteSettingsDefinedInSonarDotProperties extends DataChange {

private static final Logger LOG = Loggers.get(DeleteSettingsDefinedInSonarDotProperties.class);

private static final List<String> SONAR_PROPERTIES = asList(
"sonar.jdbc.url",
"sonar.jdbc.username",
"sonar.jdbc.password",
"sonar.jdbc.driverPath",
"sonar.jdbc.maxActive",
"sonar.jdbc.maxIdle",
"sonar.jdbc.minIdle",
"sonar.jdbc.maxWait",
"sonar.jdbc.minEvictableIdleTimeMillis",
"sonar.jdbc.timeBetweenEvictionRunsMillis",
"sonar.embeddedDatabase.port",
"sonar.path.data",
"sonar.path.home",
"sonar.path.logs",
"sonar.path.temp",
"sonar.path.web",
"sonar.search.host",
"sonar.search.port",
"sonar.search.httpPort",
"sonar.search.javaOpts",
"sonar.search.javaAdditionalOpts",
"sonar.search.replicas",
"sonar.search.minimumMasterNodes",
"sonar.search.initialStateTimeout",
"sonar.web.javaOpts",
"sonar.web.javaAdditionalOpts",
"sonar.web.port",
"sonar.auth.jwtBase64Hs256Secret",
"sonar.ce.javaOpts",
"sonar.ce.javaAdditionalOpts",
"sonar.enableStopCommand",
"http.proxyHost",
"https.proxyHost",
"http.proxyPort",
"https.proxyPort",
"http.proxyUser",
"http.proxyPassword",
"sonar.cluster.enabled",
"sonar.cluster.node.type",
"sonar.cluster.search.hosts",
"sonar.cluster.hosts",
"sonar.cluster.node.port",
"sonar.cluster.node.host",
"sonar.cluster.node.name",
"sonar.cluster.name",
"sonar.cluster.web.startupLeader",
"sonar.sonarcloud.enabled",
"sonar.updatecenter.activate",
"http.nonProxyHosts",
"http.auth.ntlm.domain",
"socksProxyHost",
"socksProxyPort",
"sonar.web.sso.enable",
"sonar.web.sso.loginHeader",
"sonar.web.sso.nameHeader",
"sonar.web.sso.emailHeader",
"sonar.web.sso.groupsHeader",
"sonar.web.sso.refreshIntervalInMinutes",
"sonar.security.realm",
"sonar.authenticator.ignoreStartupFailure",
"sonar.telemetry.enable",
"sonar.telemetry.url",
"sonar.telemetry.frequencyInSeconds");

private static final Joiner COMMA_JOINER = Joiner.on(",");

public DeleteSettingsDefinedInSonarDotProperties(Database db) {
super(db);
}

@Override
protected void execute(DataChange.Context context) throws SQLException {
MassUpdate massUpdate = context.prepareMassUpdate();
String selectSql = "select id, prop_key from properties where prop_key in (";
selectSql += SONAR_PROPERTIES.stream().map(p -> "?").collect(MoreCollectors.join(COMMA_JOINER));
selectSql += ")";
SqlStatement selectStatement = massUpdate.select(selectSql);
for (int i = 1; i <= SONAR_PROPERTIES.size(); i++) {
selectStatement.setString(i, SONAR_PROPERTIES.get(i - 1));
}
massUpdate.update("delete from properties where id=?");
massUpdate.execute((row, update) -> {
update.setLong(1, row.getLong(1));
LOG.warn("System setting '{}' was defined in database, it has been removed", row.getString(2));
return true;
});
}
}

+ 24
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v71/package-info.java View File

@@ -0,0 +1,24 @@
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
package org.sonar.server.platform.db.migration.version.v71;

import javax.annotation.ParametersAreNonnullByDefault;


+ 1
- 1
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java View File

@@ -37,7 +37,7 @@ public class MigrationConfigurationModuleTest {
assertThat(container.getPicoContainer().getComponentAdapters())
.hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER
// DbVersion classes
+ 11
+ 12
// Others
+ 3);
}

sonar-core/src/test/java/org/sonar/core/config/TelemetryPropertiesTest.java → server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DbVersion71Test.java View File

@@ -17,23 +17,26 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.config;

package org.sonar.server.platform.db.migration.version.v71;

import org.junit.Test;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationCount;
import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber;

public class TelemetryPropertiesTest {
public class DbVersion71Test {

private Configuration underTest = new MapSettings(new PropertyDefinitions(TelemetryProperties.all())).asConfig();
private DbVersion71 underTest = new DbVersion71();

@Test
public void default_telemetry_properties() {
assertThat(underTest.getBoolean("sonar.telemetry.enable")).hasValue(true);
assertThat(underTest.getInt("sonar.telemetry.frequencyInSeconds")).hasValue(6 * 60 * 60);
assertThat(underTest.get("sonar.telemetry.url")).hasValue("https://telemetry.sonarsource.com/sonarqube");
public void migrationNumber_starts_at_2000() {
verifyMinimumMigrationNumber(underTest, 2000);
}

@Test
public void verify_migration_count() {
verifyMigrationCount(underTest, 1);
}

}

+ 131
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/DeleteSettingsDefinedInSonarDotPropertiesTest.java View File

@@ -0,0 +1,131 @@
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package org.sonar.server.platform.db.migration.version.v71;

import java.sql.SQLException;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.assertj.core.groups.Tuple;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.db.CoreDbTester;
import org.sonar.server.platform.db.migration.step.DataChange;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;

public class DeleteSettingsDefinedInSonarDotPropertiesTest {

@Rule
public CoreDbTester db = CoreDbTester.createForSchema(DeleteSettingsDefinedInSonarDotPropertiesTest.class, "properties.sql");

@Rule
public LogTester logTester = new LogTester();

private DataChange underTest = new DeleteSettingsDefinedInSonarDotProperties(db.database());

@Test
public void delete_sonar_dot_properties_settings() throws SQLException {
insertSetting("sonar.jdbc.url");
insertSetting("sonar.path.data");
insertSetting("sonar.cluster.enabled");
insertSetting("sonar.updatecenter.activate");

underTest.execute();

assertNoSettings();
}

@Test
public void log_removed_settings() throws SQLException {
insertSetting("sonar.jdbc.url");
insertSetting("not.to.be.removed");

underTest.execute();

assertThat(logTester.logs(LoggerLevel.WARN)).containsExactlyInAnyOrder("System setting 'sonar.jdbc.url' was defined in database, it has been removed");
}

@Test
public void delete_setting_at_global_and_component_level() throws SQLException {
insertSetting("sonar.jdbc.url", null);
insertSetting("sonar.jdbc.url", 100L);

underTest.execute();

assertNoSettings();
}

@Test
public void migration_is_reentrant() throws SQLException {
insertSetting("sonar.jdbc.url");

underTest.execute();
assertNoSettings();

underTest.execute();
assertNoSettings();
}

@Test
public void does_nothing_when_no_sonar_dot_properties_settings() throws SQLException {
insertSetting("other");

underTest.execute();

assertSettings(tuple("other", null));
}

@Test
public void does_nothing_on_empty_table() throws SQLException {
underTest.execute();

assertSettings();
}

private void assertSettings(Tuple... expectedTuples) {
assertThat(db.select("SELECT PROP_KEY, RESOURCE_ID FROM PROPERTIES")
.stream()
.map(map -> new Tuple(map.get("PROP_KEY"), map.get("RESOURCE_ID")))
.collect(Collectors.toList()))
.containsExactlyInAnyOrder(expectedTuples);
}

private void assertNoSettings() {
assertSettings();
}

private void insertSetting(String key) {
insertSetting(key, null);
}

private void insertSetting(String key, @Nullable Long componentId) {
db.executeInsert(
"properties",
"PROP_KEY", key,
"RESOURCE_ID", componentId,
"IS_EMPTY", false,
"CREATED_AT", 1000);
}

}

+ 11
- 0
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v71/DeleteSettingsDefinedInSonarDotPropertiesTest/properties.sql View File

@@ -0,0 +1,11 @@
CREATE TABLE "PROPERTIES" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"PROP_KEY" VARCHAR(512) NOT NULL,
"RESOURCE_ID" INTEGER,
"USER_ID" INTEGER,
"IS_EMPTY" BOOLEAN NOT NULL,
"TEXT_VALUE" VARCHAR(4000),
"CLOB_VALUE" CLOB,
"CREATED_AT" BIGINT
);
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY");

+ 9
- 9
server/sonar-main/src/main/java/org/sonar/application/AppFileSystem.java View File

@@ -38,10 +38,10 @@ import static java.lang.String.format;
import static java.nio.file.FileVisitResult.CONTINUE;
import static org.apache.commons.io.FileUtils.forceMkdir;
import static org.sonar.process.FileUtils2.deleteDirectory;
import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.PATH_LOGS;
import static org.sonar.process.ProcessProperties.PATH_TEMP;
import static org.sonar.process.ProcessProperties.PATH_WEB;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;

public class AppFileSystem implements FileSystem {

@@ -56,10 +56,10 @@ public class AppFileSystem implements FileSystem {

@Override
public void reset() throws IOException {
createDirectory(PATH_DATA);
createDirectory(PATH_WEB);
createDirectory(PATH_LOGS);
File tempDir = createOrCleanTempDirectory(PATH_TEMP);
createDirectory(PATH_DATA.getKey());
createDirectory(PATH_WEB.getKey());
createDirectory(PATH_LOGS.getKey());
File tempDir = createOrCleanTempDirectory(PATH_TEMP.getKey());
try (AllProcessesCommands allProcessesCommands = new AllProcessesCommands(tempDir)) {
allProcessesCommands.clean();
}
@@ -67,7 +67,7 @@ public class AppFileSystem implements FileSystem {

@Override
public File getTempDir() {
return settings.getProps().nonNullValueAsFile(PATH_TEMP);
return settings.getProps().nonNullValueAsFile(PATH_TEMP.getKey());
}

private boolean createDirectory(String propKey) throws IOException {

+ 10
- 10
server/sonar-main/src/main/java/org/sonar/application/AppReloaderImpl.java View File

@@ -28,11 +28,11 @@ import org.sonar.process.MessageException;
import org.sonar.process.Props;

import static java.lang.String.format;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.PATH_LOGS;
import static org.sonar.process.ProcessProperties.PATH_TEMP;
import static org.sonar.process.ProcessProperties.PATH_WEB;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;

public class AppReloaderImpl implements AppReloader {

@@ -63,11 +63,11 @@ public class AppReloaderImpl implements AppReloader {
}

private static void ensureUnchangedConfiguration(Props oldProps, Props newProps) {
verifyUnchanged(oldProps, newProps, PATH_DATA);
verifyUnchanged(oldProps, newProps, PATH_WEB);
verifyUnchanged(oldProps, newProps, PATH_LOGS);
verifyUnchanged(oldProps, newProps, PATH_TEMP);
verifyUnchanged(oldProps, newProps, CLUSTER_ENABLED);
verifyUnchanged(oldProps, newProps, PATH_DATA.getKey());
verifyUnchanged(oldProps, newProps, PATH_WEB.getKey());
verifyUnchanged(oldProps, newProps, PATH_LOGS.getKey());
verifyUnchanged(oldProps, newProps, PATH_TEMP.getKey());
verifyUnchanged(oldProps, newProps, CLUSTER_ENABLED.getKey());
}

private static void verifyUnchanged(Props initialProps, Props newProps, String propKey) {

+ 10
- 6
server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java View File

@@ -23,13 +23,17 @@ import org.sonar.application.cluster.ClusterAppStateImpl;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.ClusterSettings;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.cluster.NodeType;
import org.sonar.process.cluster.hz.HazelcastMember;
import org.sonar.process.cluster.hz.HazelcastMemberBuilder;

import static java.util.Arrays.asList;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;

public class AppStateFactory {

@@ -49,11 +53,11 @@ public class AppStateFactory {

private static HazelcastMember createHzMember(Props props) {
HazelcastMemberBuilder builder = new HazelcastMemberBuilder()
.setNetworkInterface(props.nonNullValue(ProcessProperties.CLUSTER_NODE_HOST))
.setMembers(asList(props.nonNullValue(ProcessProperties.CLUSTER_HOSTS).split(",")))
.setNodeType(NodeType.parse(props.nonNullValue(ProcessProperties.CLUSTER_NODE_TYPE)))
.setNodeName(props.nonNullValue(ProcessProperties.CLUSTER_NODE_NAME))
.setPort(Integer.parseInt(props.nonNullValue(ProcessProperties.CLUSTER_NODE_PORT)))
.setNetworkInterface(props.nonNullValue(CLUSTER_NODE_HOST.getKey()))
.setMembers(asList(props.nonNullValue(CLUSTER_HOSTS.getKey()).split(",")))
.setNodeType(NodeType.parse(props.nonNullValue(CLUSTER_NODE_TYPE.getKey())))
.setNodeName(props.nonNullValue(CLUSTER_NODE_NAME.getKey()))
.setPort(Integer.parseInt(props.nonNullValue(CLUSTER_NODE_PORT.getKey())))
.setProcessId(ProcessId.APP);
return builder.build();
}

+ 6
- 6
server/sonar-main/src/main/java/org/sonar/application/cluster/health/SearchNodeHealthProvider.java View File

@@ -27,9 +27,9 @@ import org.sonar.process.cluster.health.NodeDetails;
import org.sonar.process.cluster.health.NodeHealth;
import org.sonar.process.cluster.health.NodeHealthProvider;

import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;

public class SearchNodeHealthProvider implements NodeHealthProvider {

@@ -44,15 +44,15 @@ public class SearchNodeHealthProvider implements NodeHealthProvider {
this.clusterAppState = clusterAppState;
this.nodeDetails = NodeDetails.newNodeDetailsBuilder()
.setType(NodeDetails.Type.SEARCH)
.setName(props.nonNullValue(CLUSTER_NODE_NAME))
.setName(props.nonNullValue(CLUSTER_NODE_NAME.getKey()))
.setHost(getHost(props, networkUtils))
.setPort(Integer.valueOf(props.nonNullValue(CLUSTER_NODE_PORT)))
.setPort(Integer.valueOf(props.nonNullValue(CLUSTER_NODE_PORT.getKey())))
.setStartedAt(clock.now())
.build();
}

private static String getHost(Props props, NetworkUtils networkUtils) {
String host = props.value(CLUSTER_NODE_HOST);
String host = props.value(CLUSTER_NODE_HOST.getKey());
if (host != null && !host.isEmpty()) {
return host;
}

+ 41
- 30
server/sonar-main/src/main/java/org/sonar/application/command/CommandFactoryImpl.java View File

@@ -28,14 +28,26 @@ import org.sonar.application.es.EsLogging;
import org.sonar.application.es.EsSettings;
import org.sonar.application.es.EsYmlSettings;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.System2;

import static org.sonar.process.ProcessProperties.HTTPS_PROXY_HOST;
import static org.sonar.process.ProcessProperties.HTTPS_PROXY_PORT;
import static org.sonar.process.ProcessProperties.HTTP_PROXY_HOST;
import static org.sonar.process.ProcessProperties.HTTP_PROXY_PORT;
import static org.sonar.process.ProcessProperties.Property.CE_JAVA_ADDITIONAL_OPTS;
import static org.sonar.process.ProcessProperties.Property.CE_JAVA_OPTS;
import static org.sonar.process.ProcessProperties.Property.HTTPS_PROXY_HOST;
import static org.sonar.process.ProcessProperties.Property.HTTPS_PROXY_PORT;
import static org.sonar.process.ProcessProperties.Property.HTTP_AUTH_NLM_DOMAN;
import static org.sonar.process.ProcessProperties.Property.HTTP_NON_PROXY_HOSTS;
import static org.sonar.process.ProcessProperties.Property.HTTP_PROXY_HOST;
import static org.sonar.process.ProcessProperties.Property.HTTP_PROXY_PORT;
import static org.sonar.process.ProcessProperties.Property.JDBC_DRIVER_PATH;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.SEARCH_JAVA_ADDITIONAL_OPTS;
import static org.sonar.process.ProcessProperties.Property.SEARCH_JAVA_OPTS;
import static org.sonar.process.ProcessProperties.Property.SOCKS_PROXY_HOST;
import static org.sonar.process.ProcessProperties.Property.SOCKS_PROXY_PORT;
import static org.sonar.process.ProcessProperties.Property.WEB_JAVA_ADDITIONAL_OPTS;
import static org.sonar.process.ProcessProperties.Property.WEB_JAVA_OPTS;

public class CommandFactoryImpl implements CommandFactory {
private static final String ENV_VAR_JAVA_TOOL_OPTIONS = "JAVA_TOOL_OPTIONS";
@@ -43,14 +55,14 @@ public class CommandFactoryImpl implements CommandFactory {
* Properties about proxy that must be set as system properties
*/
private static final String[] PROXY_PROPERTY_KEYS = new String[] {
HTTP_PROXY_HOST,
HTTP_PROXY_PORT,
"http.nonProxyHosts",
HTTPS_PROXY_HOST,
HTTPS_PROXY_PORT,
"http.auth.ntlm.domain",
"socksProxyHost",
"socksProxyPort"};
HTTP_PROXY_HOST.getKey(),
HTTP_PROXY_PORT.getKey(),
HTTP_NON_PROXY_HOSTS.getKey(),
HTTPS_PROXY_HOST.getKey(),
HTTPS_PROXY_PORT.getKey(),
HTTP_AUTH_NLM_DOMAN.getKey(),
SOCKS_PROXY_HOST.getKey(),
SOCKS_PROXY_PORT.getKey()};

private final Props props;
private final File tempDir;
@@ -93,11 +105,10 @@ public class CommandFactoryImpl implements CommandFactory {
.setReadsArgumentsFromFile(false)
.setArgument("path.conf", esInstallation.getConfDirectory().getAbsolutePath())
.setJvmOptions(new EsJvmOptions()
.addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_OPTS)
.addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_ADDITIONAL_OPTS)
.addFromMandatoryProperty(props, SEARCH_JAVA_OPTS.getKey())
.addFromMandatoryProperty(props, SEARCH_JAVA_ADDITIONAL_OPTS.getKey())
.add("-Delasticsearch")
.add("-Des.path.home=" + esInstallation.getHomeDirectory())
)
.add("-Des.path.home=" + esInstallation.getHomeDirectory()))
.setEnvVariable("ES_JVM_OPTIONS", esInstallation.getJvmOptions().getAbsolutePath())
.setEnvVariable("JAVA_HOME", System.getProperties().getProperty("java.home"))
.setClassName("org.elasticsearch.bootstrap.Elasticsearch")
@@ -115,8 +126,8 @@ public class CommandFactoryImpl implements CommandFactory {
esInstallation
.setLog4j2Properties(new EsLogging().createProperties(props, esInstallation.getLogDirectory()))
.setEsJvmOptions(new EsJvmOptions()
.addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_OPTS)
.addFromMandatoryProperty(props, ProcessProperties.SEARCH_JAVA_ADDITIONAL_OPTS))
.addFromMandatoryProperty(props, SEARCH_JAVA_OPTS.getKey())
.addFromMandatoryProperty(props, SEARCH_JAVA_ADDITIONAL_OPTS.getKey()))
.setEsYmlSettings(new EsYmlSettings(settingsMap))
.setClusterName(settingsMap.get("cluster.name"))
.setHost(settingsMap.get("network.host"))
@@ -126,11 +137,11 @@ public class CommandFactoryImpl implements CommandFactory {

@Override
public JavaCommand createWebCommand(boolean leader) {
File homeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME);
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey());

WebJvmOptions jvmOptions = new WebJvmOptions(tempDir)
.addFromMandatoryProperty(props, ProcessProperties.WEB_JAVA_OPTS)
.addFromMandatoryProperty(props, ProcessProperties.WEB_JAVA_ADDITIONAL_OPTS);
.addFromMandatoryProperty(props, WEB_JAVA_OPTS.getKey())
.addFromMandatoryProperty(props, WEB_JAVA_ADDITIONAL_OPTS.getKey());
addProxyJvmOptions(jvmOptions);

JavaCommand<WebJvmOptions> command = new JavaCommand<WebJvmOptions>(ProcessId.WEB_SERVER, homeDir)
@@ -138,12 +149,12 @@ public class CommandFactoryImpl implements CommandFactory {
.setArguments(props.rawProperties())
.setJvmOptions(jvmOptions)
// required for logback tomcat valve
.setEnvVariable(ProcessProperties.PATH_LOGS, props.nonNullValue(ProcessProperties.PATH_LOGS))
.setEnvVariable(PATH_LOGS.getKey(), props.nonNullValue(PATH_LOGS.getKey()))
.setArgument("sonar.cluster.web.startupLeader", Boolean.toString(leader))
.setClassName("org.sonar.server.app.WebServer")
.addClasspath("./lib/common/*")
.addClasspath("./lib/server/*");
String driverPath = props.value(ProcessProperties.JDBC_DRIVER_PATH);
String driverPath = props.value(JDBC_DRIVER_PATH.getKey());
if (driverPath != null) {
command.addClasspath(driverPath);
}
@@ -153,11 +164,11 @@ public class CommandFactoryImpl implements CommandFactory {

@Override
public JavaCommand createCeCommand() {
File homeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME);
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey());

CeJvmOptions jvmOptions = new CeJvmOptions(tempDir)
.addFromMandatoryProperty(props, ProcessProperties.CE_JAVA_OPTS)
.addFromMandatoryProperty(props, ProcessProperties.CE_JAVA_ADDITIONAL_OPTS);
.addFromMandatoryProperty(props, CE_JAVA_OPTS.getKey())
.addFromMandatoryProperty(props, CE_JAVA_ADDITIONAL_OPTS.getKey());
addProxyJvmOptions(jvmOptions);

JavaCommand<CeJvmOptions> command = new JavaCommand<CeJvmOptions>(ProcessId.COMPUTE_ENGINE, homeDir)
@@ -168,7 +179,7 @@ public class CommandFactoryImpl implements CommandFactory {
.addClasspath("./lib/common/*")
.addClasspath("./lib/server/*")
.addClasspath("./lib/ce/*");
String driverPath = props.value(ProcessProperties.JDBC_DRIVER_PATH);
String driverPath = props.value(JDBC_DRIVER_PATH.getKey());
if (driverPath != null) {
command.addClasspath(driverPath);
}
@@ -182,8 +193,8 @@ public class CommandFactoryImpl implements CommandFactory {
}

// defaults of HTTPS are the same than HTTP defaults
setSystemPropertyToDefaultIfNotSet(jvmOptions, HTTPS_PROXY_HOST, HTTP_PROXY_HOST);
setSystemPropertyToDefaultIfNotSet(jvmOptions, HTTPS_PROXY_PORT, HTTP_PROXY_PORT);
setSystemPropertyToDefaultIfNotSet(jvmOptions, HTTPS_PROXY_HOST.getKey(), HTTP_PROXY_HOST.getKey());
setSystemPropertyToDefaultIfNotSet(jvmOptions, HTTPS_PROXY_PORT.getKey(), HTTP_PROXY_PORT.getKey());
}

private void setSystemPropertyToDefaultIfNotSet(JvmOptions jvmOptions,

+ 4
- 3
server/sonar-main/src/main/java/org/sonar/application/config/AppSettingsLoaderImpl.java View File

@@ -31,10 +31,11 @@ import java.util.function.Consumer;
import org.slf4j.LoggerFactory;
import org.sonar.process.ConfigurationUtils;
import org.sonar.process.NetworkUtilsImpl;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.sonar.process.ProcessProperties.completeDefaults;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;

public class AppSettingsLoaderImpl implements AppSettingsLoader {

@@ -61,14 +62,14 @@ public class AppSettingsLoaderImpl implements AppSettingsLoader {
public AppSettings load() {
Properties p = loadPropertiesFile(homeDir);
p.putAll(CommandLineParser.parseArguments(cliArguments));
p.setProperty(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
p.setProperty(PATH_HOME.getKey(), homeDir.getAbsolutePath());
p = ConfigurationUtils.interpolateVariables(p, System.getenv());

// the difference between Properties and Props is that the latter
// supports decryption of values, so it must be used when values
// are accessed
Props props = new Props(p);
ProcessProperties.completeDefaults(props);
completeDefaults(props);
Arrays.stream(consumers).forEach(c -> c.accept(props));

return new AppSettingsImpl(props);

+ 24
- 24
server/sonar-main/src/main/java/org/sonar/application/config/ClusterSettings.java View File

@@ -38,15 +38,15 @@ import static java.util.Arrays.stream;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.joining;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.sonar.process.ProcessProperties.AUTH_JWT_SECRET;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.CLUSTER_WEB_STARTUP_LEADER;
import static org.sonar.process.ProcessProperties.JDBC_URL;
import static org.sonar.process.ProcessProperties.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.AUTH_JWT_SECRET;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_WEB_STARTUP_LEADER;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;

public class ClusterSettings implements Consumer<Props> {

@@ -65,33 +65,33 @@ public class ClusterSettings implements Consumer<Props> {

private void checkClusterProperties(Props props) {
// for internal use
if (props.value(CLUSTER_WEB_STARTUP_LEADER) != null) {
throw new MessageException(format("Property [%s] is forbidden", CLUSTER_WEB_STARTUP_LEADER));
if (props.value(CLUSTER_WEB_STARTUP_LEADER.getKey()) != null) {
throw new MessageException(format("Property [%s] is forbidden", CLUSTER_WEB_STARTUP_LEADER.getKey()));
}

NodeType nodeType = toNodeType(props);
switch (nodeType) {
case APPLICATION:
ensureNotH2(props);
requireValue(props, AUTH_JWT_SECRET);
requireValue(props, AUTH_JWT_SECRET.getKey());
break;
case SEARCH:
requireValue(props, SEARCH_HOST);
ensureLocalButNotLoopbackAddress(props, SEARCH_HOST);
requireValue(props, SEARCH_HOST.getKey());
ensureLocalButNotLoopbackAddress(props, SEARCH_HOST.getKey());
break;
default:
throw new UnsupportedOperationException("Unknown value: " + nodeType);
}
ensureNotLoopbackAddresses(props, CLUSTER_HOSTS);
requireValue(props, CLUSTER_NODE_HOST);
ensureLocalButNotLoopbackAddress(props, CLUSTER_NODE_HOST);
ensureNotLoopbackAddresses(props, CLUSTER_SEARCH_HOSTS);
ensureNotLoopbackAddresses(props, CLUSTER_HOSTS.getKey());
requireValue(props, CLUSTER_NODE_HOST.getKey());
ensureLocalButNotLoopbackAddress(props, CLUSTER_NODE_HOST.getKey());
ensureNotLoopbackAddresses(props, CLUSTER_SEARCH_HOSTS.getKey());
}

private static NodeType toNodeType(Props props) {
String nodeTypeValue = requireValue(props, CLUSTER_NODE_TYPE);
String nodeTypeValue = requireValue(props, CLUSTER_NODE_TYPE.getKey());
if (!NodeType.isValid(nodeTypeValue)) {
throw new MessageException(format("Invalid value for property %s: [%s], only [%s] are allowed", CLUSTER_NODE_TYPE, nodeTypeValue,
throw new MessageException(format("Invalid value for property %s: [%s], only [%s] are allowed", CLUSTER_NODE_TYPE.getKey(), nodeTypeValue,
Arrays.stream(NodeType.values()).map(NodeType::getValue).collect(joining(", "))));
}
return NodeType.parse(nodeTypeValue);
@@ -106,7 +106,7 @@ public class ClusterSettings implements Consumer<Props> {
}

private static void ensureNotH2(Props props) {
String jdbcUrl = props.value(JDBC_URL);
String jdbcUrl = props.value(JDBC_URL.getKey());
if (isBlank(jdbcUrl) || jdbcUrl.startsWith("jdbc:h2:")) {
throw new MessageException("Embedded database is not supported in cluster mode");
}
@@ -145,14 +145,14 @@ public class ClusterSettings implements Consumer<Props> {
}

private static boolean isClusterEnabled(Props props) {
return props.valueAsBoolean(CLUSTER_ENABLED);
return props.valueAsBoolean(CLUSTER_ENABLED.getKey());
}

public static List<ProcessId> getEnabledProcesses(AppSettings settings) {
if (!isClusterEnabled(settings)) {
return asList(ProcessId.ELASTICSEARCH, ProcessId.WEB_SERVER, ProcessId.COMPUTE_ENGINE);
}
NodeType nodeType = NodeType.parse(settings.getValue(CLUSTER_NODE_TYPE).orElse(""));
NodeType nodeType = NodeType.parse(settings.getValue(CLUSTER_NODE_TYPE.getKey()).orElse(""));
switch (nodeType) {
case APPLICATION:
return asList(ProcessId.WEB_SERVER, ProcessId.COMPUTE_ENGINE);
@@ -166,7 +166,7 @@ public class ClusterSettings implements Consumer<Props> {
public static boolean isLocalElasticsearchEnabled(AppSettings settings) {
// elasticsearch is enabled on "search" nodes, but disabled on "application" nodes
if (isClusterEnabled(settings.getProps())) {
return NodeType.parse(settings.getValue(CLUSTER_NODE_TYPE).orElse("")) == NodeType.SEARCH;
return NodeType.parse(settings.getValue(CLUSTER_NODE_TYPE.getKey()).orElse("")) == NodeType.SEARCH;
}

// elasticsearch is enabled in standalone mode

+ 10
- 10
server/sonar-main/src/main/java/org/sonar/application/config/FileSystemSettings.java View File

@@ -25,11 +25,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.process.Props;

import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.PATH_HOME;
import static org.sonar.process.ProcessProperties.PATH_LOGS;
import static org.sonar.process.ProcessProperties.PATH_TEMP;
import static org.sonar.process.ProcessProperties.PATH_WEB;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;

public class FileSystemSettings implements Consumer<Props> {

@@ -37,10 +37,10 @@ public class FileSystemSettings implements Consumer<Props> {

@Override
public void accept(Props props) {
ensurePropertyIsAbsolutePath(props, PATH_DATA);
ensurePropertyIsAbsolutePath(props, PATH_WEB);
ensurePropertyIsAbsolutePath(props, PATH_LOGS);
ensurePropertyIsAbsolutePath(props, PATH_TEMP);
ensurePropertyIsAbsolutePath(props, PATH_DATA.getKey());
ensurePropertyIsAbsolutePath(props, PATH_WEB.getKey());
ensurePropertyIsAbsolutePath(props, PATH_LOGS.getKey());
ensurePropertyIsAbsolutePath(props, PATH_TEMP.getKey());
}

private static File ensurePropertyIsAbsolutePath(Props props, String propKey) {
@@ -48,7 +48,7 @@ public class FileSystemSettings implements Consumer<Props> {
String path = props.nonNullValue(propKey);
File d = new File(path);
if (!d.isAbsolute()) {
File homeDir = props.nonNullValueAsFile(PATH_HOME);
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey());
d = new File(homeDir, path);
LOG.trace("Overriding property {} from relative path '{}' to absolute path '{}'", propKey, path, d.getAbsolutePath());
props.set(propKey, d.getAbsolutePath());

+ 12
- 11
server/sonar-main/src/main/java/org/sonar/application/config/JdbcSettings.java View File

@@ -32,14 +32,15 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.process.MessageException;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.process.ProcessProperties.JDBC_EMBEDDED_PORT;
import static org.sonar.process.ProcessProperties.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.JDBC_DRIVER_PATH;
import static org.sonar.process.ProcessProperties.Property.JDBC_EMBEDDED_PORT;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;

public class JdbcSettings implements Consumer<Props> {

@@ -58,12 +59,12 @@ public class JdbcSettings implements Consumer<Props> {

@Override
public void accept(Props props) {
File homeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME);
File homeDir = props.nonNullValueAsFile(PATH_HOME.getKey());
Provider provider = resolveProviderAndEnforceNonnullJdbcUrl(props);
String url = props.value(JDBC_URL);
String url = props.value(JDBC_URL.getKey());
checkUrlParameters(provider, url);
String driverPath = driverPath(homeDir, provider);
props.set(ProcessProperties.JDBC_DRIVER_PATH, driverPath);
props.set(JDBC_DRIVER_PATH.getKey(), driverPath);
}

String driverPath(File homeDir, Provider provider) {
@@ -83,19 +84,19 @@ public class JdbcSettings implements Consumer<Props> {
}

Provider resolveProviderAndEnforceNonnullJdbcUrl(Props props) {
String url = props.value(JDBC_URL);
Integer embeddedDatabasePort = props.valueAsInt(JDBC_EMBEDDED_PORT);
String url = props.value(JDBC_URL.getKey());
Integer embeddedDatabasePort = props.valueAsInt(JDBC_EMBEDDED_PORT.getKey());

if (embeddedDatabasePort != null) {
String correctUrl = buildH2JdbcUrl(embeddedDatabasePort);
warnIfUrlIsSet(embeddedDatabasePort, url, correctUrl);
props.set(JDBC_URL, correctUrl);
props.set(JDBC_URL.getKey(), correctUrl);
return Provider.H2;
}

if (isEmpty(url)) {
props.set(JDBC_URL, buildH2JdbcUrl(JDBC_EMBEDDED_PORT_DEFAULT_VALUE));
props.set(JDBC_EMBEDDED_PORT, String.valueOf(JDBC_EMBEDDED_PORT_DEFAULT_VALUE));
props.set(JDBC_URL.getKey(), buildH2JdbcUrl(JDBC_EMBEDDED_PORT_DEFAULT_VALUE));
props.set(JDBC_EMBEDDED_PORT.getKey(), String.valueOf(JDBC_EMBEDDED_PORT_DEFAULT_VALUE));
return Provider.H2;
}


+ 10
- 6
server/sonar-main/src/main/java/org/sonar/application/es/EsInstallation.java View File

@@ -24,9 +24,13 @@ import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.sonar.application.command.EsJvmOptions;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;

/**
* Holds {@link File} to the various directories of ElasticSearch distribution embedded in SonarQube and provides
* {@link File} objects to the various files of it SonarQube cares about.
@@ -49,7 +53,7 @@ public class EsInstallation {
private int port;

public EsInstallation(Props props) {
File sqHomeDir = props.nonNullValueAsFile(ProcessProperties.PATH_HOME);
File sqHomeDir = props.nonNullValueAsFile(PATH_HOME.getKey());

this.homeDirectory = new File(sqHomeDir, "elasticsearch");
this.outdatedSearchDirectories = buildOutdatedSearchDirs(props);
@@ -59,21 +63,21 @@ public class EsInstallation {
}

private static List<File> buildOutdatedSearchDirs(Props props) {
String dataPath = props.nonNullValue(ProcessProperties.PATH_DATA);
String dataPath = props.nonNullValue(PATH_DATA.getKey());
return Collections.singletonList(new File(dataPath, "es"));
}

private static File buildDataDir(Props props) {
String dataPath = props.nonNullValue(ProcessProperties.PATH_DATA);
String dataPath = props.nonNullValue(PATH_DATA.getKey());
return new File(dataPath, "es5");
}

private static File buildLogPath(Props props) {
return props.nonNullValueAsFile(ProcessProperties.PATH_LOGS);
return props.nonNullValueAsFile(PATH_LOGS.getKey());
}

private static File buildConfDir(Props props) {
File tempPath = props.nonNullValueAsFile(ProcessProperties.PATH_TEMP);
File tempPath = props.nonNullValueAsFile(PATH_TEMP.getKey());
return new File(new File(tempPath, "conf"), "es");
}


+ 19
- 15
server/sonar-main/src/main/java/org/sonar/application/es/EsSettings.java View File

@@ -26,15 +26,19 @@ import java.util.Map;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.System2;

import static java.lang.String.valueOf;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HTTP_PORT;
import static org.sonar.process.ProcessProperties.Property.SEARCH_INITIAL_STATE_TIMEOUT;
import static org.sonar.process.ProcessProperties.Property.SEARCH_MINIMUM_MASTER_NODES;
import static org.sonar.process.ProcessProperties.Property.SEARCH_PORT;

public class EsSettings {

@@ -52,10 +56,10 @@ public class EsSettings {
this.props = props;
this.fileSystem = fileSystem;

this.clusterName = props.nonNullValue(CLUSTER_NAME);
this.clusterEnabled = props.valueAsBoolean(CLUSTER_ENABLED);
this.clusterName = props.nonNullValue(CLUSTER_NAME.getKey());
this.clusterEnabled = props.valueAsBoolean(CLUSTER_ENABLED.getKey());
if (this.clusterEnabled) {
this.nodeName = props.value(CLUSTER_NODE_NAME, "sonarqube-" + UUID.randomUUID().toString());
this.nodeName = props.value(CLUSTER_NODE_NAME.getKey(), "sonarqube-" + UUID.randomUUID().toString());
} else {
this.nodeName = STANDALONE_NODE_NAME;
}
@@ -83,7 +87,7 @@ public class EsSettings {

private void configureNetwork(Map<String, String> builder) {
InetAddress host = readHost();
int port = Integer.parseInt(props.nonNullValue(ProcessProperties.SEARCH_PORT));
int port = Integer.parseInt(props.nonNullValue(SEARCH_PORT.getKey()));
LOGGER.info("Elasticsearch listening on {}:{}", host, port);

builder.put("transport.tcp.port", valueOf(port));
@@ -93,7 +97,7 @@ public class EsSettings {
// Elasticsearch sets the default value of TCP reuse address to true only on non-MSWindows machines, but why ?
builder.put("network.tcp.reuse_address", valueOf(true));

int httpPort = props.valueAsInt(ProcessProperties.SEARCH_HTTP_PORT, -1);
int httpPort = props.valueAsInt(SEARCH_HTTP_PORT.getKey(), -1);
if (httpPort < 0) {
// standard configuration
builder.put("http.enabled", valueOf(false));
@@ -109,11 +113,11 @@ public class EsSettings {
}

private InetAddress readHost() {
String hostProperty = props.nonNullValue(ProcessProperties.SEARCH_HOST);
String hostProperty = props.nonNullValue(SEARCH_HOST.getKey());
try {
return InetAddress.getByName(hostProperty);
} catch (UnknownHostException e) {
throw new IllegalStateException("Can not resolve host [" + hostProperty + "]. Please check network settings and property " + ProcessProperties.SEARCH_HOST, e);
throw new IllegalStateException("Can not resolve host [" + hostProperty + "]. Please check network settings and property " + SEARCH_HOST.getKey(), e);
}
}

@@ -124,10 +128,10 @@ public class EsSettings {
String initialStateTimeOut = "30s";

if (clusterEnabled) {
minimumMasterNodes = props.valueAsInt(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, 2);
initialStateTimeOut = props.value(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "120s");
minimumMasterNodes = props.valueAsInt(SEARCH_MINIMUM_MASTER_NODES.getKey(), 2);
initialStateTimeOut = props.value(SEARCH_INITIAL_STATE_TIMEOUT.getKey(), "120s");

String hosts = props.value(CLUSTER_SEARCH_HOSTS, "");
String hosts = props.value(CLUSTER_SEARCH_HOSTS.getKey(), "");
LOGGER.info("Elasticsearch cluster enabled. Connect to hosts [{}]", hosts);
builder.put("discovery.zen.ping.unicast.hosts", hosts);
}

+ 4
- 3
server/sonar-main/src/main/java/org/sonar/application/process/StopRequestWatcherImpl.java View File

@@ -22,10 +22,11 @@ package org.sonar.application.process;
import org.sonar.application.FileSystem;
import org.sonar.application.Scheduler;
import org.sonar.application.config.AppSettings;
import org.sonar.process.ProcessId;
import org.sonar.process.sharedmemoryfile.DefaultProcessCommands;
import org.sonar.process.sharedmemoryfile.ProcessCommands;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import static org.sonar.process.ProcessProperties.Property.ENABLE_STOP_COMMAND;

public class StopRequestWatcherImpl extends Thread implements StopRequestWatcher {

@@ -78,7 +79,7 @@ public class StopRequestWatcherImpl extends Thread implements StopRequestWatcher

@Override
public void startWatching() {
if (settings.getProps().valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND)) {
if (settings.getProps().valueAsBoolean(ENABLE_STOP_COMMAND.getKey())) {
start();
}
}

+ 14
- 10
server/sonar-main/src/test/java/org/sonar/application/AppFileSystemTest.java View File

@@ -34,9 +34,13 @@ import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.application.config.TestAppSettings;
import org.sonar.process.sharedmemoryfile.AllProcessesCommands;
import org.sonar.process.ProcessProperties;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;
import static org.sonar.process.sharedmemoryfile.ProcessCommands.MAX_PROCESSES;

public class AppFileSystemTest {
@@ -62,11 +66,11 @@ public class AppFileSystemTest {
logsDir = new File(homeDir, "logs");
webDir = new File(homeDir, "web");

settings.getProps().set(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
settings.getProps().set(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath());
settings.getProps().set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
settings.getProps().set(ProcessProperties.PATH_LOGS, logsDir.getAbsolutePath());
settings.getProps().set(ProcessProperties.PATH_WEB, webDir.getAbsolutePath());
settings.getProps().set(PATH_HOME.getKey(), homeDir.getAbsolutePath());
settings.getProps().set(PATH_DATA.getKey(), dataDir.getAbsolutePath());
settings.getProps().set(PATH_TEMP.getKey(), tempDir.getAbsolutePath());
settings.getProps().set(PATH_LOGS.getKey(), logsDir.getAbsolutePath());
settings.getProps().set(PATH_WEB.getKey(), webDir.getAbsolutePath());
}

@Test
@@ -152,22 +156,22 @@ public class AppFileSystemTest {

@Test
public void reset_throws_ISE_if_data_dir_is_a_file() throws Exception {
resetThrowsISEIfDirIsAFile(ProcessProperties.PATH_DATA);
resetThrowsISEIfDirIsAFile(PATH_DATA.getKey());
}

@Test
public void reset_throws_ISE_if_web_dir_is_a_file() throws Exception {
resetThrowsISEIfDirIsAFile(ProcessProperties.PATH_WEB);
resetThrowsISEIfDirIsAFile(PATH_WEB.getKey());
}

@Test
public void reset_throws_ISE_if_logs_dir_is_a_file() throws Exception {
resetThrowsISEIfDirIsAFile(ProcessProperties.PATH_LOGS);
resetThrowsISEIfDirIsAFile(PATH_LOGS.getKey());
}

@Test
public void reset_throws_ISE_if_temp_dir_is_a_file() throws Exception {
resetThrowsISEIfDirIsAFile(ProcessProperties.PATH_TEMP);
resetThrowsISEIfDirIsAFile(PATH_TEMP.getKey());
}

private void resetThrowsISEIfDirIsAFile(String property) throws IOException {

+ 4
- 5
server/sonar-main/src/test/java/org/sonar/application/AppLoggingTest.java View File

@@ -31,7 +31,6 @@ import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.joran.spi.ConsoleTarget;
import ch.qos.logback.core.rolling.RollingFileAppender;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import org.junit.AfterClass;
import org.junit.Before;
@@ -42,13 +41,13 @@ import org.junit.rules.TemporaryFolder;
import org.slf4j.LoggerFactory;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.TestAppSettings;
import org.sonar.process.ProcessProperties;
import org.sonar.process.logging.LogbackHelper;

import static org.assertj.core.api.Assertions.assertThat;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import static org.sonar.application.process.StreamGobbler.LOGGER_GOBBLER;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

public class AppLoggingTest {

@@ -65,7 +64,7 @@ public class AppLoggingTest {
@Before
public void setUp() throws Exception {
logDir = temp.newFolder();
settings.getProps().set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
settings.getProps().set(PATH_LOGS.getKey(), logDir.getAbsolutePath());
}

@AfterClass
@@ -249,7 +248,7 @@ public class AppLoggingTest {

@Test
public void no_info_log_from_hazelcast() {
settings.getProps().set(CLUSTER_ENABLED, "true");
settings.getProps().set(CLUSTER_ENABLED.getKey(), "true");
underTest.configure();

assertThat(

+ 11
- 8
server/sonar-main/src/test/java/org/sonar/application/AppReloaderImplTest.java View File

@@ -27,7 +27,6 @@ import org.sonar.application.config.AppSettings;
import org.sonar.application.config.AppSettingsLoader;
import org.sonar.application.config.TestAppSettings;
import org.sonar.process.MessageException;
import org.sonar.process.ProcessProperties;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
@@ -35,7 +34,11 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;

public class AppReloaderImplTest {

@@ -68,7 +71,7 @@ public class AppReloaderImplTest {

@Test
public void throw_ISE_if_cluster_is_enabled() throws IOException {
AppSettings settings = new TestAppSettings().set(CLUSTER_ENABLED, "true");
AppSettings settings = new TestAppSettings().set(CLUSTER_ENABLED.getKey(), "true");

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Restart is not possible with cluster mode");
@@ -82,15 +85,15 @@ public class AppReloaderImplTest {

@Test
public void throw_MessageException_if_path_properties_are_changed() throws IOException {
verifyFailureIfPropertyValueChanged(ProcessProperties.PATH_DATA);
verifyFailureIfPropertyValueChanged(ProcessProperties.PATH_LOGS);
verifyFailureIfPropertyValueChanged(ProcessProperties.PATH_TEMP);
verifyFailureIfPropertyValueChanged(ProcessProperties.PATH_WEB);
verifyFailureIfPropertyValueChanged(PATH_DATA.getKey());
verifyFailureIfPropertyValueChanged(PATH_LOGS.getKey());
verifyFailureIfPropertyValueChanged(PATH_TEMP.getKey());
verifyFailureIfPropertyValueChanged(PATH_WEB.getKey());
}

@Test
public void throw_MessageException_if_cluster_mode_changed() throws IOException {
verifyFailureIfPropertyValueChanged(CLUSTER_ENABLED);
verifyFailureIfPropertyValueChanged(CLUSTER_ENABLED.getKey());
}

private void verifyFailureIfPropertyValueChanged(String propertyKey) throws IOException {

+ 10
- 10
server/sonar-main/src/test/java/org/sonar/application/AppStateFactoryTest.java View File

@@ -29,11 +29,11 @@ import org.sonar.process.NetworkUtilsImpl;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assume.assumeThat;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;

public class AppStateFactoryTest {

@@ -45,11 +45,11 @@ public class AppStateFactoryTest {
Optional<InetAddress> ip = NetworkUtilsImpl.INSTANCE.getLocalNonLoopbackIpv4Address();
assumeThat(ip.isPresent(), CoreMatchers.is(true));

settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "application");
settings.set(CLUSTER_NODE_HOST, ip.get().getHostAddress());
settings.set(CLUSTER_HOSTS, ip.get().getHostAddress());
settings.set(CLUSTER_NAME, "foo");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "application");
settings.set(CLUSTER_NODE_HOST.getKey(), ip.get().getHostAddress());
settings.set(CLUSTER_HOSTS.getKey(), ip.get().getHostAddress());
settings.set(CLUSTER_NAME.getKey(), "foo");

AppState appState = underTest.create();
assertThat(appState).isInstanceOf(ClusterAppStateImpl.class);

+ 18
- 20
server/sonar-main/src/test/java/org/sonar/application/SchedulerImplTest.java View File

@@ -55,11 +55,11 @@ import static org.mockito.Mockito.mock;
import static org.sonar.process.ProcessId.COMPUTE_ENGINE;
import static org.sonar.process.ProcessId.ELASTICSEARCH;
import static org.sonar.process.ProcessId.WEB_SERVER;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;

public class SchedulerImplTest {

@@ -71,7 +71,6 @@ public class SchedulerImplTest {
public TemporaryFolder temporaryFolder = new TemporaryFolder();

private EsScriptCommand esScriptCommand;
private JavaCommand esJavaCommand;
private JavaCommand webLeaderCommand;
private JavaCommand webFollowerCommand;
private JavaCommand ceCommand;
@@ -89,7 +88,6 @@ public class SchedulerImplTest {
public void setUp() throws Exception {
File tempDir = temporaryFolder.newFolder();
esScriptCommand = new EsScriptCommand(ELASTICSEARCH, tempDir);
esJavaCommand = new JavaCommand(ELASTICSEARCH, tempDir);
webLeaderCommand = new JavaCommand(WEB_SERVER, tempDir);
webFollowerCommand = new JavaCommand(WEB_SERVER, tempDir);
ceCommand = new JavaCommand(COMPUTE_ENGINE, tempDir);
@@ -211,8 +209,8 @@ public class SchedulerImplTest {

@Test
public void search_node_starts_only_elasticsearch() throws Exception {
settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "search");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "search");
addRequiredNodeProperties();
SchedulerImpl underTest = newScheduler(true);
underTest.schedule();
@@ -226,8 +224,8 @@ public class SchedulerImplTest {
@Test
public void application_node_starts_only_web_and_ce() throws Exception {
clusterAppState.setOperational(ProcessId.ELASTICSEARCH);
settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "application");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "application");
SchedulerImpl underTest = newScheduler(true);
underTest.schedule();

@@ -245,8 +243,8 @@ public class SchedulerImplTest {
assertThat(clusterAppState.tryToLockWebLeader()).isTrue();

clusterAppState.setOperational(ProcessId.ELASTICSEARCH);
settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "search");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "search");
addRequiredNodeProperties();
SchedulerImpl underTest = newScheduler(true);
underTest.schedule();
@@ -263,8 +261,8 @@ public class SchedulerImplTest {
assertThat(clusterAppState.tryToLockWebLeader()).isTrue();
clusterAppState.setOperational(ProcessId.ELASTICSEARCH);

settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "application");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "application");
SchedulerImpl underTest = newScheduler(true);
underTest.schedule();

@@ -281,8 +279,8 @@ public class SchedulerImplTest {

@Test
public void web_server_waits_for_remote_elasticsearch_to_be_started_if_local_es_is_disabled() throws Exception {
settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "application");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "application");
SchedulerImpl underTest = newScheduler(true);
underTest.schedule();

@@ -321,9 +319,9 @@ public class SchedulerImplTest {
}

private void addRequiredNodeProperties() {
settings.set(CLUSTER_NODE_NAME, randomAlphanumeric(4));
settings.set(CLUSTER_NODE_HOST, randomAlphanumeric(4));
settings.set(CLUSTER_NODE_PORT, String.valueOf(1 + new Random().nextInt(999)));
settings.set(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(4));
settings.set(CLUSTER_NODE_HOST.getKey(), randomAlphanumeric(4));
settings.set(CLUSTER_NODE_PORT.getKey(), String.valueOf(1 + new Random().nextInt(999)));
}

private class TestCommandFactory implements CommandFactory {

+ 20
- 21
server/sonar-main/src/test/java/org/sonar/application/cluster/health/SearchNodeHealthProviderTest.java View File

@@ -28,7 +28,6 @@ import org.junit.rules.ExpectedException;
import org.sonar.application.cluster.ClusterAppState;
import org.sonar.process.NetworkUtils;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.cluster.health.NodeHealth;

@@ -38,9 +37,9 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;

public class SearchNodeHealthProviderTest {
@Rule
@@ -64,7 +63,7 @@ public class SearchNodeHealthProviderTest {
@Test
public void constructor_throws_NPE_if_NetworkUtils_getHostname_returns_null_and_property_is_not_set() {
Properties properties = new Properties();
properties.put(ProcessProperties.CLUSTER_NODE_NAME, randomAlphanumeric(3));
properties.put(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
Props props = new Props(properties);

expectedException.expect(NullPointerException.class);
@@ -75,7 +74,7 @@ public class SearchNodeHealthProviderTest {
@Test
public void constructor_throws_IAE_if_property_node_port_is_not_set() {
Properties properties = new Properties();
properties.put(ProcessProperties.CLUSTER_NODE_NAME, randomAlphanumeric(3));
properties.put(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(34));
Props props = new Props(properties);

@@ -89,8 +88,8 @@ public class SearchNodeHealthProviderTest {
public void constructor_throws_FormatException_if_property_node_port_is_not_an_integer() {
String port = randomAlphabetic(3);
Properties properties = new Properties();
properties.put(ProcessProperties.CLUSTER_NODE_NAME, randomAlphanumeric(3));
properties.put(ProcessProperties.CLUSTER_NODE_PORT, port);
properties.put(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
properties.put(CLUSTER_NODE_PORT.getKey(), port);
when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(34));
Props props = new Props(properties);

@@ -105,8 +104,8 @@ public class SearchNodeHealthProviderTest {
String name = randomAlphanumeric(3);
int port = 1 + random.nextInt(4);
Properties properties = new Properties();
properties.setProperty(CLUSTER_NODE_NAME, name);
properties.setProperty(CLUSTER_NODE_PORT, valueOf(port));
properties.setProperty(CLUSTER_NODE_NAME.getKey(), name);
properties.setProperty(CLUSTER_NODE_PORT.getKey(), valueOf(port));
when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(34));
when(clock.now()).thenReturn(1L + random.nextInt(87));
SearchNodeHealthProvider underTest = new SearchNodeHealthProvider(new Props(properties), clusterAppState, networkUtils, clock);
@@ -117,8 +116,8 @@ public class SearchNodeHealthProviderTest {
assertThat(nodeHealth.getDetails().getPort()).isEqualTo(port);

// change values in properties
properties.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(6));
properties.setProperty(CLUSTER_NODE_PORT, valueOf(1 + random.nextInt(99)));
properties.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(6));
properties.setProperty(CLUSTER_NODE_PORT.getKey(), valueOf(1 + random.nextInt(99)));

NodeHealth newNodeHealth = underTest.get();

@@ -130,9 +129,9 @@ public class SearchNodeHealthProviderTest {
public void get_returns_host_from_property_if_set_at_constructor_time() {
String host = randomAlphanumeric(55);
Properties properties = new Properties();
properties.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
properties.setProperty(CLUSTER_NODE_PORT, valueOf(1 + random.nextInt(4)));
properties.setProperty(CLUSTER_NODE_HOST, host);
properties.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
properties.setProperty(CLUSTER_NODE_PORT.getKey(), valueOf(1 + random.nextInt(4)));
properties.setProperty(CLUSTER_NODE_HOST.getKey(), host);
when(clock.now()).thenReturn(1L + random.nextInt(87));
SearchNodeHealthProvider underTest = new SearchNodeHealthProvider(new Props(properties), clusterAppState, networkUtils, clock);

@@ -141,7 +140,7 @@ public class SearchNodeHealthProviderTest {
assertThat(nodeHealth.getDetails().getHost()).isEqualTo(host);

// change now
properties.setProperty(CLUSTER_NODE_HOST, randomAlphanumeric(96));
properties.setProperty(CLUSTER_NODE_HOST.getKey(), randomAlphanumeric(96));

NodeHealth newNodeHealth = underTest.get();

@@ -161,10 +160,10 @@ public class SearchNodeHealthProviderTest {
private void getReturnsHostFromNetworkUtils(@Nullable String hostPropertyValue) {
String host = randomAlphanumeric(34);
Properties properties = new Properties();
properties.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
properties.setProperty(CLUSTER_NODE_PORT, valueOf(1 + random.nextInt(4)));
properties.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
properties.setProperty(CLUSTER_NODE_PORT.getKey(), valueOf(1 + random.nextInt(4)));
if (hostPropertyValue != null) {
properties.setProperty(CLUSTER_NODE_HOST, hostPropertyValue);
properties.setProperty(CLUSTER_NODE_HOST.getKey(), hostPropertyValue);
}
when(clock.now()).thenReturn(1L + random.nextInt(87));
when(networkUtils.getHostname()).thenReturn(host);
@@ -226,8 +225,8 @@ public class SearchNodeHealthProviderTest {
}

private long setRequiredPropertiesAndMocks(Properties properties) {
properties.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
properties.setProperty(CLUSTER_NODE_PORT, valueOf(1 + random.nextInt(4)));
properties.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
properties.setProperty(CLUSTER_NODE_PORT.getKey(), valueOf(1 + random.nextInt(4)));
long now = 1L + random.nextInt(87);
when(clock.now()).thenReturn(now);
when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(34));

+ 30
- 32
server/sonar-main/src/test/java/org/sonar/application/config/ClusterSettingsLoopbackTest.java View File

@@ -20,7 +20,6 @@
package org.sonar.application.config;

import java.net.InetAddress;
import java.net.SocketException;
import java.util.Optional;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
@@ -30,17 +29,16 @@ import org.junit.rules.ExpectedException;
import org.sonar.process.MessageException;
import org.sonar.process.NetworkUtils;
import org.sonar.process.NetworkUtilsImpl;
import org.sonar.process.ProcessProperties;

import static org.junit.Assume.assumeThat;
import static org.mockito.Mockito.spy;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.JDBC_URL;
import static org.sonar.process.ProcessProperties.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;

public class ClusterSettingsLoopbackTest {

@@ -60,26 +58,26 @@ public class ClusterSettingsLoopbackTest {
}

@Test
public void ClusterSettings_throws_MessageException_if_host_of_search_node_is_loopback() throws Exception {
verifySearchFailureIfLoopback(ProcessProperties.CLUSTER_NODE_HOST);
verifySearchFailureIfLoopback(ProcessProperties.CLUSTER_SEARCH_HOSTS);
verifySearchFailureIfLoopback(ProcessProperties.CLUSTER_HOSTS);
verifySearchFailureIfLoopback(ProcessProperties.SEARCH_HOST);
public void ClusterSettings_throws_MessageException_if_host_of_search_node_is_loopback() {
verifySearchFailureIfLoopback(CLUSTER_NODE_HOST.getKey());
verifySearchFailureIfLoopback(CLUSTER_SEARCH_HOSTS.getKey());
verifySearchFailureIfLoopback(CLUSTER_HOSTS.getKey());
verifySearchFailureIfLoopback(SEARCH_HOST.getKey());
}

@Test
public void ClusterSettings_throws_MessageException_if_host_of_app_node_is_loopback() throws Exception {
verifyAppFailureIfLoopback(ProcessProperties.CLUSTER_NODE_HOST);
verifyAppFailureIfLoopback(ProcessProperties.CLUSTER_SEARCH_HOSTS);
verifyAppFailureIfLoopback(ProcessProperties.CLUSTER_HOSTS);
public void ClusterSettings_throws_MessageException_if_host_of_app_node_is_loopback() {
verifyAppFailureIfLoopback(CLUSTER_NODE_HOST.getKey());
verifyAppFailureIfLoopback(CLUSTER_SEARCH_HOSTS.getKey());
verifyAppFailureIfLoopback(CLUSTER_HOSTS.getKey());
}

private void verifySearchFailureIfLoopback(String propertyKey) throws Exception {
private void verifySearchFailureIfLoopback(String propertyKey) {
TestAppSettings settings = newSettingsForSearchNode();
verifyFailure(propertyKey, settings);
}

private void verifyAppFailureIfLoopback(String propertyKey) throws Exception {
private void verifyAppFailureIfLoopback(String propertyKey) {
TestAppSettings settings = newSettingsForAppNode();
verifyFailure(propertyKey, settings);
}
@@ -95,22 +93,22 @@ public class ClusterSettingsLoopbackTest {

private TestAppSettings newSettingsForAppNode() {
return new TestAppSettings()
.set(CLUSTER_ENABLED, "true")
.set(CLUSTER_NODE_TYPE, "application")
.set(CLUSTER_NODE_HOST, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_ENABLED.getKey(), "true")
.set(CLUSTER_NODE_TYPE.getKey(), "application")
.set(CLUSTER_NODE_HOST.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set("sonar.auth.jwtBase64Hs256Secret", "abcde")
.set(JDBC_URL, "jdbc:mysql://localhost:3306/sonar");
.set(JDBC_URL.getKey(), "jdbc:mysql://localhost:3306/sonar");
}

private TestAppSettings newSettingsForSearchNode() {
return new TestAppSettings()
.set(CLUSTER_ENABLED, "true")
.set(CLUSTER_NODE_TYPE, "search")
.set(CLUSTER_NODE_HOST, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS, nonLoopbackLocal.getHostAddress())
.set(SEARCH_HOST, nonLoopbackLocal.getHostAddress());
.set(CLUSTER_ENABLED.getKey(), "true")
.set(CLUSTER_NODE_TYPE.getKey(), "search")
.set(CLUSTER_NODE_HOST.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set(SEARCH_HOST.getKey(), nonLoopbackLocal.getHostAddress());
}
}

+ 51
- 52
server/sonar-main/src/test/java/org/sonar/application/config/ClusterSettingsTest.java View File

@@ -20,7 +20,6 @@
package org.sonar.application.config;

import java.net.InetAddress;
import java.net.SocketException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -36,13 +35,13 @@ import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessId.COMPUTE_ENGINE;
import static org.sonar.process.ProcessId.ELASTICSEARCH;
import static org.sonar.process.ProcessId.WEB_SERVER;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.JDBC_URL;
import static org.sonar.process.ProcessProperties.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;

public class ClusterSettingsTest {

@@ -59,11 +58,11 @@ public class ClusterSettingsTest {
}

@Test
public void test_isClusterEnabled() throws Exception {
TestAppSettings settings = newSettingsForAppNode().set(CLUSTER_ENABLED, "true");
public void test_isClusterEnabled() {
TestAppSettings settings = newSettingsForAppNode().set(CLUSTER_ENABLED.getKey(), "true");
assertThat(ClusterSettings.isClusterEnabled(settings)).isTrue();

settings = new TestAppSettings().set(CLUSTER_ENABLED, "false");
settings = new TestAppSettings().set(CLUSTER_ENABLED.getKey(), "false");
assertThat(ClusterSettings.isClusterEnabled(settings)).isFalse();
}

@@ -74,12 +73,12 @@ public class ClusterSettingsTest {

@Test
public void getEnabledProcesses_returns_all_processes_in_standalone_mode() {
TestAppSettings settings = new TestAppSettings().set(CLUSTER_ENABLED, "false");
TestAppSettings settings = new TestAppSettings().set(CLUSTER_ENABLED.getKey(), "false");
assertThat(ClusterSettings.getEnabledProcesses(settings)).containsOnly(COMPUTE_ENGINE, ELASTICSEARCH, WEB_SERVER);
}

@Test
public void getEnabledProcesses_returns_configured_processes_in_cluster_mode() throws Exception {
public void getEnabledProcesses_returns_configured_processes_in_cluster_mode() {
TestAppSettings settings = newSettingsForAppNode();
assertThat(ClusterSettings.getEnabledProcesses(settings)).containsOnly(COMPUTE_ENGINE, WEB_SERVER);

@@ -90,7 +89,7 @@ public class ClusterSettingsTest {
@Test
public void accept_throws_MessageException_if_no_node_type_is_configured() {
TestAppSettings settings = new TestAppSettings();
settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_ENABLED.getKey(), "true");

expectedException.expect(MessageException.class);
expectedException.expectMessage("Property sonar.cluster.node.type is mandatory");
@@ -101,8 +100,8 @@ public class ClusterSettingsTest {
@Test
public void accept_throws_MessageException_if_node_type_is_not_correct() {
TestAppSettings settings = new TestAppSettings();
settings.set(CLUSTER_ENABLED, "true");
settings.set(CLUSTER_NODE_TYPE, "bla");
settings.set(CLUSTER_ENABLED.getKey(), "true");
settings.set(CLUSTER_NODE_TYPE.getKey(), "bla");

expectedException.expect(MessageException.class);
expectedException.expectMessage("Invalid value for property sonar.cluster.node.type: [bla], only [application, search] are allowed");
@@ -111,7 +110,7 @@ public class ClusterSettingsTest {
}

@Test
public void accept_throws_MessageException_if_internal_property_for_startup_leader_is_configured() throws Exception {
public void accept_throws_MessageException_if_internal_property_for_startup_leader_is_configured() {
TestAppSettings settings = newSettingsForAppNode();
settings.set("sonar.cluster.web.startupLeader", "true");

@@ -124,7 +123,7 @@ public class ClusterSettingsTest {
@Test
public void accept_does_nothing_if_cluster_is_disabled() {
TestAppSettings settings = new TestAppSettings();
settings.set(CLUSTER_ENABLED, "false");
settings.set(CLUSTER_ENABLED.getKey(), "false");
// this property is supposed to fail if cluster is enabled
settings.set("sonar.cluster.web.startupLeader", "true");

@@ -132,7 +131,7 @@ public class ClusterSettingsTest {
}

@Test
public void accept_throws_MessageException_if_h2_on_application_node() throws Exception {
public void accept_throws_MessageException_if_h2_on_application_node() {
TestAppSettings settings = newSettingsForAppNode();
settings.set("sonar.jdbc.url", "jdbc:h2:mem");

@@ -143,7 +142,7 @@ public class ClusterSettingsTest {
}

@Test
public void accept_does_not_verify_h2_on_search_node() throws Exception {
public void accept_does_not_verify_h2_on_search_node() {
TestAppSettings settings = newSettingsForSearchNode();
settings.set("sonar.jdbc.url", "jdbc:h2:mem");

@@ -152,9 +151,9 @@ public class ClusterSettingsTest {
}

@Test
public void accept_throws_MessageException_on_application_node_if_default_jdbc_url() throws Exception {
public void accept_throws_MessageException_on_application_node_if_default_jdbc_url() {
TestAppSettings settings = newSettingsForAppNode();
settings.clearProperty(JDBC_URL);
settings.clearProperty(JDBC_URL.getKey());

expectedException.expect(MessageException.class);
expectedException.expectMessage("Embedded database is not supported in cluster mode");
@@ -169,56 +168,56 @@ public class ClusterSettingsTest {
}

@Test
public void isLocalElasticsearchEnabled_returns_true_on_search_node() throws Exception {
public void isLocalElasticsearchEnabled_returns_true_on_search_node() {
TestAppSettings settings = newSettingsForSearchNode();

assertThat(ClusterSettings.isLocalElasticsearchEnabled(settings)).isTrue();
}

@Test
public void isLocalElasticsearchEnabled_returns_true_for_a_application_node() throws Exception {
public void isLocalElasticsearchEnabled_returns_true_for_a_application_node() {
TestAppSettings settings = newSettingsForAppNode();

assertThat(ClusterSettings.isLocalElasticsearchEnabled(settings)).isFalse();
}

@Test
public void accept_throws_MessageException_if_searchHost_is_missing() throws Exception {
public void accept_throws_MessageException_if_searchHost_is_missing() {
TestAppSettings settings = newSettingsForSearchNode();
settings.clearProperty(SEARCH_HOST);
assertThatPropertyIsMandatory(settings, SEARCH_HOST);
settings.clearProperty(SEARCH_HOST.getKey());
assertThatPropertyIsMandatory(settings, SEARCH_HOST.getKey());
}

@Test
public void accept_throws_MessageException_if_searchHost_is_empty() throws Exception {
public void accept_throws_MessageException_if_searchHost_is_empty() {
TestAppSettings settings = newSettingsForSearchNode();
settings.set(SEARCH_HOST, "");
assertThatPropertyIsMandatory(settings, SEARCH_HOST);
settings.set(SEARCH_HOST.getKey(), "");
assertThatPropertyIsMandatory(settings, SEARCH_HOST.getKey());
}

@Test
public void accept_throws_MessageException_if_clusterHosts_is_missing() throws Exception {
public void accept_throws_MessageException_if_clusterHosts_is_missing() {
TestAppSettings settings = newSettingsForSearchNode();
settings.clearProperty(CLUSTER_HOSTS);
assertThatPropertyIsMandatory(settings, CLUSTER_HOSTS);
settings.clearProperty(CLUSTER_HOSTS.getKey());
assertThatPropertyIsMandatory(settings, CLUSTER_HOSTS.getKey());
}

@Test
public void accept_throws_MessageException_if_clusterSearchHosts_is_missing() throws Exception {
public void accept_throws_MessageException_if_clusterSearchHosts_is_missing() {
TestAppSettings settings = newSettingsForSearchNode();
settings.clearProperty(CLUSTER_SEARCH_HOSTS);
assertThatPropertyIsMandatory(settings, CLUSTER_SEARCH_HOSTS);
settings.clearProperty(CLUSTER_SEARCH_HOSTS.getKey());
assertThatPropertyIsMandatory(settings, CLUSTER_SEARCH_HOSTS.getKey());
}

@Test
public void accept_throws_MessageException_if_clusterSearchHosts_is_empty() throws Exception {
public void accept_throws_MessageException_if_clusterSearchHosts_is_empty() {
TestAppSettings settings = newSettingsForSearchNode();
settings.set(CLUSTER_SEARCH_HOSTS, "");
assertThatPropertyIsMandatory(settings, CLUSTER_SEARCH_HOSTS);
settings.set(CLUSTER_SEARCH_HOSTS.getKey(), "");
assertThatPropertyIsMandatory(settings, CLUSTER_SEARCH_HOSTS.getKey());
}

@Test
public void accept_throws_MessageException_if_jwt_token_is_not_set_on_application_nodes() throws Exception {
public void accept_throws_MessageException_if_jwt_token_is_not_set_on_application_nodes() {
TestAppSettings settings = newSettingsForAppNode();
settings.clearProperty("sonar.auth.jwtBase64Hs256Secret");
assertThatPropertyIsMandatory(settings, "sonar.auth.jwtBase64Hs256Secret");
@@ -233,22 +232,22 @@ public class ClusterSettingsTest {

private TestAppSettings newSettingsForAppNode() {
return new TestAppSettings()
.set(CLUSTER_ENABLED, "true")
.set(CLUSTER_NODE_TYPE, "application")
.set(CLUSTER_NODE_HOST, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_ENABLED.getKey(), "true")
.set(CLUSTER_NODE_TYPE.getKey(), "application")
.set(CLUSTER_NODE_HOST.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set("sonar.auth.jwtBase64Hs256Secret", "abcde")
.set(JDBC_URL, "jdbc:mysql://localhost:3306/sonar");
.set(JDBC_URL.getKey(), "jdbc:mysql://localhost:3306/sonar");
}

private TestAppSettings newSettingsForSearchNode() {
return new TestAppSettings()
.set(CLUSTER_ENABLED, "true")
.set(CLUSTER_NODE_TYPE, "search")
.set(CLUSTER_NODE_HOST, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS, nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS, nonLoopbackLocal.getHostAddress())
.set(SEARCH_HOST, nonLoopbackLocal.getHostAddress());
.set(CLUSTER_ENABLED.getKey(), "true")
.set(CLUSTER_NODE_TYPE.getKey(), "search")
.set(CLUSTER_NODE_HOST.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set(CLUSTER_SEARCH_HOSTS.getKey(), nonLoopbackLocal.getHostAddress())
.set(SEARCH_HOST.getKey(), nonLoopbackLocal.getHostAddress());
}
}

+ 14
- 15
server/sonar-main/src/test/java/org/sonar/application/config/FileSystemSettingsTest.java View File

@@ -29,12 +29,11 @@ import org.junit.rules.TemporaryFolder;
import org.sonar.process.Props;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.PATH_HOME;
import static org.sonar.process.ProcessProperties.PATH_LOGS;
import static org.sonar.process.ProcessProperties.PATH_TEMP;
import static org.sonar.process.ProcessProperties.PATH_WEB;

import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;

public class FileSystemSettingsTest {

@@ -54,22 +53,22 @@ public class FileSystemSettingsTest {
@Test
public void relative_paths_are_converted_to_absolute_paths() {
Props props = new Props(new Properties());
props.set(PATH_HOME, homeDir.getAbsolutePath());
props.set(PATH_HOME.getKey(), homeDir.getAbsolutePath());

// relative paths
props.set(PATH_DATA, "data");
props.set(PATH_LOGS, "logs");
props.set(PATH_TEMP, "temp");
props.set(PATH_DATA.getKey(), "data");
props.set(PATH_LOGS.getKey(), "logs");
props.set(PATH_TEMP.getKey(), "temp");

// already absolute paths
props.set(PATH_WEB, new File(homeDir, "web").getAbsolutePath());
props.set(PATH_WEB.getKey(), new File(homeDir, "web").getAbsolutePath());

underTest.accept(props);

assertThat(props.nonNullValue(PATH_DATA)).isEqualTo(new File(homeDir, "data").getAbsolutePath());
assertThat(props.nonNullValue(PATH_LOGS)).isEqualTo(new File(homeDir, "logs").getAbsolutePath());
assertThat(props.nonNullValue(PATH_TEMP)).isEqualTo(new File(homeDir, "temp").getAbsolutePath());
assertThat(props.nonNullValue(PATH_WEB)).isEqualTo(new File(homeDir, "web").getAbsolutePath());
assertThat(props.nonNullValue(PATH_DATA.getKey())).isEqualTo(new File(homeDir, "data").getAbsolutePath());
assertThat(props.nonNullValue(PATH_LOGS.getKey())).isEqualTo(new File(homeDir, "logs").getAbsolutePath());
assertThat(props.nonNullValue(PATH_TEMP.getKey())).isEqualTo(new File(homeDir, "temp").getAbsolutePath());
assertThat(props.nonNullValue(PATH_WEB.getKey())).isEqualTo(new File(homeDir, "web").getAbsolutePath());
}

}

+ 17
- 16
server/sonar-main/src/test/java/org/sonar/application/config/JdbcSettingsTest.java View File

@@ -29,12 +29,13 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.process.MessageException;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.application.config.JdbcSettings.Provider;
import static org.sonar.process.ProcessProperties.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.JDBC_DRIVER_PATH;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;

public class JdbcSettingsTest {

@@ -57,7 +58,7 @@ public class JdbcSettingsTest {

assertThat(underTest.resolveProviderAndEnforceNonnullJdbcUrl(props))
.isEqualTo(Provider.H2);
assertThat(props.nonNullValue(JDBC_URL)).isEqualTo(String.format("jdbc:h2:tcp://%s:9092/sonar", InetAddress.getLoopbackAddress().getHostAddress()));
assertThat(props.nonNullValue(JDBC_URL.getKey())).isEqualTo(String.format("jdbc:h2:tcp://%s:9092/sonar", InetAddress.getLoopbackAddress().getHostAddress()));
}

@Test
@@ -88,15 +89,15 @@ public class JdbcSettingsTest {
}

private void checkProviderForUrlAndUnchangedUrl(String url, Provider expected) {
Props props = newProps(JDBC_URL, url);
Props props = newProps(JDBC_URL.getKey(), url);

assertThat(underTest.resolveProviderAndEnforceNonnullJdbcUrl(props)).isEqualTo(expected);
assertThat(props.nonNullValue(JDBC_URL)).isEqualTo(url);
assertThat(props.nonNullValue(JDBC_URL.getKey())).isEqualTo(url);
}

@Test
public void fail_with_MessageException_when_provider_is_not_supported() {
Props props = newProps(JDBC_URL, "jdbc:microsoft:sqlserver://localhost");
Props props = newProps(JDBC_URL.getKey(), "jdbc:microsoft:sqlserver://localhost");

expectedException.expect(MessageException.class);
expectedException.expectMessage("Unsupported JDBC driver provider: microsoft");
@@ -106,7 +107,7 @@ public class JdbcSettingsTest {

@Test
public void fail_with_MessageException_when_url_does_not_have_jdbc_prefix() {
Props props = newProps(JDBC_URL, "oracle:thin:@localhost/XE");
Props props = newProps(JDBC_URL.getKey(), "oracle:thin:@localhost/XE");

expectedException.expect(MessageException.class);
expectedException.expectMessage("Bad format of JDBC URL: oracle:thin:@localhost/XE");
@@ -136,9 +137,9 @@ public class JdbcSettingsTest {
File driverFile = new File(homeDir, "extensions/jdbc-driver/oracle/ojdbc6.jar");
FileUtils.touch(driverFile);

Props props = newProps(JDBC_URL, "jdbc:oracle:thin:@localhost/XE");
Props props = newProps(JDBC_URL.getKey(), "jdbc:oracle:thin:@localhost/XE");
underTest.accept(props);
assertThat(props.nonNullValueAsFile(ProcessProperties.JDBC_DRIVER_PATH)).isEqualTo(driverFile);
assertThat(props.nonNullValueAsFile(JDBC_DRIVER_PATH.getKey())).isEqualTo(driverFile);
}

@Test
@@ -146,9 +147,9 @@ public class JdbcSettingsTest {
File driverFile = new File(homeDir, "lib/jdbc/h2/h2.jar");
FileUtils.touch(driverFile);

Props props = newProps(JDBC_URL, "jdbc:h2:tcp://localhost:9092/sonar");
Props props = newProps(JDBC_URL.getKey(), "jdbc:h2:tcp://localhost:9092/sonar");
underTest.accept(props);
assertThat(props.nonNullValueAsFile(ProcessProperties.JDBC_DRIVER_PATH)).isEqualTo(driverFile);
assertThat(props.nonNullValueAsFile(JDBC_DRIVER_PATH.getKey())).isEqualTo(driverFile);
}

@Test
@@ -156,9 +157,9 @@ public class JdbcSettingsTest {
File driverFile = new File(homeDir, "lib/jdbc/postgresql/pg.jar");
FileUtils.touch(driverFile);

Props props = newProps(JDBC_URL, "jdbc:postgresql://localhost/sonar");
Props props = newProps(JDBC_URL.getKey(), "jdbc:postgresql://localhost/sonar");
underTest.accept(props);
assertThat(props.nonNullValueAsFile(ProcessProperties.JDBC_DRIVER_PATH)).isEqualTo(driverFile);
assertThat(props.nonNullValueAsFile(JDBC_DRIVER_PATH.getKey())).isEqualTo(driverFile);
}

@Test
@@ -166,9 +167,9 @@ public class JdbcSettingsTest {
File driverFile = new File(homeDir, "lib/jdbc/mssql/sqljdbc4.jar");
FileUtils.touch(driverFile);

Props props = newProps(JDBC_URL, "jdbc:sqlserver://localhost/sonar;SelectMethod=Cursor");
Props props = newProps(JDBC_URL.getKey(), "jdbc:sqlserver://localhost/sonar;SelectMethod=Cursor");
underTest.accept(props);
assertThat(props.nonNullValueAsFile(ProcessProperties.JDBC_DRIVER_PATH)).isEqualTo(driverFile);
assertThat(props.nonNullValueAsFile(JDBC_DRIVER_PATH.getKey())).isEqualTo(driverFile);
}

@Test
@@ -215,7 +216,7 @@ public class JdbcSettingsTest {
properties.setProperty(params[i], params[i + 1]);
i++;
}
properties.setProperty(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
properties.setProperty(PATH_HOME.getKey(), homeDir.getAbsolutePath());
return new Props(properties);
}
}

+ 39
- 36
server/sonar-main/src/test/java/org/sonar/application/es/EsInstallationTest.java View File

@@ -26,10 +26,13 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;

public class EsInstallationTest {

@@ -51,8 +54,8 @@ public class EsInstallationTest {
@Test
public void constructor_fails_with_IAE_if_temp_dir_property_is_not_defined() throws IOException {
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), temp.newFolder().getAbsolutePath());

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Property sonar.path.temp is not set");
@@ -63,7 +66,7 @@ public class EsInstallationTest {
@Test
public void constructor_fails_with_IAE_if_data_dir_property_is_not_defined() throws IOException {
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), temp.newFolder().getAbsolutePath());

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Missing property: sonar.path.data");
@@ -75,10 +78,10 @@ public class EsInstallationTest {
public void getHomeDirectory_is_elasticsearch_subdirectory_of_sq_home_directory() throws IOException {
File sqHomeDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), sqHomeDir.getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -91,11 +94,11 @@ public class EsInstallationTest {
File tempDir = temp.newFolder();
File dataDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), sqHomeDir.getAbsolutePath());
props.set(PATH_TEMP.getKey(), tempDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

props.set(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath());
props.set(PATH_DATA.getKey(), dataDir.getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -107,10 +110,10 @@ public class EsInstallationTest {
File sqHomeDir = temp.newFolder();
File logDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), sqHomeDir.getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), logDir.getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -121,10 +124,10 @@ public class EsInstallationTest {
public void conf_directory_is_conf_es_subdirectory_of_sq_temp_directory() throws IOException {
File tempDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), tempDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -135,10 +138,10 @@ public class EsInstallationTest {
public void getExecutable_resolve_executable_for_platform() throws IOException {
File sqHomeDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, sqHomeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), sqHomeDir.getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -153,10 +156,10 @@ public class EsInstallationTest {
public void getLog4j2Properties_is_in_es_conf_directory() throws IOException {
File tempDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), tempDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -167,10 +170,10 @@ public class EsInstallationTest {
public void getElasticsearchYml_is_in_es_conf_directory() throws IOException {
File tempDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), tempDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);

@@ -181,10 +184,10 @@ public class EsInstallationTest {
public void getJvmOptions_is_in_es_conf_directory() throws IOException {
File tempDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_HOME, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_HOME.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), tempDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());

EsInstallation underTest = new EsInstallation(props);


+ 61
- 50
server/sonar-main/src/test/java/org/sonar/application/es/EsSettingsTest.java View File

@@ -32,6 +32,7 @@ import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.application.logging.ListAppender;
import org.sonar.process.ProcessProperties;
import org.sonar.process.ProcessProperties.Property;
import org.sonar.process.Props;
import org.sonar.process.System2;

@@ -39,8 +40,18 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HTTP_PORT;
import static org.sonar.process.ProcessProperties.Property.SEARCH_INITIAL_STATE_TIMEOUT;
import static org.sonar.process.ProcessProperties.Property.SEARCH_MINIMUM_MASTER_NODES;
import static org.sonar.process.ProcessProperties.Property.SEARCH_PORT;

public class EsSettingsTest {

@@ -97,11 +108,11 @@ public class EsSettingsTest {

private Props minimalProps() {
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_HOME, randomAlphanumeric(12));
props.set(ProcessProperties.PATH_DATA, randomAlphanumeric(12));
props.set(ProcessProperties.PATH_TEMP, randomAlphanumeric(12));
props.set(ProcessProperties.PATH_LOGS, randomAlphanumeric(12));
props.set(CLUSTER_NAME, randomAlphanumeric(12));
props.set(PATH_HOME.getKey(), randomAlphanumeric(12));
props.set(PATH_DATA.getKey(), randomAlphanumeric(12));
props.set(PATH_TEMP.getKey(), randomAlphanumeric(12));
props.set(PATH_LOGS.getKey(), randomAlphanumeric(12));
props.set(CLUSTER_NAME.getKey(), randomAlphanumeric(12));
return props;
}

@@ -109,13 +120,13 @@ public class EsSettingsTest {
public void test_default_settings_for_standalone_mode() throws Exception {
File homeDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.SEARCH_PORT, "1234");
props.set(ProcessProperties.SEARCH_HOST, "127.0.0.1");
props.set(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(CLUSTER_NAME, "sonarqube");
props.set(SEARCH_PORT.getKey(), "1234");
props.set(SEARCH_HOST.getKey(), "127.0.0.1");
props.set(PATH_HOME.getKey(), homeDir.getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());
props.set(CLUSTER_NAME.getKey(), "sonarqube");

EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);

@@ -146,15 +157,15 @@ public class EsSettingsTest {
public void test_default_settings_for_cluster_mode() throws Exception {
File homeDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.SEARCH_PORT, "1234");
props.set(ProcessProperties.SEARCH_HOST, "127.0.0.1");
props.set(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.CLUSTER_NAME, "sonarqube-1");
props.set(ProcessProperties.CLUSTER_ENABLED, "true");
props.set(ProcessProperties.CLUSTER_NODE_NAME, "node-1");
props.set(SEARCH_PORT.getKey(), "1234");
props.set(SEARCH_HOST.getKey(), "127.0.0.1");
props.set(PATH_HOME.getKey(), homeDir.getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());
props.set(CLUSTER_NAME.getKey(), "sonarqube-1");
props.set(Property.CLUSTER_ENABLED.getKey(), "true");
props.set(CLUSTER_NODE_NAME.getKey(), "node-1");

EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);

@@ -167,14 +178,14 @@ public class EsSettingsTest {
public void test_node_name_default_for_cluster_mode() throws Exception {
File homeDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.CLUSTER_NAME, "sonarqube");
props.set(ProcessProperties.CLUSTER_ENABLED, "true");
props.set(ProcessProperties.SEARCH_PORT, "1234");
props.set(ProcessProperties.SEARCH_HOST, "127.0.0.1");
props.set(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(CLUSTER_NAME.getKey(), "sonarqube");
props.set(Property.CLUSTER_ENABLED.getKey(), "true");
props.set(SEARCH_PORT.getKey(), "1234");
props.set(SEARCH_HOST.getKey(), "127.0.0.1");
props.set(PATH_HOME.getKey(), homeDir.getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());
EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
Map<String, String> generated = esSettings.build();
assertThat(generated.get("node.name")).startsWith("sonarqube-");
@@ -184,14 +195,14 @@ public class EsSettingsTest {
public void test_node_name_default_for_standalone_mode() throws Exception {
File homeDir = temp.newFolder();
Props props = new Props(new Properties());
props.set(ProcessProperties.CLUSTER_NAME, "sonarqube");
props.set(ProcessProperties.CLUSTER_ENABLED, "false");
props.set(ProcessProperties.SEARCH_PORT, "1234");
props.set(ProcessProperties.SEARCH_HOST, "127.0.0.1");
props.set(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_TEMP, temp.newFolder().getAbsolutePath());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(CLUSTER_NAME.getKey(), "sonarqube");
props.set(Property.CLUSTER_ENABLED.getKey(), "false");
props.set(SEARCH_PORT.getKey(), "1234");
props.set(SEARCH_HOST.getKey(), "127.0.0.1");
props.set(PATH_HOME.getKey(), homeDir.getAbsolutePath());
props.set(PATH_DATA.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_TEMP.getKey(), temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());
EsSettings esSettings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);
Map<String, String> generated = esSettings.build();
assertThat(generated.get("node.name")).isEqualTo("sonarqube");
@@ -216,7 +227,7 @@ public class EsSettingsTest {
@Test
public void set_discovery_settings_if_cluster_is_enabled() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(CLUSTER_SEARCH_HOSTS, "1.2.3.4:9000,1.2.3.5:8080");
props.set(CLUSTER_SEARCH_HOSTS.getKey(), "1.2.3.4:9000,1.2.3.5:8080");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("discovery.zen.ping.unicast.hosts")).isEqualTo("1.2.3.4:9000,1.2.3.5:8080");
@@ -227,7 +238,7 @@ public class EsSettingsTest {
@Test
public void incorrect_values_of_minimum_master_nodes() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "ꝱꝲꝳପ");
props.set(SEARCH_MINIMUM_MASTER_NODES.getKey(), "ꝱꝲꝳପ");

EsSettings underTest = new EsSettings(props, new EsInstallation(props), System2.INSTANCE);

@@ -239,7 +250,7 @@ public class EsSettingsTest {
@Test
public void cluster_is_enabled_with_defined_minimum_master_nodes() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "5");
props.set(SEARCH_MINIMUM_MASTER_NODES.getKey(), "5");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("discovery.zen.minimum_master_nodes")).isEqualTo("5");
@@ -248,7 +259,7 @@ public class EsSettingsTest {
@Test
public void cluster_is_enabled_with_defined_initialTimeout() throws Exception {
Props props = minProps(CLUSTER_ENABLED);
props.set(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "10s");
props.set(SEARCH_INITIAL_STATE_TIMEOUT.getKey(), "10s");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("discovery.initial_state_timeout")).isEqualTo("10s");
@@ -257,7 +268,7 @@ public class EsSettingsTest {
@Test
public void in_standalone_initialTimeout_is_not_overridable() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "10s");
props.set(SEARCH_INITIAL_STATE_TIMEOUT.getKey(), "10s");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("discovery.initial_state_timeout")).isEqualTo("30s");
@@ -266,7 +277,7 @@ public class EsSettingsTest {
@Test
public void in_standalone_minimumMasterNodes_is_not_overridable() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "5");
props.set(SEARCH_MINIMUM_MASTER_NODES.getKey(), "5");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("discovery.zen.minimum_master_nodes")).isEqualTo("1");
@@ -275,7 +286,7 @@ public class EsSettingsTest {
@Test
public void enable_http_connector() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_HTTP_PORT, "9010");
props.set(SEARCH_HTTP_PORT.getKey(), "9010");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("http.port")).isEqualTo("9010");
@@ -286,8 +297,8 @@ public class EsSettingsTest {
@Test
public void enable_http_connector_different_host() throws Exception {
Props props = minProps(CLUSTER_DISABLED);
props.set(ProcessProperties.SEARCH_HTTP_PORT, "9010");
props.set(ProcessProperties.SEARCH_HOST, "127.0.0.2");
props.set(SEARCH_HTTP_PORT.getKey(), "9010");
props.set(SEARCH_HOST.getKey(), "127.0.0.2");
Map<String, String> settings = new EsSettings(props, new EsInstallation(props), System2.INSTANCE).build();

assertThat(settings.get("http.port")).isEqualTo("9010");
@@ -299,8 +310,8 @@ public class EsSettingsTest {
File homeDir = temp.newFolder();
Props props = new Props(new Properties());
ProcessProperties.completeDefaults(props);
props.set(ProcessProperties.PATH_HOME, homeDir.getAbsolutePath());
props.set(ProcessProperties.CLUSTER_ENABLED, Boolean.toString(cluster));
props.set(PATH_HOME.getKey(), homeDir.getAbsolutePath());
props.set(Property.CLUSTER_ENABLED.getKey(), Boolean.toString(cluster));
return props;
}
}

+ 2
- 2
server/sonar-main/src/test/java/org/sonar/application/process/StopRequestWatcherImplTest.java View File

@@ -30,7 +30,6 @@ import org.sonar.application.FileSystem;
import org.sonar.application.Scheduler;
import org.sonar.application.config.AppSettings;
import org.sonar.process.sharedmemoryfile.ProcessCommands;
import org.sonar.process.ProcessProperties;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -40,6 +39,7 @@ import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.Property.ENABLE_STOP_COMMAND;

public class StopRequestWatcherImplTest {

@@ -108,7 +108,7 @@ public class StopRequestWatcherImplTest {
}

private void enableSetting(boolean b) {
when(settings.getProps().valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND)).thenReturn(b);
when(settings.getProps().valueAsBoolean(ENABLE_STOP_COMMAND.getKey())).thenReturn(b);
}

}

+ 112
- 82
server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java View File

@@ -21,9 +21,13 @@ package org.sonar.process;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
* Constants shared by search, web server and app processes.
@@ -31,61 +35,110 @@ import java.util.UUID;
*/
public class ProcessProperties {

public static final String JDBC_URL = "sonar.jdbc.url";
public static final String JDBC_DRIVER_PATH = "sonar.jdbc.driverPath";
public static final String JDBC_MAX_ACTIVE = "sonar.jdbc.maxActive";
public static final String JDBC_MAX_IDLE = "sonar.jdbc.maxIdle";
public static final String JDBC_MIN_IDLE = "sonar.jdbc.minIdle";
public static final String JDBC_MAX_WAIT = "sonar.jdbc.maxWait";
public static final String JDBC_MIN_EVICTABLE_IDLE_TIME_MILLIS = "sonar.jdbc.minEvictableIdleTimeMillis";
public static final String JDBC_TIME_BETWEEN_EVICTION_RUNS_MILLIS = "sonar.jdbc.timeBetweenEvictionRunsMillis";
public static final String JDBC_EMBEDDED_PORT = "sonar.embeddedDatabase.port";

public static final String PATH_DATA = "sonar.path.data";
public static final String PATH_HOME = "sonar.path.home";
public static final String PATH_LOGS = "sonar.path.logs";
public static final String PATH_TEMP = "sonar.path.temp";
public static final String PATH_WEB = "sonar.path.web";

public static final String SEARCH_HOST = "sonar.search.host";
public static final String SEARCH_PORT = "sonar.search.port";
public static final String SEARCH_HTTP_PORT = "sonar.search.httpPort";
public static final String SEARCH_JAVA_OPTS = "sonar.search.javaOpts";
public static final String SEARCH_JAVA_ADDITIONAL_OPTS = "sonar.search.javaAdditionalOpts";
public static final String SEARCH_REPLICAS = "sonar.search.replicas";
public static final String SEARCH_MINIMUM_MASTER_NODES = "sonar.search.minimumMasterNodes";
public static final String SEARCH_INITIAL_STATE_TIMEOUT = "sonar.search.initialStateTimeout";

public static final String WEB_JAVA_OPTS = "sonar.web.javaOpts";
public static final String WEB_JAVA_ADDITIONAL_OPTS = "sonar.web.javaAdditionalOpts";
public static final String WEB_PORT = "sonar.web.port";
public static final String AUTH_JWT_SECRET = "sonar.auth.jwtBase64Hs256Secret";

public static final String CE_JAVA_OPTS = "sonar.ce.javaOpts";
public static final String CE_JAVA_ADDITIONAL_OPTS = "sonar.ce.javaAdditionalOpts";

/**
* Used by Orchestrator to ask for shutdown of monitor process
*/
public static final String ENABLE_STOP_COMMAND = "sonar.enableStopCommand";

public static final String HTTP_PROXY_HOST = "http.proxyHost";
public static final String HTTPS_PROXY_HOST = "https.proxyHost";
public static final String HTTP_PROXY_PORT = "http.proxyPort";
public static final String HTTPS_PROXY_PORT = "https.proxyPort";
public static final String HTTP_PROXY_USER = "http.proxyUser";
public static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";

public static final String CLUSTER_ENABLED = "sonar.cluster.enabled";
public static final String CLUSTER_NODE_TYPE = "sonar.cluster.node.type";
public static final String CLUSTER_SEARCH_HOSTS = "sonar.cluster.search.hosts";
public static final String CLUSTER_HOSTS = "sonar.cluster.hosts";
public static final String CLUSTER_NODE_PORT = "sonar.cluster.node.port";
public static final int CLUSTER_NODE_PORT_DEFAULT_VALUE = 9003;
public static final String CLUSTER_NODE_HOST = "sonar.cluster.node.host";
public static final String CLUSTER_NODE_NAME = "sonar.cluster.node.name";
public static final String CLUSTER_NAME = "sonar.cluster.name";
public static final String CLUSTER_WEB_STARTUP_LEADER = "sonar.cluster.web.startupLeader";
public enum Property {
JDBC_URL("sonar.jdbc.url"),
JDBC_USERNAME("sonar.jdbc.username", ""),
JDBC_PASSWORD("sonar.jdbc.password", ""),
JDBC_DRIVER_PATH("sonar.jdbc.driverPath"),
JDBC_MAX_ACTIVE("sonar.jdbc.maxActive", "60"),
JDBC_MAX_IDLE("sonar.jdbc.maxIdle", "5"),
JDBC_MIN_IDLE("sonar.jdbc.minIdle", "2"),
JDBC_MAX_WAIT("sonar.jdbc.maxWait", "5000"),
JDBC_MIN_EVICTABLE_IDLE_TIME_MILLIS("sonar.jdbc.minEvictableIdleTimeMillis", "600000"),
JDBC_TIME_BETWEEN_EVICTION_RUNS_MILLIS("sonar.jdbc.timeBetweenEvictionRunsMillis", "30000"),
JDBC_EMBEDDED_PORT("sonar.embeddedDatabase.port"),

PATH_DATA("sonar.path.data", "data"),
PATH_HOME("sonar.path.home"),
PATH_LOGS("sonar.path.logs", "logs"),
PATH_TEMP("sonar.path.temp", "temp"),
PATH_WEB("sonar.path.web", "web"),

SEARCH_HOST("sonar.search.host", InetAddress.getLoopbackAddress().getHostAddress()),
SEARCH_PORT("sonar.search.port", "9001"),
SEARCH_HTTP_PORT("sonar.search.httpPort"),
SEARCH_JAVA_OPTS("sonar.search.javaOpts", "-Xms512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError"),
SEARCH_JAVA_ADDITIONAL_OPTS("sonar.search.javaAdditionalOpts", ""),
SEARCH_REPLICAS("sonar.search.replicas"),
SEARCH_MINIMUM_MASTER_NODES("sonar.search.minimumMasterNodes"),
SEARCH_INITIAL_STATE_TIMEOUT("sonar.search.initialStateTimeout"),

WEB_JAVA_OPTS("sonar.web.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError"),
WEB_JAVA_ADDITIONAL_OPTS("sonar.web.javaAdditionalOpts", ""),
WEB_PORT("sonar.web.port"),

CE_JAVA_OPTS("sonar.ce.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError"),
CE_JAVA_ADDITIONAL_OPTS("sonar.ce.javaAdditionalOpts", ""),

HTTP_PROXY_HOST("http.proxyHost"),
HTTPS_PROXY_HOST("https.proxyHost"),
HTTP_PROXY_PORT("http.proxyPort"),
HTTPS_PROXY_PORT("https.proxyPort"),
HTTP_PROXY_USER("http.proxyUser"),
HTTP_PROXY_PASSWORD("http.proxyPassword"),
HTTP_NON_PROXY_HOSTS("http.nonProxyHosts"),
HTTP_AUTH_NLM_DOMAN("http.auth.ntlm.domain"),
SOCKS_PROXY_HOST("socksProxyHost"),
SOCKS_PROXY_PORT("socksProxyPort"),

CLUSTER_ENABLED("sonar.cluster.enabled", "false"),
CLUSTER_NODE_TYPE("sonar.cluster.node.type"),
CLUSTER_SEARCH_HOSTS("sonar.cluster.search.hosts"),
CLUSTER_HOSTS("sonar.cluster.hosts"),
CLUSTER_NODE_PORT("sonar.cluster.node.port", "9003"),
CLUSTER_NODE_HOST("sonar.cluster.node.host"),
CLUSTER_NODE_NAME("sonar.cluster.node.name", "sonarqube-" + UUID.randomUUID().toString()),
CLUSTER_NAME("sonar.cluster.name", "sonarqube"),
CLUSTER_WEB_STARTUP_LEADER("sonar.cluster.web.startupLeader"),

AUTH_JWT_SECRET("sonar.auth.jwtBase64Hs256Secret"),
SONAR_WEB_SSO_ENABLE("sonar.web.sso.enable", "false"),
SONAR_WEB_SSO_LOGIN_HEADER("sonar.web.sso.loginHeader", "X-Forwarded-Login"),
SONAR_WEB_SSO_NAME_HEADER("sonar.web.sso.nameHeader", "X-Forwarded-Name"),
SONAR_WEB_SSO_EMAIL_HEADER("sonar.web.sso.emailHeader", "X-Forwarded-Email"),
SONAR_WEB_SSO_GROUPS_HEADER("sonar.web.sso.groupsHeader", "X-Forwarded-Groups"),
SONAR_WEB_SSO_REFRESH_INTERVAL_IN_MINUTES("sonar.web.sso.refreshIntervalInMinutes", "5"),
SONAR_SECURITY_REALM("sonar.security.realm"),
SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE("sonar.authenticator.ignoreStartupFailure", "false"),

SONAR_TELEMETRY_ENABLE("sonar.telemetry.enable", "true"),
SONAR_TELEMETRY_URL("sonar.telemetry.url", "https://telemetry.sonarsource.com/sonarqube"),
SONAR_TELEMETRY_FREQUENCY_IN_SECONDS("sonar.telemetry.frequencyInSeconds", "21600"),

SONAR_UPDATECENTER_ACTIVATE("sonar.updatecenter.activate", "true"),

SONARCLOUD_ENABLED("sonar.sonarcloud.enabled", "false"),

/**
* Used by Orchestrator to ask for shutdown of monitor process
*/
ENABLE_STOP_COMMAND("sonar.enableStopCommand");

private final String key;
private final String defaultValue;

Property(String key, @Nullable String defaultValue) {
this.key = key;
this.defaultValue = defaultValue;
}

Property(String key) {
this(key, null);
}

public String getKey() {
return key;
}

public String getDefaultValue() {
Objects.requireNonNull(defaultValue, "There's no default value on this property");
return defaultValue;
}

public boolean hasDefaultValue() {
return defaultValue != null;
}
}

private ProcessProperties() {
// only static stuff
@@ -97,37 +150,14 @@ public class ProcessProperties {
props.setDefault(entry.getKey().toString(), entry.getValue().toString());
}

fixPortIfZero(props, SEARCH_HOST, SEARCH_PORT);
fixPortIfZero(props, Property.SEARCH_HOST.getKey(), Property.SEARCH_PORT.getKey());
}

public static Properties defaults() {
Properties defaults = new Properties();
defaults.put(SEARCH_HOST, InetAddress.getLoopbackAddress().getHostAddress());
defaults.put(SEARCH_PORT, "9001");
defaults.put(SEARCH_JAVA_OPTS, "-Xms512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError");
defaults.put(SEARCH_JAVA_ADDITIONAL_OPTS, "");

defaults.put(PATH_DATA, "data");
defaults.put(PATH_LOGS, "logs");
defaults.put(PATH_TEMP, "temp");
defaults.put(PATH_WEB, "web");

defaults.put(WEB_JAVA_OPTS, "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError");
defaults.put(WEB_JAVA_ADDITIONAL_OPTS, "");
defaults.put(CE_JAVA_OPTS, "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError");
defaults.put(CE_JAVA_ADDITIONAL_OPTS, "");
defaults.put(JDBC_MAX_ACTIVE, "60");
defaults.put(JDBC_MAX_IDLE, "5");
defaults.put(JDBC_MIN_IDLE, "2");
defaults.put(JDBC_MAX_WAIT, "5000");
defaults.put(JDBC_MIN_EVICTABLE_IDLE_TIME_MILLIS, "600000");
defaults.put(JDBC_TIME_BETWEEN_EVICTION_RUNS_MILLIS, "30000");

defaults.put(CLUSTER_ENABLED, "false");
defaults.put(CLUSTER_NAME, "sonarqube");
defaults.put(CLUSTER_NODE_PORT, Integer.toString(CLUSTER_NODE_PORT_DEFAULT_VALUE));
defaults.put(CLUSTER_NODE_NAME, "sonarqube-" + UUID.randomUUID().toString());

defaults.putAll(Arrays.stream(Property.values())
.filter(Property::hasDefaultValue)
.collect(Collectors.toMap(Property::getKey, Property::getDefaultValue)));
return defaults;
}


+ 2
- 2
server/sonar-process/src/main/java/org/sonar/process/cluster/hz/HazelcastMemberBuilder.java View File

@@ -30,13 +30,13 @@ import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.cluster.NodeType;
import org.sonar.process.cluster.hz.HazelcastMember.Attribute;

import static java.lang.String.format;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;

public class HazelcastMemberBuilder {

@@ -83,7 +83,7 @@ public class HazelcastMemberBuilder {
*/
public HazelcastMemberBuilder setMembers(Collection<String> c) {
this.members = c.stream()
.map(host -> host.contains(":") ? host : format("%s:%d", host, ProcessProperties.CLUSTER_NODE_PORT_DEFAULT_VALUE))
.map(host -> host.contains(":") ? host : format("%s:%s", host, CLUSTER_NODE_PORT.getDefaultValue()))
.collect(Collectors.toList());
return this;
}

+ 2
- 2
server/sonar-process/src/main/java/org/sonar/process/logging/LogbackHelper.java View File

@@ -45,11 +45,11 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.sonar.process.MessageException;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static java.lang.String.format;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

/**
* Helps to configure Logback in a programmatic way, without using XML.
@@ -241,7 +241,7 @@ public class LogbackHelper extends AbstractLogHelper {
public RollingPolicy createRollingPolicy(Context ctx, Props props, String filenamePrefix) {
String rollingPolicy = props.value(ROLLING_POLICY_PROPERTY, "time:yyyy-MM-dd");
int maxFiles = props.valueAsInt(MAX_FILES_PROPERTY, 7);
File logsDir = props.nonNullValueAsFile(ProcessProperties.PATH_LOGS);
File logsDir = props.nonNullValueAsFile(PATH_LOGS.getKey());

if (rollingPolicy.startsWith("time:")) {
return new TimeRollingPolicy(ctx, filenamePrefix, logsDir, maxFiles, StringUtils.substringAfter(rollingPolicy, "time:"));

+ 2
- 0
server/sonar-process/src/test/java/org/sonar/process/ProcessPropertiesTest.java View File

@@ -35,6 +35,8 @@ public class ProcessPropertiesTest {

assertThat(props.value("sonar.search.javaOpts")).contains("-Xmx");
assertThat(props.valueAsInt("sonar.jdbc.maxActive")).isEqualTo(60);
assertThat(props.valueAsBoolean("sonar.sonarcloud.enabled")).isEqualTo(false);
assertThat(props.valueAsBoolean("sonar.updatecenter.activate")).isEqualTo(true);
}

@Test

+ 3
- 3
server/sonar-process/src/test/java/org/sonar/process/cluster/hz/HazelcastMemberBuilderTest.java View File

@@ -27,11 +27,11 @@ import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.sonar.process.NetworkUtilsImpl;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.cluster.NodeType;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;

public class HazelcastMemberBuilderTest {

@@ -72,8 +72,8 @@ public class HazelcastMemberBuilderTest {
underTest.setMembers(asList("foo", "bar:9100", "1.2.3.4"));

assertThat(underTest.getMembers()).containsExactly(
"foo:" + ProcessProperties.CLUSTER_NODE_PORT_DEFAULT_VALUE,
"foo:" + CLUSTER_NODE_PORT.getDefaultValue(),
"bar:9100",
"1.2.3.4:" + ProcessProperties.CLUSTER_NODE_PORT_DEFAULT_VALUE);
"1.2.3.4:" + CLUSTER_NODE_PORT.getDefaultValue());
}
}

+ 17
- 17
server/sonar-process/src/test/java/org/sonar/process/logging/LogbackHelperTest.java View File

@@ -52,13 +52,13 @@ import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.sonar.process.MessageException;
import org.sonar.process.ProcessId;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.logging.RootLoggerConfig.newRootLoggerConfigBuilder;

@RunWith(DataProviderRunner.class)
@@ -75,7 +75,7 @@ public class LogbackHelperTest {
@Before
public void setUp() throws Exception {
File dir = temp.newFolder();
props.set(ProcessProperties.PATH_LOGS, dir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), dir.getAbsolutePath());
}

@After
@@ -88,12 +88,11 @@ public class LogbackHelperTest {
assertThat(underTest.getRootContext()).isNotNull();
}


@Test
public void buildLogPattern_puts_process_key_as_process_id() {
String pattern = underTest.buildLogPattern(newRootLoggerConfigBuilder()
.setProcessId(ProcessId.ELASTICSEARCH)
.build());
.setProcessId(ProcessId.ELASTICSEARCH)
.build());

assertThat(pattern).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level es[][%logger{20}] %msg%n");
}
@@ -102,10 +101,10 @@ public class LogbackHelperTest {
public void buildLogPattern_puts_threadIdFieldPattern_from_RootLoggerConfig_non_null() {
String threadIdFieldPattern = RandomStringUtils.randomAlphabetic(5);
String pattern = underTest.buildLogPattern(
newRootLoggerConfigBuilder()
.setProcessId(ProcessId.APP)
.setThreadIdFieldPattern(threadIdFieldPattern)
.build());
newRootLoggerConfigBuilder()
.setProcessId(ProcessId.APP)
.setThreadIdFieldPattern(threadIdFieldPattern)
.build());

assertThat(pattern).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level app[" + threadIdFieldPattern + "][%logger{20}] %msg%n");
}
@@ -113,9 +112,9 @@ public class LogbackHelperTest {
@Test
public void buildLogPattern_does_not_put_threadIdFieldPattern_from_RootLoggerConfig_is_null() {
String pattern = underTest.buildLogPattern(
newRootLoggerConfigBuilder()
.setProcessId(ProcessId.COMPUTE_ENGINE)
.build());
newRootLoggerConfigBuilder()
.setProcessId(ProcessId.COMPUTE_ENGINE)
.build());

assertThat(pattern).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level ce[][%logger{20}] %msg%n");
}
@@ -123,13 +122,14 @@ public class LogbackHelperTest {
@Test
public void buildLogPattern_does_not_put_threadIdFieldPattern_from_RootLoggerConfig_is_empty() {
String pattern = underTest.buildLogPattern(
newRootLoggerConfigBuilder()
.setProcessId(ProcessId.WEB_SERVER)
.setThreadIdFieldPattern("")
.build());
newRootLoggerConfigBuilder()
.setProcessId(ProcessId.WEB_SERVER)
.setThreadIdFieldPattern("")
.build());

assertThat(pattern).isEqualTo("%d{yyyy.MM.dd HH:mm:ss} %-5level web[][%logger{20}] %msg%n");
}

@Test
public void enableJulChangePropagation() {
LoggerContext ctx = underTest.getRootContext();
@@ -255,7 +255,7 @@ public class LogbackHelperTest {
assertThat(rollingPolicy.getMaxIndex()).isEqualTo(20);
assertThat(rollingPolicy.getFileNamePattern()).endsWith("sonar.%i.log");
SizeBasedTriggeringPolicy triggeringPolicy = (SizeBasedTriggeringPolicy) fileAppender.getTriggeringPolicy();
FileSize maxFileSize = (FileSize)FieldUtils.readField(triggeringPolicy, "maxFileSize", true);
FileSize maxFileSize = (FileSize) FieldUtils.readField(triggeringPolicy, "maxFileSize", true);
assertThat(maxFileSize.getSize()).isEqualTo(1024L * 1024);
}


+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/app/EmbeddedTomcat.java View File

@@ -25,10 +25,10 @@ import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.sonar.api.utils.log.Loggers;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static org.sonar.core.util.FileUtils.deleteQuietly;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;

class EmbeddedTomcat {

@@ -89,7 +89,7 @@ class EmbeddedTomcat {
}

private File tomcatBasedir() {
return new File(props.value(ProcessProperties.PATH_TEMP), "tc");
return new File(props.value(PATH_TEMP.getKey()), "tc");
}

void terminate() {

+ 4
- 3
server/sonar-server/src/main/java/org/sonar/server/app/TomcatContexts.java View File

@@ -28,10 +28,11 @@ import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.io.FileUtils;
import org.sonar.api.utils.MessageException;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static java.lang.String.format;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;

/**
* Configures Tomcat contexts:
@@ -57,7 +58,7 @@ public class TomcatContexts {
}

public StandardContext configure(Tomcat tomcat, Props props) {
addStaticDir(tomcat, getContextPath(props) + "/deploy", new File(props.nonNullValueAsFile(ProcessProperties.PATH_DATA), WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR));
addStaticDir(tomcat, getContextPath(props) + "/deploy", new File(props.nonNullValueAsFile(PATH_DATA.getKey()), WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR));

StandardContext webapp = addContext(tomcat, getContextPath(props), webappDir(props));
for (Map.Entry<Object, Object> entry : props.rawProperties().entrySet()) {
@@ -115,7 +116,7 @@ public class TomcatContexts {
}

private static File webappDir(Props props) {
return new File(props.value(ProcessProperties.PATH_HOME), "web");
return new File(props.value(PATH_HOME.getKey()), "web");
}

static class Fs {

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/authentication/JwtSerializer.java View File

@@ -45,7 +45,7 @@ import org.sonar.server.authentication.event.AuthenticationException;
import static com.google.common.base.Preconditions.checkNotNull;
import static io.jsonwebtoken.impl.crypto.MacProvider.generateKey;
import static java.util.Objects.requireNonNull;
import static org.sonar.process.ProcessProperties.AUTH_JWT_SECRET;
import static org.sonar.process.ProcessProperties.Property.AUTH_JWT_SECRET;

/**
* This class can be used to encode or decode a JWT token
@@ -74,7 +74,7 @@ public class JwtSerializer implements Startable {

@Override
public void start() {
Optional<String> encodedKey = config.get(AUTH_JWT_SECRET);
Optional<String> encodedKey = config.get(AUTH_JWT_SECRET.getKey());
if (encodedKey.isPresent()) {
this.secretKey = decodeSecretKeyProperty(encodedKey.get());
} else {

+ 22
- 32
server/sonar-server/src/main/java/org/sonar/server/authentication/SsoAuthenticator.java View File

@@ -23,6 +23,7 @@ import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
@@ -40,12 +41,19 @@ import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.user.UserDto;
import org.sonar.process.ProcessProperties;
import org.sonar.server.authentication.event.AuthenticationEvent;
import org.sonar.server.authentication.event.AuthenticationEvent.Source;
import org.sonar.server.authentication.event.AuthenticationException;
import org.sonar.server.exceptions.BadRequestException;

import static org.apache.commons.lang.time.DateUtils.addMinutes;
import static org.sonar.process.ProcessProperties.Property.SONAR_WEB_SSO_EMAIL_HEADER;
import static org.sonar.process.ProcessProperties.Property.SONAR_WEB_SSO_ENABLE;
import static org.sonar.process.ProcessProperties.Property.SONAR_WEB_SSO_GROUPS_HEADER;
import static org.sonar.process.ProcessProperties.Property.SONAR_WEB_SSO_LOGIN_HEADER;
import static org.sonar.process.ProcessProperties.Property.SONAR_WEB_SSO_NAME_HEADER;
import static org.sonar.process.ProcessProperties.Property.SONAR_WEB_SSO_REFRESH_INTERVAL_IN_MINUTES;
import static org.sonar.server.user.ExternalIdentity.SQ_AUTHORITY;

public class SsoAuthenticator implements Startable {
@@ -54,31 +62,14 @@ public class SsoAuthenticator implements Startable {

private static final Splitter COMA_SPLITTER = Splitter.on(",").trimResults().omitEmptyStrings();

private static final String ENABLE_PARAM = "sonar.web.sso.enable";

private static final String LOGIN_HEADER_PARAM = "sonar.web.sso.loginHeader";
private static final String LOGIN_HEADER_DEFAULT_VALUE = "X-Forwarded-Login";

private static final String NAME_HEADER_PARAM = "sonar.web.sso.nameHeader";
private static final String NAME_HEADER_DEFAULT_VALUE = "X-Forwarded-Name";

private static final String EMAIL_HEADER_PARAM = "sonar.web.sso.emailHeader";
private static final String EMAIL_HEADER_DEFAULT_VALUE = "X-Forwarded-Email";

private static final String GROUPS_HEADER_PARAM = "sonar.web.sso.groupsHeader";
private static final String GROUPS_HEADER_DEFAULT_VALUE = "X-Forwarded-Groups";

private static final String REFRESH_INTERVAL_PARAM = "sonar.web.sso.refreshIntervalInMinutes";
private static final String REFRESH_INTERVAL_DEFAULT_VALUE = "5";

private static final String LAST_REFRESH_TIME_TOKEN_PARAM = "ssoLastRefreshTime";

private static final Map<String, String> DEFAULT_VALUES_BY_SETTING_KEYS = ImmutableMap.of(
LOGIN_HEADER_PARAM, LOGIN_HEADER_DEFAULT_VALUE,
NAME_HEADER_PARAM, NAME_HEADER_DEFAULT_VALUE,
EMAIL_HEADER_PARAM, EMAIL_HEADER_DEFAULT_VALUE,
GROUPS_HEADER_PARAM, GROUPS_HEADER_DEFAULT_VALUE,
REFRESH_INTERVAL_PARAM, REFRESH_INTERVAL_DEFAULT_VALUE);
private static final EnumSet<ProcessProperties.Property> SETTINGS = EnumSet.of(
SONAR_WEB_SSO_LOGIN_HEADER,
SONAR_WEB_SSO_NAME_HEADER,
SONAR_WEB_SSO_EMAIL_HEADER,
SONAR_WEB_SSO_GROUPS_HEADER,
SONAR_WEB_SSO_REFRESH_INTERVAL_IN_MINUTES);

private final System2 system2;
private final Configuration config;
@@ -100,11 +91,10 @@ public class SsoAuthenticator implements Startable {

@Override
public void start() {
if (config.getBoolean(ENABLE_PARAM).orElse(false)) {
if (config.getBoolean(SONAR_WEB_SSO_ENABLE.getKey()).orElse(false)) {
LOG.info("SSO Authentication enabled");
enabled = true;
DEFAULT_VALUES_BY_SETTING_KEYS.entrySet()
.forEach(entry -> settingsByKey.put(entry.getKey(), config.get(entry.getKey()).orElse(DEFAULT_VALUES_BY_SETTING_KEYS.get(entry.getKey()))));
SETTINGS.forEach(entry -> settingsByKey.put(entry.getKey(), config.get(entry.getKey()).orElse(entry.getDefaultValue())));
}
}

@@ -129,7 +119,7 @@ public class SsoAuthenticator implements Startable {
return Optional.empty();
}
Map<String, String> headerValuesByNames = getHeaders(request);
String login = getHeaderValue(headerValuesByNames, LOGIN_HEADER_PARAM);
String login = getHeaderValue(headerValuesByNames, SONAR_WEB_SSO_LOGIN_HEADER.getKey());
if (login == null) {
return Optional.empty();
}
@@ -150,7 +140,7 @@ public class SsoAuthenticator implements Startable {
return Optional.empty();
}
Date now = new Date(system2.now());
int refreshIntervalInMinutes = Integer.parseInt(settingsByKey.get(REFRESH_INTERVAL_PARAM));
int refreshIntervalInMinutes = Integer.parseInt(settingsByKey.get(SONAR_WEB_SSO_REFRESH_INTERVAL_IN_MINUTES.getKey()));
Long lastFreshTime = (Long) token.get().getProperties().get(LAST_REFRESH_TIME_TOKEN_PARAM);
if (lastFreshTime == null || now.after(addMinutes(new Date(lastFreshTime), refreshIntervalInMinutes))) {
return Optional.empty();
@@ -159,15 +149,15 @@ public class SsoAuthenticator implements Startable {
}

private UserDto doAuthenticate(Map<String, String> headerValuesByNames, String login) {
String name = getHeaderValue(headerValuesByNames, NAME_HEADER_PARAM);
String email = getHeaderValue(headerValuesByNames, EMAIL_HEADER_PARAM);
String name = getHeaderValue(headerValuesByNames, SONAR_WEB_SSO_NAME_HEADER.getKey());
String email = getHeaderValue(headerValuesByNames, SONAR_WEB_SSO_EMAIL_HEADER.getKey());
UserIdentity.Builder userIdentityBuilder = UserIdentity.builder()
.setLogin(login)
.setName(name == null ? login : name)
.setEmail(email)
.setProviderLogin(login);
if (hasHeader(headerValuesByNames, GROUPS_HEADER_PARAM)) {
String groupsValue = getHeaderValue(headerValuesByNames, GROUPS_HEADER_PARAM);
if (hasHeader(headerValuesByNames, SONAR_WEB_SSO_GROUPS_HEADER.getKey())) {
String groupsValue = getHeaderValue(headerValuesByNames, SONAR_WEB_SSO_GROUPS_HEADER.getKey());
userIdentityBuilder.setGroups(groupsValue == null ? Collections.emptySet() : new HashSet<>(COMA_SPLITTER.splitToList(groupsValue)));
}
return userIdentityAuthenticator.authenticate(userIdentityBuilder.build(), new SsoIdentityProvider(), Source.sso());

+ 3
- 2
server/sonar-server/src/main/java/org/sonar/server/badge/ws/ProjectBadgesWsModule.java View File

@@ -20,9 +20,10 @@
package org.sonar.server.badge.ws;

import org.sonar.api.config.Configuration;
import org.sonar.core.config.WebConstants;
import org.sonar.core.platform.Module;

import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;

public class ProjectBadgesWsModule extends Module {

private final Configuration config;
@@ -33,7 +34,7 @@ public class ProjectBadgesWsModule extends Module {

@Override
protected void configureModule() {
if (!config.getBoolean(WebConstants.SONARCLOUD_ENABLED).orElse(false)) {
if (!config.getBoolean(SONARCLOUD_ENABLED.getKey()).orElse(false)) {
return;
}
add(

+ 11
- 10
server/sonar-server/src/main/java/org/sonar/server/es/EsClientProvider.java View File

@@ -43,13 +43,14 @@ import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.process.cluster.NodeType;
import org.sonar.process.ProcessProperties;

import static java.util.Collections.unmodifiableList;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.SEARCH_PORT;
import static org.sonar.process.cluster.NodeType.SEARCH;

@ComputeEngineSide
@@ -65,19 +66,19 @@ public class EsClientProvider extends ProviderAdapter {
Settings.Builder esSettings = Settings.builder();

// mandatory property defined by bootstrap process
esSettings.put("cluster.name", config.get(CLUSTER_NAME).get());
esSettings.put("cluster.name", config.get(CLUSTER_NAME.getKey()).get());

boolean clusterEnabled = config.getBoolean(CLUSTER_ENABLED).orElse(false);
boolean searchNode = !clusterEnabled || SEARCH.equals(NodeType.parse(config.get(CLUSTER_NODE_TYPE).orElse(null)));
boolean clusterEnabled = config.getBoolean(CLUSTER_ENABLED.getKey()).orElse(false);
boolean searchNode = !clusterEnabled || SEARCH.equals(NodeType.parse(config.get(CLUSTER_NODE_TYPE.getKey()).orElse(null)));
final TransportClient nativeClient = new MinimalTransportClient(esSettings.build());
if (clusterEnabled && !searchNode) {
esSettings.put("client.transport.sniff", true);
Arrays.stream(config.getStringArray(CLUSTER_SEARCH_HOSTS))
Arrays.stream(config.getStringArray(CLUSTER_SEARCH_HOSTS.getKey()))
.map(HostAndPort::fromString)
.forEach(h -> addHostToClient(h, nativeClient));
LOGGER.info("Connected to remote Elasticsearch: [{}]", displayedAddresses(nativeClient));
} else {
HostAndPort host = HostAndPort.fromParts(config.get(ProcessProperties.SEARCH_HOST).get(), config.getInt(ProcessProperties.SEARCH_PORT).get());
HostAndPort host = HostAndPort.fromParts(config.get(SEARCH_HOST.getKey()).get(), config.getInt(SEARCH_PORT.getKey()).get());
addHostToClient(host, nativeClient);
LOGGER.info("Connected to local Elasticsearch: [{}]", displayedAddresses(nativeClient));
}

+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java View File

@@ -32,14 +32,14 @@ import org.apache.commons.lang.StringUtils;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.sonar.api.config.Configuration;
import org.sonar.process.ProcessProperties;
import org.sonar.server.permission.index.AuthorizationTypeSupport;

import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static java.lang.String.valueOf;
import static java.util.Objects.requireNonNull;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.SEARCH_REPLICAS;
import static org.sonar.server.es.DefaultIndexSettings.ANALYZER;
import static org.sonar.server.es.DefaultIndexSettings.FIELDDATA_ENABLED;
import static org.sonar.server.es.DefaultIndexSettings.FIELD_FIELDDATA;
@@ -71,10 +71,10 @@ public class NewIndex {
settings.put("index.refresh_interval", refreshInterval(settingsConfiguration));

Configuration config = settingsConfiguration.getConfiguration();
boolean clusterMode = config.getBoolean(CLUSTER_ENABLED).orElse(false);
boolean clusterMode = config.getBoolean(CLUSTER_ENABLED.getKey()).orElse(false);
int shards = config.getInt(format("sonar.search.%s.shards", indexName))
.orElse(settingsConfiguration.getDefaultNbOfShards());
int replicas = clusterMode ? config.getInt(ProcessProperties.SEARCH_REPLICAS).orElse(1) : 0;
int replicas = clusterMode ? config.getInt(SEARCH_REPLICAS.getKey()).orElse(1) : 0;

settings.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, shards);
settings.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, replicas);

+ 8
- 8
server/sonar-server/src/main/java/org/sonar/server/health/NodeHealthProviderImpl.java View File

@@ -28,9 +28,9 @@ import org.sonar.process.cluster.health.NodeHealth;
import org.sonar.process.cluster.health.NodeHealthProvider;

import static java.lang.String.format;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;
import static org.sonar.process.cluster.health.NodeDetails.newNodeDetailsBuilder;
import static org.sonar.process.cluster.health.NodeHealth.newNodeHealthBuilder;

@@ -52,19 +52,19 @@ public class NodeHealthProviderImpl implements NodeHealthProvider {
}

private static String computeName(Configuration configuration) {
return configuration.get(CLUSTER_NODE_NAME)
.orElseThrow(missingPropertyISE(CLUSTER_NODE_NAME));
return configuration.get(CLUSTER_NODE_NAME.getKey())
.orElseThrow(missingPropertyISE(CLUSTER_NODE_NAME.getKey()));
}

private static String computeHost(Configuration configuration, NetworkUtils networkUtils) {
return configuration.get(CLUSTER_NODE_HOST)
return configuration.get(CLUSTER_NODE_HOST.getKey())
.filter(s -> !s.isEmpty())
.orElseGet(networkUtils::getHostname);
}

private static int computePort(Configuration configuration) {
return configuration.getInt(CLUSTER_NODE_PORT)
.orElseThrow(missingPropertyISE(CLUSTER_NODE_PORT));
return configuration.getInt(CLUSTER_NODE_PORT.getKey())
.orElseThrow(missingPropertyISE(CLUSTER_NODE_PORT.getKey()));
}

private static Supplier<IllegalStateException> missingPropertyISE(String propertyName) {

+ 7
- 4
server/sonar-server/src/main/java/org/sonar/server/platform/ServerFileSystemImpl.java View File

@@ -24,9 +24,12 @@ import org.picocontainer.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.process.ProcessProperties;
import org.sonar.server.app.TomcatContexts;

import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;

public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.platform.ServerFileSystem, Startable {

private static final Logger LOGGER = Loggers.get(ServerFileSystemImpl.class);
@@ -39,9 +42,9 @@ public class ServerFileSystemImpl implements ServerFileSystem, org.sonar.api.pla
private final File editionUninstallDir;

public ServerFileSystemImpl(Configuration config) {
this.homeDir = new File(config.get(ProcessProperties.PATH_HOME).get());
this.tempDir = new File(config.get(ProcessProperties.PATH_TEMP).get());
this.dataDir = new File(config.get(ProcessProperties.PATH_DATA).get());
this.homeDir = new File(config.get(PATH_HOME.getKey()).get());
this.tempDir = new File(config.get(PATH_TEMP.getKey()).get());
this.dataDir = new File(config.get(PATH_DATA.getKey()).get());
this.deployDir = new File(this.dataDir, TomcatContexts.WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR);
this.uninstallDir = new File(getTempDir(), "uninstalled-plugins");
this.editionUninstallDir = new File(getTempDir(), "uninstalled-edition-plugins");

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/platform/ServerIdManager.java View File

@@ -39,6 +39,7 @@ import static com.google.common.base.Preconditions.checkState;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.api.CoreProperties.SERVER_ID;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.server.property.InternalProperties.SERVER_ID_CHECKSUM;

public class ServerIdManager implements Startable {
@@ -132,7 +133,7 @@ public class ServerIdManager implements Startable {
}

private String computeChecksum(String serverId) {
String jdbcUrl = config.get("sonar.jdbc.url").orElseThrow(() -> new IllegalStateException("Missing JDBC URL"));
String jdbcUrl = config.get(JDBC_URL.getKey()).orElseThrow(() -> new IllegalStateException("Missing JDBC URL"));
return ServerIdChecksum.of(serverId, jdbcUrl);
}


+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/platform/ServerLogging.java View File

@@ -31,11 +31,11 @@ import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.Database;
import org.sonar.process.ProcessProperties;
import org.sonar.process.logging.LogbackHelper;
import org.sonar.server.app.ServerProcessLogging;

import static org.sonar.api.utils.log.LoggerLevel.TRACE;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

@ServerSide
@ComputeEngineSide
@@ -89,7 +89,7 @@ public class ServerLogging implements Startable {
* The directory that contains log files. May not exist.
*/
public File getLogsDir() {
return new File(config.get(ProcessProperties.PATH_LOGS).get());
return new File(config.get(PATH_LOGS.getKey()).get());
}

}

+ 1
- 1
server/sonar-server/src/main/java/org/sonar/server/platform/WebServer.java View File

@@ -27,7 +27,7 @@ import org.sonar.api.server.ServerSide;
public interface WebServer {

/**
* WebServer is standalone when property {@link org.sonar.process.ProcessProperties#CLUSTER_ENABLED} is {@code false} or
* WebServer is standalone when property {@link org.sonar.process.ProcessProperties.Property#CLUSTER_ENABLED} is {@code false} or
* undefined.
*/
boolean isStandalone();

+ 4
- 4
server/sonar-server/src/main/java/org/sonar/server/platform/WebServerImpl.java View File

@@ -22,8 +22,8 @@ package org.sonar.server.platform;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Loggers;

import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_WEB_STARTUP_LEADER;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_WEB_STARTUP_LEADER;

public class WebServerImpl implements WebServer {

@@ -31,9 +31,9 @@ public class WebServerImpl implements WebServer {
private final boolean startupLeader;

public WebServerImpl(Configuration config) {
this.clusterEnabled = config.getBoolean(CLUSTER_ENABLED).orElse(false);
this.clusterEnabled = config.getBoolean(CLUSTER_ENABLED.getKey()).orElse(false);
if (this.clusterEnabled) {
this.startupLeader = config.getBoolean(CLUSTER_WEB_STARTUP_LEADER).orElse(false);
this.startupLeader = config.getBoolean(CLUSTER_WEB_STARTUP_LEADER.getKey()).orElse(false);
Loggers.get(WebServerImpl.class).info("Cluster enabled (startup {})", startupLeader ? "leader" : "follower");
} else {
this.startupLeader = true;

+ 12
- 15
server/sonar-server/src/main/java/org/sonar/server/platform/db/EmbeddedDatabase.java View File

@@ -23,7 +23,6 @@ import java.io.File;
import java.net.InetAddress;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.commons.lang.StringUtils;
import org.h2.Driver;
import org.h2.tools.Server;
import org.picocontainer.Startable;
@@ -35,13 +34,11 @@ import org.sonar.api.utils.log.Loggers;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.api.database.DatabaseProperties.PROP_EMBEDDED_PORT;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD_DEFAULT_VALUE;
import static org.sonar.api.database.DatabaseProperties.PROP_URL;
import static org.sonar.api.database.DatabaseProperties.PROP_USER;
import static org.sonar.api.database.DatabaseProperties.PROP_USER_DEFAULT_VALUE;
import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.JDBC_EMBEDDED_PORT;
import static org.sonar.process.ProcessProperties.Property.JDBC_PASSWORD;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.JDBC_USERNAME;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;

public class EmbeddedDatabase implements Startable {
private static final Logger LOG = Loggers.get(EmbeddedDatabase.class);
@@ -57,7 +54,7 @@ public class EmbeddedDatabase implements Startable {

@Override
public void start() {
File dbHome = new File(getRequiredSetting(PATH_DATA));
File dbHome = new File(getRequiredSetting(PATH_DATA.getKey()));
if (!dbHome.exists()) {
dbHome.mkdirs();
}
@@ -66,10 +63,10 @@ public class EmbeddedDatabase implements Startable {
}

private void startServer(File dbHome) {
String url = getRequiredSetting(PROP_URL);
String port = getRequiredSetting(PROP_EMBEDDED_PORT);
String user = getSetting(PROP_USER, PROP_USER_DEFAULT_VALUE);
String password = getSetting(PROP_PASSWORD, PROP_PASSWORD_DEFAULT_VALUE);
String url = getRequiredSetting(JDBC_URL.getKey());
String port = getRequiredSetting(JDBC_EMBEDDED_PORT.getKey());
String user = getSetting(JDBC_USERNAME.getKey());
String password = getSetting(JDBC_PASSWORD.getKey());
try {
// Db is used only by web server and compute engine. No need
// to make it accessible from outside.
@@ -106,8 +103,8 @@ public class EmbeddedDatabase implements Startable {
return value;
}

private String getSetting(String name, String defaultValue) {
return StringUtils.defaultIfBlank(config.get(name).orElse(""), defaultValue);
private String getSetting(String name) {
return config.get(name).orElse("");
}

private static void createDatabase(File dbHome, String user, String password) throws SQLException {

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/platform/db/EmbeddedDatabaseFactory.java View File

@@ -22,10 +22,10 @@ package org.sonar.server.platform.db;
import com.google.common.annotations.VisibleForTesting;
import org.picocontainer.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.System2;

import static org.apache.commons.lang.StringUtils.startsWith;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;

public class EmbeddedDatabaseFactory implements Startable {

@@ -43,7 +43,7 @@ public class EmbeddedDatabaseFactory implements Startable {
@Override
public void start() {
if (embeddedDatabase == null) {
String jdbcUrl = config.get(DatabaseProperties.PROP_URL).get();
String jdbcUrl = config.get(JDBC_URL.getKey()).get();
if (startsWith(jdbcUrl, URL_PREFIX)) {
embeddedDatabase = createEmbeddedDatabase();
embeddedDatabase.start();

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/SettingsSection.java View File

@@ -33,7 +33,7 @@ import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
import static org.apache.commons.lang.StringUtils.abbreviate;
import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
import static org.apache.commons.lang.StringUtils.endsWithIgnoreCase;
import static org.sonar.process.ProcessProperties.AUTH_JWT_SECRET;
import static org.sonar.process.ProcessProperties.Property.AUTH_JWT_SECRET;
import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;

@ServerSide
@@ -70,7 +70,7 @@ public class SettingsSection implements SystemInfoSection, Global {
if (endsWithIgnoreCase(key, ".secured") ||
containsIgnoreCase(key, "password") ||
containsIgnoreCase(key, "passcode") ||
AUTH_JWT_SECRET.equals(key)) {
AUTH_JWT_SECRET.getKey().equals(key)) {
return PASSWORD_VALUE;
}
return abbreviate(value, MAX_VALUE_LENGTH);

+ 6
- 4
server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/StandaloneSystemSection.java View File

@@ -29,12 +29,14 @@ import org.sonar.api.platform.Server;
import org.sonar.api.security.SecurityRealm;
import org.sonar.api.server.authentication.IdentityProvider;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.process.ProcessProperties;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
import org.sonar.server.authentication.IdentityProviderRepository;
import org.sonar.server.platform.ServerLogging;
import org.sonar.server.user.SecurityRealmFactory;

import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;

public class StandaloneSystemSection extends BaseSectionMBean implements SystemSectionMBean {
@@ -120,9 +122,9 @@ public class StandaloneSystemSection extends BaseSectionMBean implements SystemS
setAttribute(protobuf, "High Availability", false);
setAttribute(protobuf, "Official Distribution", officialDistribution.check());
setAttribute(protobuf, "Force authentication", getForceAuthentication());
setAttribute(protobuf, "Home Dir", config.get(ProcessProperties.PATH_HOME).orElse(null));
setAttribute(protobuf, "Data Dir", config.get(ProcessProperties.PATH_DATA).orElse(null));
setAttribute(protobuf, "Temp Dir", config.get(ProcessProperties.PATH_TEMP).orElse(null));
setAttribute(protobuf, "Home Dir", config.get(PATH_HOME.getKey()).orElse(null));
setAttribute(protobuf, "Data Dir", config.get(PATH_DATA.getKey()).orElse(null));
setAttribute(protobuf, "Temp Dir", config.get(PATH_TEMP.getKey()).orElse(null));
setAttribute(protobuf, "Processors", Runtime.getRuntime().availableProcessors());
return protobuf.build();
}

+ 6
- 4
server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/cluster/NodeSystemSection.java View File

@@ -22,11 +22,13 @@ package org.sonar.server.platform.monitoring.cluster;
import org.sonar.api.config.Configuration;
import org.sonar.api.platform.Server;
import org.sonar.api.server.ServerSide;
import org.sonar.process.ProcessProperties;
import org.sonar.process.systeminfo.SystemInfoSection;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
import org.sonar.server.platform.monitoring.OfficialDistribution;

import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;

@ServerSide
@@ -49,9 +51,9 @@ public class NodeSystemSection implements SystemInfoSection {

setAttribute(protobuf, "Version", server.getVersion());
setAttribute(protobuf, "Official Distribution", officialDistribution.check());
setAttribute(protobuf, "Home Dir", config.get(ProcessProperties.PATH_HOME).orElse(null));
setAttribute(protobuf, "Data Dir", config.get(ProcessProperties.PATH_DATA).orElse(null));
setAttribute(protobuf, "Temp Dir", config.get(ProcessProperties.PATH_TEMP).orElse(null));
setAttribute(protobuf, "Home Dir", config.get(PATH_HOME.getKey()).orElse(null));
setAttribute(protobuf, "Data Dir", config.get(PATH_DATA.getKey()).orElse(null));
setAttribute(protobuf, "Temp Dir", config.get(PATH_TEMP.getKey()).orElse(null));
setAttribute(protobuf, "Processors", Runtime.getRuntime().availableProcessors());
return protobuf.build();
}

+ 2
- 12
server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java View File

@@ -28,11 +28,10 @@ import java.util.Date;
import org.apache.commons.io.IOUtils;
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.UriReader;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.config.WebConstants;
import org.sonar.process.ProcessProperties;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.UpdateCenterDeserializer;
import org.sonar.updatecenter.common.UpdateCenterDeserializer.Mode;
@@ -43,15 +42,6 @@ import org.sonar.updatecenter.common.UpdateCenterDeserializer.Mode;
* @since 2.4
*/
@Properties({
@Property(
key = WebConstants.SONAR_UPDATECENTER_ACTIVATE,
defaultValue = "true",
name = "Enable Update Center",
category = "Update Center",
project = false,
// hidden from UI
global = false,
type = PropertyType.BOOLEAN),
@Property(
key = UpdateCenterClient.URL_PROPERTY,
defaultValue = "https://update.sonarsource.org/update-center.properties",
@@ -75,7 +65,7 @@ public class UpdateCenterClient {
public UpdateCenterClient(UriReader uriReader, Configuration config) throws URISyntaxException {
this.uriReader = uriReader;
this.uri = new URI(config.get(URL_PROPERTY).get());
this.isActivated = config.getBoolean(WebConstants.SONAR_UPDATECENTER_ACTIVATE).get();
this.isActivated = config.getBoolean(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey()).get();
Loggers.get(getClass()).info("Update center: " + uriReader.description(uri));
}


+ 6
- 2
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ResetAction.java View File

@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Optional;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -38,11 +39,11 @@ import org.sonar.server.setting.ws.SettingValidations.SettingData;
import org.sonar.server.user.UserSession;

import static java.util.Collections.emptyList;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_COMPONENT;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_KEYS;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;

public class ResetAction implements SettingsWsAction {

@@ -67,12 +68,14 @@ public class ResetAction implements SettingsWsAction {
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("reset")
.setDescription("Remove a setting value.<br>" +
"The settings defined in config/sonar.properties are read-only and can't be changed.<br/>" +
"Requires one of the following permissions: " +
"<ul>" +
"<li>'Administer System'</li>" +
"<li>'Administer' rights on the specified component</li>" +
"</ul>")
.setSince("6.1")
.setChangelog(new Change("7.1", "The settings defined in config/sonar.properties are read-only and can't be changed"))
.setPost(true)
.setHandler(this);

@@ -98,6 +101,7 @@ public class ResetAction implements SettingsWsAction {
Optional<ComponentDto> component = getComponent(dbSession, resetRequest);
checkPermissions(component);
resetRequest.getKeys().forEach(key -> {
SettingsWsSupport.validateKey(key);
SettingData data = new SettingData(key, emptyList(), component.orElse(null));
ImmutableList.of(validations.scope(), validations.qualifier())
.forEach(validation -> validation.accept(data));

+ 8
- 3
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java View File

@@ -40,6 +40,7 @@ import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.PropertyFieldDefinition;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -58,14 +59,14 @@ import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_BRANCH;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_COMPONENT;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_FIELD_VALUES;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_KEY;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_VALUE;
import static org.sonar.server.setting.ws.SettingsWsParameters.PARAM_VALUES;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.checkRequest;

public class SetAction implements SettingsWsAction {
private static final Collector<CharSequence, ?, String> COMMA_JOINER = Collectors.joining(",");
@@ -98,6 +99,7 @@ public class SetAction implements SettingsWsAction {
WebService.NewAction action = context.createAction("set")
.setDescription("Update a setting value.<br>" +
"Either '%s' or '%s' must be provided.<br> " +
"The settings defined in config/sonar.properties are read-only and can't be changed.<br/>" +
"Requires one of the following permissions: " +
"<ul>" +
"<li>'Administer System'</li>" +
@@ -105,6 +107,7 @@ public class SetAction implements SettingsWsAction {
"</ul>",
PARAM_VALUE, PARAM_VALUES)
.setSince("6.1")
.setChangelog(new Change("7.1", "The settings defined in config/sonar.properties are read-only and can't be changed"))
.setPost(true)
.setHandler(this);

@@ -136,7 +139,9 @@ public class SetAction implements SettingsWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
doHandle(dbSession, toWsRequest(request));
SetRequest wsRequest = toWsRequest(request);
SettingsWsSupport.validateKey(wsRequest.getKey());
doHandle(dbSession, wsRequest);
}
response.noContent();
}

+ 13
- 1
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingsWsSupport.java View File

@@ -29,9 +29,12 @@ import org.sonar.api.server.ServerSide;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.process.ProcessProperties;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.user.UserSession;

import static java.lang.String.format;
import static java.util.Arrays.stream;
import static org.sonar.api.PropertyType.LICENSE;
import static org.sonar.api.web.UserRole.ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
@@ -56,6 +59,15 @@ public class SettingsWsSupport {
this.userSession = userSession;
}

static void validateKey(String key) {
stream(ProcessProperties.Property.values())
.filter(property -> property.getKey().equalsIgnoreCase(key))
.findFirst()
.ifPresent(property -> {
throw new IllegalArgumentException(format("Setting '%s' can only be used in sonar.properties", key));
});
}

Predicate<Setting> isSettingVisible(Optional<ComponentDto> component) {
return setting -> isVisible(setting.getKey(), setting.getDefinition(), component);
}
@@ -89,7 +101,7 @@ public class SettingsWsSupport {
.orElse(false);
}

WebService.NewParam addBranchParam(WebService.NewAction action){
WebService.NewParam addBranchParam(WebService.NewAction action) {
return action.createParam(PARAM_BRANCH)
.setDescription("Branch key. Only available on following settings : %s", SettingsWs.SETTING_ON_BRANCHES.stream().collect(COMMA_JOINER))
.setExampleValue(KEY_BRANCH_EXAMPLE_001)

+ 4
- 0
server/sonar-server/src/main/java/org/sonar/server/setting/ws/ValuesAction.java View File

@@ -32,6 +32,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -85,6 +86,7 @@ public class ValuesAction implements SettingsWsAction {
WebService.NewAction action = context.createAction("values")
.setDescription("List settings values.<br>" +
"If no value has been set for a setting, then the default value is returned.<br>" +
"The settings from conf/sonar.properties are excluded from results.<br>" +
"Requires 'Browse' permission when a component is specified<br/>",
"To access licensed settings, authentication is required<br/>" +
"To access secured settings, one of the following permissions is required: " +
@@ -95,6 +97,7 @@ public class ValuesAction implements SettingsWsAction {
"</ul>")
.setResponseExample(getClass().getResource("values-example.json"))
.setSince("6.3")
.setChangelog(new Change("7.1", "The settings from conf/sonar.properties are excluded from results."))
.setHandler(this);
action.createParam(PARAM_KEYS)
.setDescription("List of setting keys")
@@ -120,6 +123,7 @@ public class ValuesAction implements SettingsWsAction {
Optional<ComponentDto> component = loadComponent(dbSession, valuesRequest);

Set<String> keys = loadKeys(valuesRequest);
keys.forEach(SettingsWsSupport::validateKey);
Map<String, String> keysToDisplayMap = getKeysToDisplayMap(keys);
List<Setting> settings = loadSettings(dbSession, component, keysToDisplayMap.keySet());
return new ValuesResponseBuilder(settings, component, keysToDisplayMap).build();

+ 15
- 8
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryClient.java View File

@@ -26,20 +26,22 @@ import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.sonar.api.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;

import static org.sonar.core.config.TelemetryProperties.PROP_URL;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;

@ServerSide
public class TelemetryClient {
public class TelemetryClient implements Startable {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static final Logger LOG = Loggers.get(TelemetryClient.class);

private final OkHttpClient okHttpClient;
private final Configuration config;
private String serverUrl;

public TelemetryClient(OkHttpClient okHttpClient, Configuration config) {
this.okHttpClient = okHttpClient;
@@ -53,7 +55,7 @@ public class TelemetryClient {

void optOut(String json) {
Request.Builder request = new Request.Builder();
request.url(serverUrl());
request.url(serverUrl);
RequestBody body = RequestBody.create(JSON, json);
request.delete(body);

@@ -66,20 +68,25 @@ public class TelemetryClient {

private Request buildHttpRequest(String json) {
Request.Builder request = new Request.Builder();
request.url(serverUrl());
request.url(serverUrl);
RequestBody body = RequestBody.create(JSON, json);
request.post(body);
return request.build();
}

private String serverUrl() {
return config.get(PROP_URL).orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", PROP_URL)));
}

private static void execute(Call call) throws IOException {
try (Response ignored = call.execute()) {
// auto close connection to avoid leaked connection
}
}

@Override
public void start() {
this.serverUrl = config.get(SONAR_TELEMETRY_URL.getKey()).orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_URL)));
}

@Override
public void stop() {
// Nothing to do
}
}

+ 7
- 5
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java View File

@@ -39,9 +39,9 @@ import org.sonar.server.property.InternalProperties;

import static org.sonar.api.utils.DateUtils.formatDate;
import static org.sonar.api.utils.DateUtils.parseDate;
import static org.sonar.core.config.TelemetryProperties.PROP_ENABLE;
import static org.sonar.core.config.TelemetryProperties.PROP_FREQUENCY;
import static org.sonar.core.config.TelemetryProperties.PROP_URL;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_ENABLE;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_FREQUENCY_IN_SECONDS;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
import static org.sonar.server.telemetry.TelemetryDataJsonWriter.writeTelemetryData;

@ServerSide
@@ -70,7 +70,8 @@ public class TelemetryDaemon implements Startable {

@Override
public void start() {
boolean isTelemetryActivated = config.getBoolean(PROP_ENABLE).orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", PROP_URL)));
boolean isTelemetryActivated = config.getBoolean(SONAR_TELEMETRY_ENABLE.getKey())
.orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_URL.getKey())));
boolean hasOptOut = internalProperties.read(I_PROP_OPT_OUT).isPresent();
if (!isTelemetryActivated && !hasOptOut) {
optOut();
@@ -153,6 +154,7 @@ public class TelemetryDaemon implements Startable {
}

private int frequency() {
return config.getInt(PROP_FREQUENCY).orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", PROP_FREQUENCY)));
return config.getInt(SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getKey())
.orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_FREQUENCY_IN_SECONDS)));
}
}

+ 24
- 9
server/sonar-server/src/main/java/org/sonar/server/ui/ws/GlobalAction.java View File

@@ -20,7 +20,10 @@
package org.sonar.server.ui.ws;

import com.google.common.collect.ImmutableSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.sonar.api.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.platform.Server;
import org.sonar.api.resources.ResourceType;
@@ -42,25 +45,25 @@ import org.sonar.server.user.UserSession;

import static org.sonar.api.CoreProperties.RATING_GRID;
import static org.sonar.core.config.CorePropertyDefinitions.EDITIONS_CONFIG_URL;
import static org.sonar.core.config.WebConstants.SONARCLOUD_ENABLED;
import static org.sonar.core.config.WebConstants.SONAR_LF_ENABLE_GRAVATAR;
import static org.sonar.core.config.WebConstants.SONAR_LF_GRAVATAR_SERVER_URL;
import static org.sonar.core.config.WebConstants.SONAR_LF_LOGO_URL;
import static org.sonar.core.config.WebConstants.SONAR_LF_LOGO_WIDTH_PX;
import static org.sonar.core.config.WebConstants.SONAR_UPDATECENTER_ACTIVATE;
import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
import static org.sonar.process.ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE;

public class GlobalAction implements NavigationWsAction {
public class GlobalAction implements NavigationWsAction, Startable {

private static final Set<String> SETTING_KEYS = ImmutableSet.of(
private static final Set<String> DYNAMIC_SETTING_KEYS = ImmutableSet.of(
SONAR_LF_LOGO_URL,
SONAR_LF_LOGO_WIDTH_PX,
SONAR_LF_ENABLE_GRAVATAR,
SONAR_LF_GRAVATAR_SERVER_URL,
SONAR_UPDATECENTER_ACTIVATE,
EDITIONS_CONFIG_URL,
SONARCLOUD_ENABLED,
RATING_GRID);

private final Map<String, String> systemSettingValuesByKey;

private final PageRepository pageRepository;
private final Configuration config;
private final ResourceTypes resourceTypes;
@@ -85,6 +88,18 @@ public class GlobalAction implements NavigationWsAction {
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.branchFeature = branchFeature;
this.userSession = userSession;
this.systemSettingValuesByKey = new HashMap<>();
}

@Override
public void start() {
this.systemSettingValuesByKey.put(SONARCLOUD_ENABLED.getKey(), config.get(SONARCLOUD_ENABLED.getKey()).orElse(null));
this.systemSettingValuesByKey.put(SONAR_UPDATECENTER_ACTIVATE.getKey(), config.get(SONAR_UPDATECENTER_ACTIVATE.getKey()).orElse(null));
}

@Override
public void stop() {
// Nothing to do
}

@Override
@@ -132,9 +147,8 @@ public class GlobalAction implements NavigationWsAction {

private void writeSettings(JsonWriter json) {
json.name("settings").beginObject();
for (String settingKey : SETTING_KEYS) {
json.prop(settingKey, config.get(settingKey).orElse(null));
}
DYNAMIC_SETTING_KEYS.forEach(key -> json.prop(key, config.get(key).orElse(null)));
systemSettingValuesByKey.forEach(json::prop);
json.endObject();
}

@@ -170,4 +184,5 @@ public class GlobalAction implements NavigationWsAction {
private void writeBranchSupport(JsonWriter json) {
json.prop("branchesEnabled", branchFeature.isEnabled());
}

}

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/ui/ws/SettingsAction.java View File

@@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.NewController;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.web.page.Page;
import org.sonar.core.config.WebConstants;
import org.sonar.process.ProcessProperties;
import org.sonar.server.ui.PageRepository;
import org.sonar.server.user.UserSession;

@@ -61,7 +61,7 @@ public class SettingsAction implements NavigationWsAction {

try (JsonWriter json = response.newJsonWriter()) {
json.beginObject();
json.prop("showUpdateCenter", isSysAdmin && config.getBoolean(WebConstants.SONAR_UPDATECENTER_ACTIVATE).orElse(false));
json.prop("showUpdateCenter", isSysAdmin && config.getBoolean(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey()).orElse(false));

json.name("extensions").beginArray();
if (isSysAdmin) {

+ 6
- 3
server/sonar-server/src/main/java/org/sonar/server/user/SecurityRealmFactory.java View File

@@ -31,6 +31,9 @@ import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;

import static org.sonar.process.ProcessProperties.Property.SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE;
import static org.sonar.process.ProcessProperties.Property.SONAR_SECURITY_REALM;

/**
* @since 2.14
*/
@@ -41,15 +44,15 @@ public class SecurityRealmFactory implements Startable {
private final SecurityRealm realm;

public SecurityRealmFactory(Configuration config, SecurityRealm[] realms, LoginPasswordAuthenticator[] authenticators) {
ignoreStartupFailure = config.getBoolean(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE).orElse(false);
String realmName = config.get(CoreProperties.CORE_AUTHENTICATOR_REALM).orElse(null);
ignoreStartupFailure = config.getBoolean(SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE.getKey()).orElse(false);
String realmName = config.get(SONAR_SECURITY_REALM.getKey()).orElse(null);
String className = config.get(CoreProperties.CORE_AUTHENTICATOR_CLASS).orElse(null);
SecurityRealm selectedRealm = null;
if (!StringUtils.isEmpty(realmName)) {
selectedRealm = selectRealm(realms, realmName);
if (selectedRealm == null) {
throw new SonarException(String.format(
"Realm '%s' not found. Please check the property '%s' in conf/sonar.properties", realmName, CoreProperties.CORE_AUTHENTICATOR_REALM));
"Realm '%s' not found. Please check the property '%s' in conf/sonar.properties", realmName, SONAR_SECURITY_REALM.getKey()));
}
}
if (selectedRealm == null && !StringUtils.isEmpty(className)) {

+ 4
- 3
server/sonar-server/src/main/java/org/sonar/server/util/OkHttpClientProvider.java View File

@@ -25,10 +25,11 @@ import org.sonar.api.SonarRuntime;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ServerSide;
import org.sonar.process.ProcessProperties;
import org.sonarqube.ws.client.OkHttpClientBuilder;

import static java.lang.String.format;
import static org.sonar.process.ProcessProperties.Property.HTTP_PROXY_PASSWORD;
import static org.sonar.process.ProcessProperties.Property.HTTP_PROXY_USER;

/**
* Provide a unique instance of {@link OkHttpClient} which configuration:
@@ -59,8 +60,8 @@ public class OkHttpClientProvider extends ProviderAdapter {
builder.setReadTimeoutMs(DEFAULT_READ_TIMEOUT_IN_MS);
// no need to define proxy URL as system-wide proxy is used and properly
// configured by bootstrap process.
builder.setProxyLogin(config.get(ProcessProperties.HTTP_PROXY_USER).orElse(null));
builder.setProxyPassword(config.get(ProcessProperties.HTTP_PROXY_PASSWORD).orElse(null));
builder.setProxyLogin(config.get(HTTP_PROXY_USER.getKey()).orElse(null));
builder.setProxyPassword(config.get(HTTP_PROXY_PASSWORD.getKey()).orElse(null));
builder.setUserAgent(format("SonarQube/%s", runtime.getApiVersion().toString()));
okHttpClient = builder.build();
}

+ 2
- 2
server/sonar-server/src/test/java/org/sonar/ce/log/CeProcessLoggingTest.java View File

@@ -38,12 +38,12 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.logging.LogbackHelper;

import static org.assertj.core.api.Assertions.assertThat;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

public class CeProcessLoggingTest {

@@ -59,7 +59,7 @@ public class CeProcessLoggingTest {
@Before
public void setUp() throws IOException {
logDir = temp.newFolder();
props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), logDir.getAbsolutePath());
}

@AfterClass

+ 9
- 7
server/sonar-server/src/test/java/org/sonar/server/app/TomcatAccessLogTest.java View File

@@ -19,6 +19,9 @@
*/
package org.sonar.server.app;

import java.io.File;
import java.io.IOException;
import java.util.Properties;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.startup.Tomcat;
@@ -28,14 +31,13 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import org.sonar.api.utils.log.Logger;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import java.io.File;
import java.io.IOException;
import java.util.Properties;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

public class TomcatAccessLogTest {

@@ -54,7 +56,7 @@ public class TomcatAccessLogTest {
public void enable_access_logs_by_Default() throws Exception {
Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
Props props = new Props(new Properties());
props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
props.set(PATH_LOGS.getKey(), temp.newFolder().getAbsolutePath());
underTest.configure(tomcat, props);

verify(tomcat.getHost().getPipeline()).addValve(any(ProgrammaticLogbackValve.class));

+ 2
- 2
server/sonar-server/src/test/java/org/sonar/server/app/TomcatContextsTest.java View File

@@ -31,7 +31,6 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.utils.MessageException;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;

import static org.assertj.core.api.Assertions.assertThat;
@@ -41,6 +40,7 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.Property;

public class TomcatContextsTest {

@@ -56,7 +56,7 @@ public class TomcatContextsTest {

@Before
public void setUp() throws Exception {
props.setProperty(ProcessProperties.PATH_DATA, temp.newFolder("data").getAbsolutePath());
props.setProperty(Property.PATH_DATA.getKey(), temp.newFolder("data").getAbsolutePath());
when(tomcat.addWebapp(anyString(), anyString())).thenReturn(mock(StandardContext.class));
}


+ 3
- 4
server/sonar-server/src/test/java/org/sonar/server/app/WebServerProcessLoggingTest.java View File

@@ -42,12 +42,12 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.logging.LogbackHelper;

import static org.assertj.core.api.Assertions.assertThat;
import static org.slf4j.Logger.ROOT_LOGGER_NAME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

public class WebServerProcessLoggingTest {

@@ -63,7 +63,7 @@ public class WebServerProcessLoggingTest {
@Before
public void setUp() throws IOException {
logDir = temp.newFolder();
props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), logDir.getAbsolutePath());
}

@AfterClass
@@ -80,12 +80,11 @@ public class WebServerProcessLoggingTest {
assertThat(appender).isNull();
}


@Test
public void check_level_of_jul() throws IOException {
Props props = new Props(new Properties());
File dir = temp.newFolder();
props.set(ProcessProperties.PATH_LOGS, dir.getAbsolutePath());
props.set(PATH_LOGS.getKey(), dir.getAbsolutePath());
props.set("sonar.log.level.web", "TRACE");

LoggerContext ctx = underTest.configure(props);

+ 23
- 22
server/sonar-server/src/test/java/org/sonar/server/es/EsClientProviderTest.java View File

@@ -30,14 +30,15 @@ import org.junit.rules.ExpectedException;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.process.ProcessProperties;

import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_TYPE;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS;
import static org.sonar.process.ProcessProperties.Property.SEARCH_HOST;
import static org.sonar.process.ProcessProperties.Property.SEARCH_PORT;

public class EsClientProviderTest {

@@ -54,16 +55,16 @@ public class EsClientProviderTest {
@Before
public void setUp() throws Exception {
// mandatory property
settings.setProperty(CLUSTER_NAME, "the_cluster_name");
settings.setProperty(CLUSTER_NAME.getKey(), "the_cluster_name");

localhost = InetAddress.getLocalHost().getHostAddress();
}

@Test
public void connection_to_local_es_when_cluster_mode_is_disabled() {
settings.setProperty(CLUSTER_ENABLED, false);
settings.setProperty(ProcessProperties.SEARCH_HOST, localhost);
settings.setProperty(ProcessProperties.SEARCH_PORT, 8080);
settings.setProperty(CLUSTER_ENABLED.getKey(), false);
settings.setProperty(SEARCH_HOST.getKey(), localhost);
settings.setProperty(SEARCH_PORT.getKey(), 8080);

EsClient client = underTest.provide(settings.asConfig());
TransportClient transportClient = (TransportClient) client.nativeClient();
@@ -79,9 +80,9 @@ public class EsClientProviderTest {

@Test
public void connection_to_remote_es_nodes_when_cluster_mode_is_enabled_and_local_es_is_disabled() {
settings.setProperty(CLUSTER_ENABLED, true);
settings.setProperty(CLUSTER_NODE_TYPE, "application");
settings.setProperty(CLUSTER_SEARCH_HOSTS, format("%s:8080,%s:8081", localhost, localhost));
settings.setProperty(CLUSTER_ENABLED.getKey(), true);
settings.setProperty(CLUSTER_NODE_TYPE.getKey(), "application");
settings.setProperty(CLUSTER_SEARCH_HOSTS.getKey(), format("%s:8080,%s:8081", localhost, localhost));

EsClient client = underTest.provide(settings.asConfig());
TransportClient transportClient = (TransportClient) client.nativeClient();
@@ -100,9 +101,9 @@ public class EsClientProviderTest {

@Test
public void es_client_provider_must_throw_ISE_when_incorrect_port_is_used_when_search_disabled() {
settings.setProperty(CLUSTER_ENABLED, true);
settings.setProperty(CLUSTER_NODE_TYPE, "application");
settings.setProperty(CLUSTER_SEARCH_HOSTS, format("%s:100000,%s:8081", localhost, localhost));
settings.setProperty(CLUSTER_ENABLED.getKey(), true);
settings.setProperty(CLUSTER_NODE_TYPE.getKey(), "application");
settings.setProperty(CLUSTER_SEARCH_HOSTS.getKey(), format("%s:100000,%s:8081", localhost, localhost));

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(format("Port number out of range: %s:100000", localhost));
@@ -112,10 +113,10 @@ public class EsClientProviderTest {

@Test
public void es_client_provider_must_throw_ISE_when_incorrect_port_is_used() {
settings.setProperty(CLUSTER_ENABLED, true);
settings.setProperty(CLUSTER_NODE_TYPE, "search");
settings.setProperty(ProcessProperties.SEARCH_HOST, "localhost");
settings.setProperty(ProcessProperties.SEARCH_PORT, "100000");
settings.setProperty(CLUSTER_ENABLED.getKey(), true);
settings.setProperty(CLUSTER_NODE_TYPE.getKey(), "search");
settings.setProperty(SEARCH_HOST.getKey(), "localhost");
settings.setProperty(SEARCH_PORT.getKey(), "100000");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Port out of range: 100000");
@@ -125,9 +126,9 @@ public class EsClientProviderTest {

@Test
public void es_client_provider_must_add_default_port_when_not_specified() {
settings.setProperty(CLUSTER_ENABLED, true);
settings.setProperty(CLUSTER_NODE_TYPE, "application");
settings.setProperty(CLUSTER_SEARCH_HOSTS, format("%s,%s:8081", localhost, localhost));
settings.setProperty(CLUSTER_ENABLED.getKey(), true);
settings.setProperty(CLUSTER_NODE_TYPE.getKey(), "application");
settings.setProperty(CLUSTER_SEARCH_HOSTS.getKey(), format("%s,%s:8081", localhost, localhost));

EsClient client = underTest.provide(settings.asConfig());
TransportClient transportClient = (TransportClient) client.nativeClient();

+ 13
- 13
server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java View File

@@ -27,12 +27,12 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.process.ProcessProperties;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
import static org.junit.Assert.fail;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.SEARCH_REPLICAS;
import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;

public class NewIndexTest {
@@ -66,7 +66,7 @@ public class NewIndexTest {

@Test
public void verify_default_index_settings_in_cluster() {
settings.setProperty(CLUSTER_ENABLED, "true");
settings.setProperty(CLUSTER_ENABLED.getKey(), "true");
Settings underTest = new NewIndex("issues", defaultSettingsConfiguration).getSettings().build();

assertThat(underTest.get("index.number_of_shards")).isNotEmpty();
@@ -210,7 +210,7 @@ public class NewIndexTest {

@Test
public void five_shards_and_one_replica_by_default_on_cluster() {
settings.setProperty(CLUSTER_ENABLED, "true");
settings.setProperty(CLUSTER_ENABLED.getKey(), "true");
NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());

assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("5");
@@ -236,7 +236,7 @@ public class NewIndexTest {

@Test
public void default_number_of_replicas_on_non_enabled_cluster_must_be_0() {
settings.setProperty(CLUSTER_ENABLED, "false");
settings.setProperty(CLUSTER_ENABLED.getKey(), "false");
NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());

assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
@@ -244,7 +244,7 @@ public class NewIndexTest {

@Test
public void default_number_of_replicas_on_cluster_instance_must_be_1() {
settings.setProperty(CLUSTER_ENABLED, "true");
settings.setProperty(CLUSTER_ENABLED.getKey(), "true");
NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());

assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("1");
@@ -252,8 +252,8 @@ public class NewIndexTest {

@Test
public void when_number_of_replicas_on_cluster_is_specified_to_zero_default_value_must_not_be_used() {
settings.setProperty(CLUSTER_ENABLED, "true");
settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "0");
settings.setProperty(CLUSTER_ENABLED.getKey(), "true");
settings.setProperty(SEARCH_REPLICAS.getKey(), "0");
NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());

assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
@@ -261,8 +261,8 @@ public class NewIndexTest {

@Test
public void index_defined_with_specified_number_of_replicas_when_cluster_enabled() {
settings.setProperty(CLUSTER_ENABLED, "true");
settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "3");
settings.setProperty(CLUSTER_ENABLED.getKey(), "true");
settings.setProperty(SEARCH_REPLICAS.getKey(), "3");
NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());

assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("3");
@@ -270,8 +270,8 @@ public class NewIndexTest {

@Test
public void fail_when_replica_customization_cant_be_parsed() {
settings.setProperty(CLUSTER_ENABLED, "true");
settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "ꝱꝲꝳପ");
settings.setProperty(CLUSTER_ENABLED.getKey(), "true");
settings.setProperty(SEARCH_REPLICAS.getKey(), "ꝱꝲꝳପ");
NewIndex.SettingsConfiguration settingsConfiguration = newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build();

expectedException.expect(IllegalStateException.class);
@@ -282,7 +282,7 @@ public class NewIndexTest {

@Test
public void in_standalone_searchReplicas_is_not_overridable() {
settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "5");
settings.setProperty(SEARCH_REPLICAS.getKey(), "5");
NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);

assertThat(index.getSettings().get("index.number_of_replicas")).isEqualTo("0");

+ 14
- 14
server/sonar-server/src/test/java/org/sonar/server/health/NodeHealthProviderImplTest.java View File

@@ -37,9 +37,9 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.CLUSTER_NODE_PORT;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_PORT;

public class NodeHealthProviderImplTest {
@Rule
@@ -61,7 +61,7 @@ public class NodeHealthProviderImplTest {

@Test
public void constructor_thows_NPE_if_NetworkUtils_getHostname_returns_null() {
mapSettings.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));

expectedException.expect(NullPointerException.class);

@@ -70,7 +70,7 @@ public class NodeHealthProviderImplTest {

@Test
public void constructor_throws_ISE_if_node_port_property_is_not_set() {
mapSettings.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
when(networkUtils.getHostname()).thenReturn(randomAlphanumeric(23));

expectedException.expect(IllegalStateException.class);
@@ -126,8 +126,8 @@ public class NodeHealthProviderImplTest {
public void get_returns_name_and_port_from_properties_at_constructor_time() {
String name = randomAlphanumeric(3);
int port = 1 + random.nextInt(4);
mapSettings.setProperty(CLUSTER_NODE_NAME, name);
mapSettings.setProperty(CLUSTER_NODE_PORT, port);
mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), name);
mapSettings.setProperty(CLUSTER_NODE_PORT.getKey(), port);
setStartedAt();
when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder()
.setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)])
@@ -152,9 +152,9 @@ public class NodeHealthProviderImplTest {
@Test
public void get_returns_host_from_property_if_set_at_constructor_time() {
String host = randomAlphanumeric(4);
mapSettings.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
mapSettings.setProperty(CLUSTER_NODE_PORT, 1 + random.nextInt(4));
mapSettings.setProperty(CLUSTER_NODE_HOST, host);
mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
mapSettings.setProperty(CLUSTER_NODE_PORT.getKey(), 1 + random.nextInt(4));
mapSettings.setProperty(CLUSTER_NODE_HOST.getKey(), host);
setStartedAt();
when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder()
.setStatus(Health.Status.values()[random.nextInt(Health.Status.values().length)])
@@ -166,7 +166,7 @@ public class NodeHealthProviderImplTest {
assertThat(nodeHealth.getDetails().getHost()).isEqualTo(host);

// change values in properties
mapSettings.setProperty(CLUSTER_NODE_HOST, randomAlphanumeric(66));
mapSettings.setProperty(CLUSTER_NODE_HOST.getKey(), randomAlphanumeric(66));

NodeHealth newNodeHealth = underTest.get();

@@ -187,7 +187,7 @@ public class NodeHealthProviderImplTest {
String host = randomAlphanumeric(3);
setRequiredPropertiesForConstructor();
if (hostPropertyValue != null) {
mapSettings.setProperty(CLUSTER_NODE_HOST, hostPropertyValue);
mapSettings.setProperty(CLUSTER_NODE_HOST.getKey(), hostPropertyValue);
}
setStartedAt();
when(healthChecker.checkNode()).thenReturn(Health.newHealthCheckBuilder()
@@ -236,7 +236,7 @@ public class NodeHealthProviderImplTest {
}

private void setRequiredPropertiesForConstructor() {
mapSettings.setProperty(CLUSTER_NODE_NAME, randomAlphanumeric(3));
mapSettings.setProperty(CLUSTER_NODE_PORT, 1 + random.nextInt(4));
mapSettings.setProperty(CLUSTER_NODE_NAME.getKey(), randomAlphanumeric(3));
mapSettings.setProperty(CLUSTER_NODE_PORT.getKey(), 1 + random.nextInt(4));
}
}

+ 2
- 2
server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java View File

@@ -35,7 +35,6 @@ import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.db.Database;
import org.sonar.process.ProcessProperties;
import org.sonar.process.logging.LogLevelConfig;
import org.sonar.process.logging.LogbackHelper;
import org.sonar.server.app.ServerProcessLogging;
@@ -51,6 +50,7 @@ import static org.sonar.api.utils.log.LoggerLevel.ERROR;
import static org.sonar.api.utils.log.LoggerLevel.INFO;
import static org.sonar.api.utils.log.LoggerLevel.TRACE;
import static org.sonar.api.utils.log.LoggerLevel.WARN;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;

@RunWith(DataProviderRunner.class)
public class ServerLoggingTest {
@@ -73,7 +73,7 @@ public class ServerLoggingTest {
@Test
public void getLogsDir() throws IOException {
File dir = temp.newFolder();
settings.setProperty(ProcessProperties.PATH_LOGS, dir.getAbsolutePath());
settings.setProperty(PATH_LOGS.getKey(), dir.getAbsolutePath());

assertThat(underTest.getLogsDir()).isEqualTo(dir);
}

+ 3
- 3
server/sonar-server/src/test/java/org/sonar/server/platform/db/EmbeddedDatabaseFactoryTest.java View File

@@ -21,12 +21,12 @@ package org.sonar.server.platform.db;

import org.junit.Test;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.System2;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;

public class EmbeddedDatabaseFactoryTest {

@@ -35,7 +35,7 @@ public class EmbeddedDatabaseFactoryTest {

@Test
public void should_start_and_stop_tcp_h2_database() {
settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:tcp:localhost");
settings.setProperty(JDBC_URL.getKey(), "jdbc:h2:tcp:localhost");

EmbeddedDatabase embeddedDatabase = mock(EmbeddedDatabase.class);

@@ -54,7 +54,7 @@ public class EmbeddedDatabaseFactoryTest {

@Test
public void should_not_start_mem_h2_database() {
settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:h2:mem");
settings.setProperty(JDBC_URL.getKey(), "jdbc:h2:mem");

EmbeddedDatabase embeddedDatabase = mock(EmbeddedDatabase.class);


+ 28
- 30
server/sonar-server/src/test/java/org/sonar/server/platform/db/EmbeddedDatabaseTest.java View File

@@ -39,13 +39,11 @@ import org.sonar.process.NetworkUtilsImpl;
import static junit.framework.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.sonar.api.database.DatabaseProperties.PROP_EMBEDDED_PORT;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD_DEFAULT_VALUE;
import static org.sonar.api.database.DatabaseProperties.PROP_URL;
import static org.sonar.api.database.DatabaseProperties.PROP_USER;
import static org.sonar.api.database.DatabaseProperties.PROP_USER_DEFAULT_VALUE;
import static org.sonar.process.ProcessProperties.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.JDBC_EMBEDDED_PORT;
import static org.sonar.process.ProcessProperties.Property.JDBC_PASSWORD;
import static org.sonar.process.ProcessProperties.Property.JDBC_URL;
import static org.sonar.process.ProcessProperties.Property.JDBC_USERNAME;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;

public class EmbeddedDatabaseTest {

@@ -74,27 +72,27 @@ public class EmbeddedDatabaseTest {
@Test
public void start_fails_with_IAE_if_property_Data_Path_is_not_set() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Missing property " + PATH_DATA);
expectedException.expectMessage("Missing property " + PATH_DATA.getKey());

underTest.start();
}

@Test
public void start_fails_with_IAE_if_property_Data_Path_is_empty() {
settings.setProperty(PATH_DATA, "");
settings.setProperty(PATH_DATA.getKey(), "");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Missing property " + PATH_DATA);
expectedException.expectMessage("Missing property " + PATH_DATA.getKey());

underTest.start();
}

@Test
public void start_fails_with_IAE_if_JDBC_URL_settings_is_not_set() throws IOException {
settings.setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath());
settings.setProperty(PATH_DATA.getKey(), temporaryFolder.newFolder().getAbsolutePath());

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Missing property " + PROP_URL);
expectedException.expectMessage("Missing property " + JDBC_URL.getKey());

underTest.start();
}
@@ -102,37 +100,37 @@ public class EmbeddedDatabaseTest {
@Test
public void start_fails_with_IAE_if_embedded_port_settings_is_not_set() throws IOException {
settings
.setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
.setProperty(PROP_URL, "jdbc url");
.setProperty(PATH_DATA.getKey(), temporaryFolder.newFolder().getAbsolutePath())
.setProperty(JDBC_URL.getKey(), "jdbc url");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Missing property " + PROP_EMBEDDED_PORT);
expectedException.expectMessage("Missing property " + JDBC_EMBEDDED_PORT.getKey());

underTest.start();
}

@Test
public void start_ignores_URL_to_create_database_and_uses_default_username_and_password_when_then_are_not_set() throws IOException {
public void start_ignores_URL_to_create_database_and_uses_empty_username_and_password_when_then_are_not_set() throws IOException {
int port = NetworkUtilsImpl.INSTANCE.getNextAvailablePort(InetAddress.getLoopbackAddress());
settings
.setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
.setProperty(PROP_URL, "jdbc url")
.setProperty(PROP_EMBEDDED_PORT, "" + port);
.setProperty(PATH_DATA.getKey(), temporaryFolder.newFolder().getAbsolutePath())
.setProperty(JDBC_URL.getKey(), "jdbc url")
.setProperty(JDBC_EMBEDDED_PORT.getKey(), "" + port);

underTest.start();

checkDbIsUp(port, PROP_USER_DEFAULT_VALUE, PROP_PASSWORD_DEFAULT_VALUE);
checkDbIsUp(port, "", "");
}

@Test
public void start_creates_db_and_adds_tcp_listener() throws IOException {
int port = NetworkUtilsImpl.INSTANCE.getNextAvailablePort(InetAddress.getLoopbackAddress());
settings
.setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
.setProperty(PROP_URL, "jdbc url")
.setProperty(PROP_EMBEDDED_PORT, "" + port)
.setProperty(PROP_USER, "foo")
.setProperty(PROP_PASSWORD, "bar");
.setProperty(PATH_DATA.getKey(), temporaryFolder.newFolder().getAbsolutePath())
.setProperty(JDBC_URL.getKey(), "jdbc url")
.setProperty(JDBC_EMBEDDED_PORT.getKey(), "" + port)
.setProperty(JDBC_USERNAME.getKey(), "foo")
.setProperty(JDBC_PASSWORD.getKey(), "bar");

underTest.start();

@@ -146,11 +144,11 @@ public class EmbeddedDatabaseTest {
public void start_supports_in_memory_H2_JDBC_URL() throws IOException {
int port = NetworkUtilsImpl.INSTANCE.getNextAvailablePort(InetAddress.getLoopbackAddress());
settings
.setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
.setProperty(PROP_URL, "jdbc:h2:mem:sonar")
.setProperty(PROP_EMBEDDED_PORT, "" + port)
.setProperty(PROP_USER, "foo")
.setProperty(PROP_PASSWORD, "bar");
.setProperty(PATH_DATA.getKey(), temporaryFolder.newFolder().getAbsolutePath())
.setProperty(JDBC_URL.getKey(), "jdbc:h2:mem:sonar")
.setProperty(JDBC_EMBEDDED_PORT.getKey(), "" + port)
.setProperty(JDBC_USERNAME.getKey(), "foo")
.setProperty(JDBC_PASSWORD.getKey(), "bar");

underTest.start();


+ 10
- 7
server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/cluster/NodeSystemSectionTest.java View File

@@ -24,7 +24,6 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.platform.Server;
import org.sonar.process.ProcessProperties;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
import org.sonar.server.platform.monitoring.OfficialDistribution;

@@ -32,10 +31,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;
import static org.sonar.process.ProcessProperties.Property.PATH_WEB;
import static org.sonar.process.systeminfo.SystemInfoUtils.attribute;
import static org.sonar.server.platform.monitoring.SystemInfoTesting.assertThatAttributeIs;


public class NodeSystemSectionTest {

@Rule
@@ -80,11 +83,11 @@ public class NodeSystemSectionTest {

@Test
public void return_dir_paths() {
settings.setProperty(ProcessProperties.PATH_HOME, "/home");
settings.setProperty(ProcessProperties.PATH_DATA, "/data");
settings.setProperty(ProcessProperties.PATH_TEMP, "/temp");
settings.setProperty(ProcessProperties.PATH_LOGS, "/logs");
settings.setProperty(ProcessProperties.PATH_WEB, "/web");
settings.setProperty(PATH_HOME.getKey(), "/home");
settings.setProperty(PATH_DATA.getKey(), "/data");
settings.setProperty(PATH_TEMP.getKey(), "/temp");
settings.setProperty(PATH_LOGS.getKey(), "/logs");
settings.setProperty(PATH_WEB.getKey(), "/web");

ProtobufSystemInfo.Section section = underTest.toProtobuf();


+ 6
- 4
server/sonar-server/src/test/java/org/sonar/server/platform/platformlevel/PlatformLevel2Test.java View File

@@ -26,13 +26,15 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.utils.System2;
import org.sonar.core.platform.PluginRepository;
import org.sonar.process.ProcessProperties;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.WebServer;
import org.sonar.server.platform.db.migration.charset.DatabaseCharsetChecker;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
import static org.sonar.process.ProcessProperties.Property.PATH_TEMP;

public class PlatformLevel2Test {

@@ -44,9 +46,9 @@ public class PlatformLevel2Test {
@Before
public void setUp() throws Exception {
// these are mandatory settings declared by bootstrap process
props.setProperty(ProcessProperties.PATH_HOME, tempFolder.newFolder().getAbsolutePath());
props.setProperty(ProcessProperties.PATH_DATA, tempFolder.newFolder().getAbsolutePath());
props.setProperty(ProcessProperties.PATH_TEMP, tempFolder.newFolder().getAbsolutePath());
props.setProperty(PATH_HOME.getKey(), tempFolder.newFolder().getAbsolutePath());
props.setProperty(PATH_DATA.getKey(), tempFolder.newFolder().getAbsolutePath());
props.setProperty(PATH_TEMP.getKey(), tempFolder.newFolder().getAbsolutePath());
}

@Test

+ 3
- 3
server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java View File

@@ -27,7 +27,7 @@ import org.junit.Test;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.UriReader;
import org.sonar.core.config.WebConstants;
import org.sonar.process.ProcessProperties;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;

@@ -51,7 +51,7 @@ public class UpdateCenterClientTest {
public void startServer() throws Exception {
reader = mock(UriReader.class);
settings.setProperty(UpdateCenterClient.URL_PROPERTY, BASE_URL);
settings.setProperty(WebConstants.SONAR_UPDATECENTER_ACTIVATE, true);
settings.setProperty(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey(), true);
underTest = new UpdateCenterClient(reader, settings.asConfig());
}

@@ -97,7 +97,7 @@ public class UpdateCenterClientTest {

@Test
public void update_center_is_null_when_property_is_false() {
settings.setProperty(WebConstants.SONAR_UPDATECENTER_ACTIVATE, false);
settings.setProperty(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey(), false);

assertThat(underTest.getUpdateCenter()).isAbsent();
}

+ 2
- 2
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java View File

@@ -32,7 +32,7 @@ import org.sonar.server.es.NewIndex;

import static org.assertj.core.api.Assertions.assertThat;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
import static org.sonar.server.es.DefaultIndexSettingsElement.ENGLISH_HTML_ANALYZER;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION;
import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_KEY;
@@ -64,7 +64,7 @@ public class RuleIndexDefinitionTest {

@Test
public void enable_replica_if_clustering_is_enabled() {
settings.setProperty(CLUSTER_ENABLED, true);
settings.setProperty(CLUSTER_ENABLED.getKey(), true);
IndexDefinition.IndexDefinitionContext context = new IndexDefinition.IndexDefinitionContext();
underTest.define(context);


+ 16
- 0
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ResetActionTest.java View File

@@ -42,6 +42,7 @@ import org.sonar.db.property.PropertyDbTester;
import org.sonar.db.property.PropertyQuery;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserTesting;
import org.sonar.process.ProcessProperties;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
@@ -406,6 +407,21 @@ public class ResetActionTest {
.execute();
}

@Test
public void fail_when_setting_key_is_defined_in_sonar_properties() {
ComponentDto project = db.components().insertPrivateProject();
logInAsProjectAdmin(project);
String settingKey = ProcessProperties.Property.JDBC_URL.getKey();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(format("Setting '%s' can only be used in sonar.properties", settingKey));

ws.newRequest()
.setParam("keys", settingKey)
.setParam("component", project.getKey())
.execute();
}

private void succeedForPropertyWithoutDefinitionAndValidComponent(ComponentDto root, ComponentDto module) {
logInAsProjectAdmin(root);


+ 17
- 0
server/sonar-server/src/test/java/org/sonar/server/setting/ws/SetActionTest.java View File

@@ -47,6 +47,7 @@ import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.property.PropertyDbTester;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
import org.sonar.process.ProcessProperties;
import org.sonar.scanner.protocol.GsonHelper;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.component.TestComponentFinder;
@@ -989,6 +990,22 @@ public class SetActionTest {
.execute();
}

@Test
public void fail_when_setting_key_is_defined_in_sonar_properties() {
ComponentDto project = db.components().insertPrivateProject();
logInAsProjectAdministrator(project);
String settingKey = ProcessProperties.Property.JDBC_URL.getKey();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(format("Setting '%s' can only be used in sonar.properties", settingKey));

ws.newRequest()
.setParam("key", settingKey)
.setParam("value", "any value")
.setParam("component", project.getKey())
.execute();
}

@Test
public void definition() {
WebService.Action definition = ws.getDef();

+ 17
- 1
server/sonar-server/src/test/java/org/sonar/server/setting/ws/ValuesActionTest.java View File

@@ -41,6 +41,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.property.PropertyDbTester;
import org.sonar.process.ProcessProperties;
import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
@@ -836,7 +837,7 @@ public class ValuesActionTest {
public void fail_when_using_branch_db_key() throws Exception {
OrganizationDto organization = db.organizations().insert();
ComponentDto project = db.components().insertMainBranch(organization);
userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
userSession.logIn().addProjectPermission(UserRole.USER, project);
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
@@ -848,6 +849,21 @@ public class ValuesActionTest {
.execute();
}

@Test
public void fail_when_setting_key_is_defined_in_sonar_properties() {
ComponentDto project = db.components().insertPrivateProject();
userSession.logIn().addProjectPermission(UserRole.USER, project);
String settingKey = ProcessProperties.Property.JDBC_URL.getKey();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage(format("Setting '%s' can only be used in sonar.properties", settingKey));

ws.newRequest()
.setParam("keys", settingKey)
.setParam("component", project.getKey())
.execute();
}

@Test
public void test_ws_definition() {
WebService.Action action = ws.getDef();

+ 5
- 3
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryClientTest.java View File

@@ -32,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.sonar.core.config.TelemetryProperties.PROP_URL;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;

public class TelemetryClientTest {

@@ -47,7 +47,8 @@ public class TelemetryClientTest {
@Test
public void upload() throws IOException {
ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
settings.setProperty(PROP_URL, TELEMETRY_URL);
settings.setProperty(SONAR_TELEMETRY_URL.getKey(), TELEMETRY_URL);
underTest.start();

underTest.upload(JSON);

@@ -64,7 +65,8 @@ public class TelemetryClientTest {
@Test
public void opt_out() throws IOException {
ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
settings.setProperty(PROP_URL, TELEMETRY_URL);
settings.setProperty(SONAR_TELEMETRY_URL.getKey(), TELEMETRY_URL);
underTest.start();

underTest.optOut(JSON);


+ 18
- 3
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java View File

@@ -29,12 +29,10 @@ import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.core.config.TelemetryProperties;
import org.sonar.core.platform.PluginInfo;
import org.sonar.core.platform.PluginRepository;
import org.sonar.db.DbSession;
@@ -72,6 +70,9 @@ import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY
import static org.sonar.api.utils.DateUtils.parseDate;
import static org.sonar.db.component.BranchType.LONG;
import static org.sonar.db.component.BranchType.SHORT;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_ENABLE;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_FREQUENCY_IN_SECONDS;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
import static org.sonar.test.JsonAssert.assertJson;

public class TelemetryDaemonTest {
@@ -94,7 +95,7 @@ public class TelemetryDaemonTest {
private FakeServer server = new FakeServer();
private PluginRepository pluginRepository = mock(PluginRepository.class);
private TestSystem2 system2 = new TestSystem2().setNow(System.currentTimeMillis());
private MapSettings settings = new MapSettings(new PropertyDefinitions(TelemetryProperties.all()));
private MapSettings settings = new MapSettings();
private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(db.getDbClient(), es.client());
private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());

@@ -108,6 +109,7 @@ public class TelemetryDaemonTest {

@Test
public void send_telemetry_data() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
server.setId("AU-TpxcB-iU5OvuD2FL7");
server.setVersion("7.5.4");
@@ -164,6 +166,7 @@ public class TelemetryDaemonTest {

@Test
public void exclude_branches() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
server.setId("AU-TpxcB-iU5OvuD2FL7").setVersion("7.5.4");
MetricDto ncloc = db.measures().insertMetric(m -> m.setKey(NCLOC_KEY));
@@ -186,6 +189,7 @@ public class TelemetryDaemonTest {

@Test
public void send_data_via_client_at_startup_after_initial_delay() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
underTest.start();

@@ -194,6 +198,7 @@ public class TelemetryDaemonTest {

@Test
public void check_if_should_send_data_periodically() throws IOException {
initTelemetrySettingsToDefaultValues();
long now = system2.now();
long sixDaysAgo = now - (ONE_DAY * 6L);
long sevenDaysAgo = now - (ONE_DAY * 7L);
@@ -208,6 +213,7 @@ public class TelemetryDaemonTest {

@Test
public void send_server_id_and_version() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
String id = randomAlphanumeric(40);
String version = randomAlphanumeric(10);
@@ -222,6 +228,7 @@ public class TelemetryDaemonTest {

@Test
public void do_not_send_data_if_last_ping_earlier_than_one_week_ago() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
long now = system2.now();
long sixDaysAgo = now - (ONE_DAY * 6L);
@@ -234,6 +241,7 @@ public class TelemetryDaemonTest {

@Test
public void send_data_if_last_ping_is_one_week_ago() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
long today = parseDate("2017-08-01").getTime();
system2.setNow(today + 15 * ONE_HOUR);
@@ -249,6 +257,7 @@ public class TelemetryDaemonTest {

@Test
public void opt_out_sent_once() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
settings.setProperty("sonar.telemetry.enable", "false");
underTest.start();
@@ -263,4 +272,10 @@ public class TelemetryDaemonTest {
return new PluginInfo(key)
.setVersion(Version.create(version));
}

private void initTelemetrySettingsToDefaultValues(){
settings.setProperty(SONAR_TELEMETRY_ENABLE.getKey(), SONAR_TELEMETRY_ENABLE.getDefaultValue());
settings.setProperty(SONAR_TELEMETRY_URL.getKey(), SONAR_TELEMETRY_URL.getDefaultValue());
settings.setProperty(SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getKey(), SONAR_TELEMETRY_FREQUENCY_IN_SECONDS.getDefaultValue());
}
}

+ 11
- 9
server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java View File

@@ -98,7 +98,6 @@ public class GlobalActionTest {

@Test
public void return_settings() {
init();
settings.setProperty("sonar.lf.logoUrl", "http://example.com/my-custom-logo.png");
settings.setProperty("sonar.lf.logoWidthPx", 135);
settings.setProperty("sonar.lf.gravatarServerUrl", "https://secure.gravatar.com/avatar/{EMAIL_MD5}.jpg?s={SIZE}&d=identicon");
@@ -109,6 +108,7 @@ public class GlobalActionTest {
settings.setProperty("sonar.technicalDebt.ratingGrid", "0.05,0.1,0.2,0.5");
// This setting should be ignored as it's not needed
settings.setProperty("sonar.defaultGroup", "sonar-users");
init();

assertJson(call()).isSimilarTo("{" +
" \"settings\": {" +
@@ -249,6 +249,12 @@ public class GlobalActionTest {

@Test
public void test_example_response() {
settings.setProperty("sonar.lf.logoUrl", "http://example.com/my-custom-logo.png");
settings.setProperty("sonar.lf.logoWidthPx", 135);
settings.setProperty("sonar.lf.gravatarServerUrl", "http://some-server.tld/logo.png");
settings.setProperty("sonar.lf.enableGravatar", true);
settings.setProperty("sonar.updatecenter.activate", false);
settings.setProperty("sonar.technicalDebt.ratingGrid", "0.05,0.1,0.2,0.5");
init(createPages(), new ResourceTypeTree[] {
ResourceTypeTree.builder()
.addType(ResourceType.builder("POL").build())
@@ -261,12 +267,6 @@ public class GlobalActionTest {
.addRelations("PAL", "LAP")
.build()
});
settings.setProperty("sonar.lf.logoUrl", "http://example.com/my-custom-logo.png");
settings.setProperty("sonar.lf.logoWidthPx", 135);
settings.setProperty("sonar.lf.gravatarServerUrl", "http://some-server.tld/logo.png");
settings.setProperty("sonar.lf.enableGravatar", true);
settings.setProperty("sonar.updatecenter.activate", false);
settings.setProperty("sonar.technicalDebt.ratingGrid", "0.05,0.1,0.2,0.5");
when(server.getVersion()).thenReturn("6.2");
when(dbClient.getDatabase().getDialect()).thenReturn(new MySql());
when(webServer.isStandalone()).thenReturn(true);
@@ -290,8 +290,10 @@ public class GlobalActionTest {
}
}});
pageRepository.start();
ws = new WsActionTester(new GlobalAction(pageRepository, settings.asConfig(), new ResourceTypes(resourceTypeTrees), server,
webServer, dbClient, organizationFlags, defaultOrganizationProvider, branchFeature, userSession));
GlobalAction wsAction = new GlobalAction(pageRepository, settings.asConfig(), new ResourceTypes(resourceTypeTrees), server,
webServer, dbClient, organizationFlags, defaultOrganizationProvider, branchFeature, userSession);
ws = new WsActionTester(wsAction);
wsAction.start();
}

private String call() {

+ 3
- 3
server/sonar-server/src/test/java/org/sonar/server/ui/ws/SettingsActionTest.java View File

@@ -24,8 +24,8 @@ import org.junit.Test;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.web.page.Page;
import org.sonar.api.web.page.PageDefinition;
import org.sonar.core.config.WebConstants;
import org.sonar.core.platform.PluginRepository;
import org.sonar.process.ProcessProperties;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ui.PageRepository;
import org.sonar.server.ws.WsActionTester;
@@ -63,7 +63,7 @@ public class SettingsActionTest {
@Test
public void returns_update_center_settings() {
init();
settings.setProperty(WebConstants.SONAR_UPDATECENTER_ACTIVATE, true);
settings.setProperty(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey(), true);
logInAsSystemAdministrator();

executeAndVerify("with_update_center.json");
@@ -72,7 +72,7 @@ public class SettingsActionTest {
@Test
public void request_succeeds_but_settings_are_not_returned_when_user_is_not_system_administrator() {
init(createPages());
settings.setProperty(WebConstants.SONAR_UPDATECENTER_ACTIVATE, true);
settings.setProperty(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey(), true);
userSessionRule.logIn().setNonSystemAdministrator();

executeAndVerify("empty.json");

+ 5
- 5
server/sonar-server/src/test/java/org/sonar/server/user/SecurityRealmFactoryTest.java View File

@@ -41,7 +41,7 @@ public class SecurityRealmFactoryTest {
@Test
public void should_select_realm_and_start() {
SecurityRealm realm = spy(new FakeRealm());
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
settings.setProperty("sonar.security.realm", realm.getName());

SecurityRealmFactory factory = new SecurityRealmFactory(settings.asConfig(), new SecurityRealm[] {realm});
factory.start();
@@ -62,7 +62,7 @@ public class SecurityRealmFactoryTest {

@Test
public void realm_not_found() {
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, "Fake");
settings.setProperty("sonar.security.realm", "Fake");

try {
new SecurityRealmFactory(settings.asConfig());
@@ -85,7 +85,7 @@ public class SecurityRealmFactoryTest {
@Test
public void should_take_precedence_over_authenticator() {
SecurityRealm realm = new FakeRealm();
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
settings.setProperty("sonar.security.realm", realm.getName());
LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());

@@ -109,7 +109,7 @@ public class SecurityRealmFactoryTest {
@Test
public void ignore_startup_failure() {
SecurityRealm realm = spy(new AlwaysFailsRealm());
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
settings.setProperty("sonar.security.realm", realm.getName());
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, true);

new SecurityRealmFactory(settings.asConfig(), new SecurityRealm[] {realm}).start();
@@ -119,7 +119,7 @@ public class SecurityRealmFactoryTest {
@Test
public void should_fail() {
SecurityRealm realm = spy(new AlwaysFailsRealm());
settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
settings.setProperty("sonar.security.realm", realm.getName());

try {
new SecurityRealmFactory(settings.asConfig(), new SecurityRealm[] {realm}).start();

+ 4
- 4
sonar-application/src/main/java/org/sonar/application/App.java View File

@@ -20,6 +20,8 @@
package org.sonar.application;

import java.io.IOException;
import org.sonar.application.command.CommandFactory;
import org.sonar.application.command.CommandFactoryImpl;
import org.sonar.application.config.AppSettings;
import org.sonar.application.config.AppSettingsLoader;
import org.sonar.application.config.AppSettingsLoaderImpl;
@@ -29,11 +31,9 @@ import org.sonar.application.process.StopRequestWatcher;
import org.sonar.application.process.StopRequestWatcherImpl;
import org.sonar.process.System2;
import org.sonar.process.SystemExit;
import org.sonar.application.command.CommandFactory;
import org.sonar.application.command.CommandFactoryImpl;

import static org.sonar.application.config.SonarQubeVersionHelper.getSonarqubeVersion;
import static org.sonar.process.ProcessProperties.CLUSTER_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_NAME;

public class App {

@@ -50,7 +50,7 @@ public class App {

try (AppState appState = new AppStateFactory(settings).create()) {
appState.registerSonarQubeVersion(getSonarqubeVersion());
appState.registerClusterName(settings.getProps().nonNullValue(CLUSTER_NAME));
appState.registerClusterName(settings.getProps().nonNullValue(CLUSTER_NAME.getKey()));
AppReloader appReloader = new AppReloaderImpl(settingsLoader, fileSystem, appState, logging);
fileSystem.reset();
CommandFactory commandFactory = new CommandFactoryImpl(settings.getProps(), fileSystem.getTempDir(), System2.INSTANCE);

+ 0
- 17
sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java View File

@@ -29,7 +29,6 @@ import org.sonar.api.resources.Qualifiers;

import static java.util.Arrays.asList;
import static org.sonar.api.PropertyType.BOOLEAN;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD;

public class CorePropertyDefinitions {

@@ -62,15 +61,9 @@ public class CorePropertyDefinitions {
defs.addAll(PurgeProperties.all());
defs.addAll(EmailSettings.definitions());
defs.addAll(WebhookProperties.all());
defs.addAll(TelemetryProperties.all());
defs.addAll(ScannerProperties.all());
defs.addAll(WebProperties.all());

defs.addAll(asList(
PropertyDefinition.builder(PROP_PASSWORD)
.type(PropertyType.PASSWORD)
.hidden()
.build(),
PropertyDefinition.builder(CoreProperties.SERVER_BASE_URL)
.name("Server base URL")
.description("HTTP URL of this SonarQube server, such as <i>http://yourhost.yourdomain/sonar</i>. This value is used i.e. to create links in emails.")
@@ -125,10 +118,6 @@ public class CorePropertyDefinitions {
.category(CoreProperties.CATEGORY_GENERAL)
.defaultValue(String.valueOf(false))
.build(),
PropertyDefinition.builder(CoreProperties.CORE_AUTHENTICATOR_REALM)
.name("Security Realm")
.hidden()
.build(),
PropertyDefinition.builder("sonar.authenticator.downcase")
.name("Downcase login")
.description("Downcase login during user authentication, typically for Active Directory")
@@ -136,12 +125,6 @@ public class CorePropertyDefinitions {
.defaultValue(String.valueOf(false))
.hidden()
.build(),
PropertyDefinition.builder(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE)
.name("Ignore failures during authenticator startup")
.type(BOOLEAN)
.defaultValue(String.valueOf(false))
.hidden()
.build(),
PropertyDefinition.builder(DISABLE_NOTIFICATION_ON_BUILT_IN_QPROFILES)
.name("Avoid quality profiles notification")
.description("Avoid sending email notification on each update of built-in quality profiles to quality profile administrators.")

+ 0
- 63
sonar-core/src/main/java/org/sonar/core/config/TelemetryProperties.java View File

@@ -1,63 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.config;

import com.google.common.collect.ImmutableList;
import java.util.List;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;

public class TelemetryProperties {

public static final String PROP_ENABLE = "sonar.telemetry.enable";
public static final String PROP_FREQUENCY = "sonar.telemetry.frequencyInSeconds";
public static final String PROP_URL = "sonar.telemetry.url";

private TelemetryProperties() {
// only static stuff
}

public static List<PropertyDefinition> all() {
return ImmutableList.of(
PropertyDefinition.builder(PROP_ENABLE)
.defaultValue(Boolean.toString(true))
.type(PropertyType.BOOLEAN)
.name("Share SonarQube statistics")
.description("By sharing anonymous SonarQube statistics, you help us understand how SonarQube is used so we can improve the plugin to work even better for you. " +
"We don't collect source code or IP addresses. And we don't share the data with anyone else.")
.hidden()
.build(),
PropertyDefinition.builder(PROP_FREQUENCY)
// 6 hours in seconds
.defaultValue("21600")
.type(PropertyType.INTEGER)
.name("Frequency of telemetry checks, in seconds")
.hidden()
.build(),
PropertyDefinition.builder(PROP_URL)
.defaultValue("https://telemetry.sonarsource.com/sonarqube")
.type(PropertyType.STRING)
.name("URL where telemetry data is sent")
.hidden()
.build()
);

}
}

+ 0
- 2
sonar-core/src/main/java/org/sonar/core/config/WebConstants.java View File

@@ -29,8 +29,6 @@ public final class WebConstants {
public static final String SONAR_LF_LOGO_URL = "sonar.lf.logoUrl";
public static final String SONAR_LF_LOGO_WIDTH_PX = "sonar.lf.logoWidthPx";
public static final String SONAR_LF_ABOUT_TEXT = "sonar.lf.aboutText";
public static final String SONAR_UPDATECENTER_ACTIVATE = "sonar.updatecenter.activate";
public static final String SONARCLOUD_ENABLED = "sonar.sonarcloud.enabled";

private WebConstants() {
}

+ 1
- 12
sonar-core/src/test/java/org/sonar/core/config/CorePropertyDefinitionsTest.java View File

@@ -20,28 +20,17 @@
package org.sonar.core.config;

import java.util.List;
import java.util.Optional;
import org.junit.Test;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD;

public class CorePropertyDefinitionsTest {

@Test
public void all() {
List<PropertyDefinition> defs = CorePropertyDefinitions.all();
assertThat(defs).hasSize(67);
}

@Test
public void jdbc_password_property_has_password_type() {
List<PropertyDefinition> defs = CorePropertyDefinitions.all();

Optional<PropertyDefinition> prop = defs.stream().filter(def -> PROP_PASSWORD.equals(def.key())).findFirst();
assertThat(prop.get().type()).isEqualTo(PropertyType.PASSWORD);
assertThat(defs).hasSize(60);
}

@Test

+ 0
- 0
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save