import org.junit.Test;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
public class GitHubSettingsTest {
- private MapSettings settings = new MapSettings(new PropertyDefinitions(GitHubSettings.definitions()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, GitHubSettings.definitions()));
private GitHubSettings underTest = new GitHubSettings(settings.asConfig());
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.utils.System2;
import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
public MockWebServer github = new MockWebServer();
// load settings with default values
- private MapSettings settings = new MapSettings(new PropertyDefinitions(GitHubSettings.definitions()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, GitHubSettings.definitions()));
private GitHubSettings gitHubSettings = new GitHubSettings(settings.asConfig());
private UserIdentityFactoryImpl userIdentityFactory = new UserIdentityFactoryImpl();
private ScribeGitHubApi scribeApi = new ScribeGitHubApi(gitHubSettings);
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private MapSettings settings = new MapSettings(new PropertyDefinitions(GitHubSettings.definitions()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, GitHubSettings.definitions()));
private UserIdentityFactoryImpl underTest = new UserIdentityFactoryImpl();
@Test
import org.junit.rules.ExpectedException;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.auth.gitlab.GitLabSettings.GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP;
@Before
public void prepare() {
- settings = new MapSettings(new PropertyDefinitions(GitLabSettings.definitions()));
+ settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, GitLabSettings.definitions()));
config = new GitLabSettings(settings.asConfig());
}
settings.setProperty(GITLAB_AUTH_URL, "https://gitlab.com/api/");
assertThat(config.url()).isEqualTo("https://gitlab.com/api");
-
settings.setProperty(GITLAB_AUTH_URL, "https://gitlab.com/api");
assertThat(config.url()).isEqualTo("https://gitlab.com/api");
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
-import org.apache.commons.io.IOUtils;
import org.sonar.api.server.authentication.OAuth2IdentityProvider;
import org.sonar.api.server.authentication.UnauthorizedException;
import org.sonar.api.server.authentication.UserIdentity;
+import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private MapSettings settings = new MapSettings(new PropertyDefinitions(SamlSettings.definitions()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, SamlSettings.definitions()));
private SamlIdentityProvider underTest = new SamlIdentityProvider(new SamlSettings(settings.asConfig()));
import org.junit.runner.RunWith;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private MapSettings settings = new MapSettings(new PropertyDefinitions(SamlSettings.definitions()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, SamlSettings.definitions()));
private SamlSettings underTest = new SamlSettings(settings.asConfig());
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.CoreProperties;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import org.sonar.core.config.PurgeConstants;
import org.sonar.core.config.PurgeProperties;
import org.sonar.db.DbSession;
import static java.util.Collections.emptySet;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
public class ProjectCleanerTest {
private PurgeProfiler profiler = mock(PurgeProfiler.class);
private DefaultPeriodCleaner periodCleaner = mock(DefaultPeriodCleaner.class);
private PurgeListener purgeListener = mock(PurgeListener.class);
- private MapSettings settings = new MapSettings(new PropertyDefinitions(PurgeProperties.all()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, PurgeProperties.all()));
@Before
public void before() {
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.System2;
import org.sonar.core.config.CorePropertyDefinitions;
import static org.assertj.core.api.Assertions.assertThat;
public class RatingSettingsTest {
- private MapSettings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, CorePropertyDefinitions.all()));
@Rule
public ExpectedException expectedException = ExpectedException.none();
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_AUTH_NTLM_DOMAIN;
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;
HTTP_NON_PROXY_HOSTS.getKey(),
HTTPS_PROXY_HOST.getKey(),
HTTPS_PROXY_PORT.getKey(),
- HTTP_AUTH_NLM_DOMAN.getKey(),
+ HTTP_AUTH_NTLM_DOMAIN.getKey(),
SOCKS_PROXY_HOST.getKey(),
SOCKS_PROXY_PORT.getKey()};
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URISyntaxException;
-import java.util.Arrays;
+import java.util.HashSet;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.LoggerFactory;
import org.sonar.core.extension.ServiceLoaderWrapper;
+import org.sonar.core.util.SettingFormatter;
import org.sonar.process.ConfigurationUtils;
import org.sonar.process.NetworkUtilsImpl;
import org.sonar.process.ProcessProperties;
import org.sonar.process.System2;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Arrays.stream;
import static java.util.Optional.ofNullable;
import static org.sonar.core.util.SettingFormatter.fromJavaPropertyToEnvVariable;
+import static org.sonar.process.ProcessProperties.Property.LDAP_SERVERS;
+import static org.sonar.process.ProcessProperties.Property.MULTI_SERVER_LDAP_SETTINGS;
import static org.sonar.process.ProcessProperties.Property.PATH_HOME;
public class AppSettingsLoaderImpl implements AppSettingsLoader {
@Override
public AppSettings load() {
Properties p = loadPropertiesFile(homeDir);
- fetchSettingsFromEnvironment(system, p);
+ Set<String> keysOverridableFromEnv = stream(ProcessProperties.Property.values()).map(ProcessProperties.Property::getKey)
+ .collect(Collectors.toSet());
+ keysOverridableFromEnv.addAll(p.stringPropertyNames());
+
+ // 1st pass to load static properties
+ Props staticProps = reloadProperties(keysOverridableFromEnv, p);
+ keysOverridableFromEnv.addAll(getDynamicPropertiesKeys(staticProps));
+
+ // 2nd pass to load dynamic properties like `ldap.*.url` or `ldap.*.baseDn` which keys depend on values of static
+ // properties loaded in 1st step
+ Props props = reloadProperties(keysOverridableFromEnv, p);
+
+ new ProcessProperties(serviceLoaderWrapper).completeDefaults(props);
+ stream(consumers).forEach(c -> c.accept(props));
+ return new AppSettingsImpl(props);
+ }
+
+ private static Set<String> getDynamicPropertiesKeys(Props p) {
+ Set<String> dynamicPropertiesKeys = new HashSet<>();
+ String ldapServersValue = p.value(LDAP_SERVERS.getKey());
+ if (ldapServersValue != null) {
+ stream(SettingFormatter.getStringArrayBySeparator(ldapServersValue, ",")).forEach(
+ ldapServer -> MULTI_SERVER_LDAP_SETTINGS.forEach(
+ multiLdapSetting -> dynamicPropertiesKeys.add(multiLdapSetting.replace("*", ldapServer))));
+ }
+
+ return dynamicPropertiesKeys;
+ }
+
+ private Props reloadProperties(Set<String> keysOverridableFromEnv, Properties p) {
+ loadPropertiesFromEnvironment(system, p, keysOverridableFromEnv);
p.putAll(CommandLineParser.parseArguments(cliArguments));
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);
- new ProcessProperties(serviceLoaderWrapper).completeDefaults(props);
- Arrays.stream(consumers).forEach(c -> c.accept(props));
-
- return new AppSettingsImpl(props);
+ return new Props(p);
}
- private static void fetchSettingsFromEnvironment(System2 system, Properties properties) {
- Set<String> possibleSettings = Arrays.stream(ProcessProperties.Property.values()).map(ProcessProperties.Property::getKey)
- .collect(Collectors.toSet());
- possibleSettings.addAll(properties.stringPropertyNames());
- possibleSettings.forEach(key -> {
+ private static void loadPropertiesFromEnvironment(System2 system, Properties properties, Set<String> overridableSettings) {
+ overridableSettings.forEach(key -> {
String environmentVarName = fromJavaPropertyToEnvVariable(key);
Optional<String> envVarValue = ofNullable(system.getenv(environmentVarName));
envVarValue.ifPresent(value -> properties.put(key, value));
import java.io.File;
import java.util.Properties;
import org.sonar.process.ProcessId;
+import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import org.sonar.process.logging.Log4JPropertiesBuilder;
import org.sonar.process.logging.LogLevelConfig;
import org.sonar.process.logging.RootLoggerConfig;
+import static org.sonar.process.ProcessProperties.Property.LOG_CONSOLE;
import static org.sonar.process.logging.RootLoggerConfig.newRootLoggerConfigBuilder;
public class EsLogging {
- private static final String ALL_LOGS_TO_CONSOLE_PROPERTY = "sonar.log.console";
public Properties createProperties(Props props, File logDir) {
Log4JPropertiesBuilder log4JPropertiesBuilder = new Log4JPropertiesBuilder(props);
return log4JPropertiesBuilder.get();
}
-
/**
* Finds out whether we are in testing environment (usually ITs) and logs of all processes must be forward to
- * App's System.out. This is specified by the value of property {@link #ALL_LOGS_TO_CONSOLE_PROPERTY}.
+ * App's System.out. This is specified by the value of property {@link ProcessProperties.Property#LOG_CONSOLE}.
*/
private static boolean isAllLogsToConsoleEnabled(Props props) {
- return props.valueAsBoolean(ALL_LOGS_TO_CONSOLE_PROPERTY, false);
+ return props.valueAsBoolean(LOG_CONSOLE.getKey(), false);
}
}
entry("sonar.embeddedDatabase.port", "8765"));
}
+ @Test
+ public void load_multi_ldap_settings() throws IOException {
+ when(system.getenv()).thenReturn(ImmutableMap.of(
+ "LDAP_FOO_URL", "url1",
+ "LDAP_RANDOM_PROP", "5"));
+ when(system.getenv("LDAP_FOO_URL")).thenReturn("url1");
+ when(system.getenv("LDAP_RANDOM_PROP")).thenReturn("5");
+ File homeDir = temp.newFolder();
+ File propsFile = new File(homeDir, "conf/sonar.properties");
+ FileUtils.write(propsFile, "ldap.servers=foo,bar\n" +
+ "ldap.bar.url=url2", UTF_8);
+ AppSettingsLoaderImpl underTest = new AppSettingsLoaderImpl(system, new String[0], homeDir, serviceLoaderWrapper);
+
+ AppSettings settings = underTest.load();
+
+ assertThat(settings.getProps().rawProperties()).contains(
+ entry("ldap.servers", "foo,bar"),
+ entry("ldap.foo.url", "url1"),
+ entry("ldap.bar.url", "url2"));
+ }
+
@Test
public void throws_ISE_if_file_fails_to_be_loaded() throws Exception {
File homeDir = temp.newFolder();
*/
package org.sonar.process;
+import com.google.common.collect.ImmutableSet;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.HashMap;
PATH_TEMP("sonar.path.temp", "temp"),
PATH_WEB("sonar.path.web", "web"),
+ LOG_LEVEL("sonar.log.level"),
LOG_LEVEL_APP("sonar.log.level.app"),
LOG_LEVEL_WEB("sonar.log.level.web"),
LOG_LEVEL_CE("sonar.log.level.ce"),
LOG_LEVEL_ES("sonar.log.level.es"),
+ LOG_ROLLING_POLICY("sonar.log.rollingPolicy"),
+ LOG_MAX_FILES("sonar.log.maxFiles"),
+ LOG_CONSOLE("sonar.log.console"),
SEARCH_HOST("sonar.search.host", InetAddress.getLoopbackAddress().getHostAddress()),
SEARCH_PORT("sonar.search.port", "9001"),
SEARCH_MINIMUM_MASTER_NODES("sonar.search.minimumMasterNodes"),
SEARCH_INITIAL_STATE_TIMEOUT("sonar.search.initialStateTimeout"),
+ WEB_HOST("sonar.web.host"),
WEB_JAVA_OPTS("sonar.web.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError"),
WEB_JAVA_ADDITIONAL_OPTS("sonar.web.javaAdditionalOpts", ""),
+ WEB_CONTEXT("sonar.web.context"),
WEB_PORT("sonar.web.port"),
WEB_GRACEFUL_STOP_TIMEOUT("sonar.web.gracefulStopTimeOutInMs", "" + 4 * 60 * 1_000L),
+ WEB_HTTP_MIN_THREADS("sonar.web.http.minThreads"),
+ WEB_HTTP_MAX_THREADS("sonar.web.http.maxThreads"),
+ WEB_HTTP_ACCEPT_COUNT("sonar.web.http.acceptCount"),
+ WEB_SESSION_TIMEOUT_IN_MIN("sonar.web.sessionTimeoutInMinutes"),
+ WEB_SYSTEM_PASS_CODE("sonar.web.systemPasscode"),
+ WEB_ACCESSLOGS_ENABLE("sonar.web.accessLogs.enable"),
+ WEB_ACCESSLOGS_PATTERN("sonar.web.accessLogs.pattern"),
CE_JAVA_OPTS("sonar.ce.javaOpts", "-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError"),
CE_JAVA_ADDITIONAL_OPTS("sonar.ce.javaAdditionalOpts", ""),
HTTP_PROXY_USER("http.proxyUser"),
HTTP_PROXY_PASSWORD("http.proxyPassword"),
HTTP_NON_PROXY_HOSTS("http.nonProxyHosts", "localhost|127.*|[::1]"),
- HTTP_AUTH_NLM_DOMAN("http.auth.ntlm.domain"),
+ HTTP_AUTH_NTLM_DOMAIN("http.auth.ntlm.domain"),
SOCKS_PROXY_HOST("socksProxyHost"),
SOCKS_PROXY_PORT("socksProxyPort"),
SONAR_SECURITY_REALM("sonar.security.realm"),
SONAR_AUTHENTICATOR_IGNORE_STARTUP_FAILURE("sonar.authenticator.ignoreStartupFailure", "false"),
+ LDAP_SERVERS("ldap.servers"),
+ LDAP_URL("ldap.url"),
+ LDAP_BIND_DN("ldap.bindDn"),
+ LDAP_BIND_PASSWORD("ldap.bindPassword"),
+ LDAP_AUTHENTICATION("ldap.authentication"),
+ LDAP_REALM("ldap.realm"),
+ LDAP_CONTEXT_FACTORY_CLASS("ldap.contextFactoryClass"),
+ LDAP_START_TLS("ldap.StartTLS"),
+ LDAP_FOLLOW_REFERRALS("ldap.followReferrals"),
+ LDAP_USER_BASE_DN("ldap.user.baseDn"),
+ LDAP_USER_REQUEST("ldap.user.request"),
+ LDAP_USER_REAL_NAME_ATTRIBUTE("ldap.user.realNameAttribute"),
+ LDAP_USER_EMAIL_ATTRIBUTE("ldap.user.emailAttribute"),
+ LDAP_GROUP_BASE_DN("ldap.group.baseDn"),
+ LDAP_GROUP_REQUEST("ldap.group.request"),
+ LDAP_GROUP_ID_ATTRIBUTE("ldap.group.idAttribute"),
+
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"),
// whether the blue/green deployment of server is enabled
BLUE_GREEN_ENABLED("sonar.blueGreenEnabled", "false");
+ /**
+ * Properties that are defined for each LDAP server from the `ldap.servers` property
+ */
+ public static final Set<String> MULTI_SERVER_LDAP_SETTINGS = ImmutableSet.of(
+ "ldap.*.url",
+ "ldap.*.bindDn",
+ "ldap.*.bindPassword",
+ "ldap.*.authentication",
+ "ldap.*.realm",
+ "ldap.*.contextFactoryClass",
+ "ldap.*.StartTLS",
+ "ldap.*.followReferrals",
+ "ldap.*.user.baseDn",
+ "ldap.*.user.request",
+ "ldap.*.user.realNameAttribute",
+ "ldap.*.user.emailAttribute",
+ "ldap.*.group.baseDn",
+ "ldap.*.group.request",
+ "ldap.*.group.idAttribute");
+
private final String key;
private final String defaultValue;
public abstract class AbstractLogHelper {
static final Level[] ALLOWED_ROOT_LOG_LEVELS = new Level[] {Level.TRACE, Level.DEBUG, Level.INFO};
- static final String SONAR_LOG_LEVEL_PROPERTY = "sonar.log.level";
- static final String ROLLING_POLICY_PROPERTY = "sonar.log.rollingPolicy";
- static final String MAX_FILES_PROPERTY = "sonar.log.maxFiles";
private static final String PROCESS_NAME_PLACEHOLDER = "XXXX";
private static final String THREAD_ID_PLACEHOLDER = "ZZZZ";
import java.util.stream.Stream;
import org.apache.commons.lang.StringUtils;
import org.sonar.process.MessageException;
+import org.sonar.process.ProcessProperties;
import org.sonar.process.Props;
import static java.lang.String.format;
import static java.lang.String.valueOf;
+import static org.sonar.process.ProcessProperties.Property.LOG_LEVEL;
+import static org.sonar.process.ProcessProperties.Property.LOG_MAX_FILES;
+import static org.sonar.process.ProcessProperties.Property.LOG_ROLLING_POLICY;
public class Log4JPropertiesBuilder extends AbstractLogHelper {
private static final String ROOT_LOGGER_NAME = "rootLogger";
* <p>
* <ul>
* <li>the file's name will use the prefix defined in {@link RootLoggerConfig#getProcessId()#getLogFilenamePrefix()}.</li>
- * <li>the file will follow the rotation policy defined in property {@link #ROLLING_POLICY_PROPERTY} and
- * the max number of files defined in property {@link #MAX_FILES_PROPERTY}</li>
+ * <li>the file will follow the rotation policy defined in property {@link ProcessProperties.Property#LOG_ROLLING_POLICY} and
+ * the max number of files defined in property {@link org.sonar.process.ProcessProperties.Property#LOG_MAX_FILES}</li>
* <li>the logs will follow the specified log pattern</li>
* </ul>
* </p>
}
private RollingPolicy createRollingPolicy(File logDir, String filenamePrefix) {
- String rollingPolicy = props.value(ROLLING_POLICY_PROPERTY, "time:yyyy-MM-dd");
- int maxFiles = props.valueAsInt(MAX_FILES_PROPERTY, 7);
+ String rollingPolicy = props.value(LOG_ROLLING_POLICY.getKey(), "time:yyyy-MM-dd");
+ int maxFiles = props.valueAsInt(LOG_MAX_FILES.getKey(), 7);
if (maxFiles <= 0) {
maxFiles = UNLIMITED_MAX_FILES;
}
} else if ("none".equals(rollingPolicy)) {
return new NoRollingPolicy(filenamePrefix, logDir);
} else {
- throw new MessageException(format("Unsupported value for property %s: %s", ROLLING_POLICY_PROPERTY, rollingPolicy));
+ throw new MessageException(format("Unsupported value for property %s: %s", LOG_ROLLING_POLICY.getKey(), rollingPolicy));
}
}
throw new IllegalArgumentException("Value of LogLevelConfig#rootLoggerName must be \"" + ROOT_LOGGER_NAME + "\"");
}
- Level propertyValueAsLevel = getPropertyValueAsLevel(props, SONAR_LOG_LEVEL_PROPERTY);
+ Level propertyValueAsLevel = getPropertyValueAsLevel(props, LOG_LEVEL.getKey());
boolean traceGloballyEnabled = propertyValueAsLevel == Level.TRACE;
List<String> loggerNames = Stream.of(
import org.sonar.process.ProcessId;
import static java.util.Objects.requireNonNull;
+import static org.sonar.process.ProcessProperties.Property.LOG_LEVEL;
public final class LogLevelConfig {
- private static final String SONAR_LOG_LEVEL_PROPERTY = "sonar.log.level";
+ private static final String SONAR_LOG_LEVEL_PROPERTY = LOG_LEVEL.getKey();
private static final String PROCESS_NAME_PLACEHOLDER = "XXXX";
- private static final String SONAR_PROCESS_LOG_LEVEL_PROPERTY = "sonar.log.level." + PROCESS_NAME_PLACEHOLDER;
+ private static final String SONAR_PROCESS_LOG_LEVEL_PROPERTY = SONAR_LOG_LEVEL_PROPERTY + "." + PROCESS_NAME_PLACEHOLDER;
private final Map<String, List<String>> configuredByProperties;
private final Map<String, Level> configuredByHardcodedLevel;
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.LOG_CONSOLE;
+import static org.sonar.process.ProcessProperties.Property.LOG_LEVEL;
+import static org.sonar.process.ProcessProperties.Property.LOG_MAX_FILES;
+import static org.sonar.process.ProcessProperties.Property.LOG_ROLLING_POLICY;
import static org.sonar.process.ProcessProperties.Property.PATH_LOGS;
/**
*/
public class LogbackHelper extends AbstractLogHelper {
- private static final String ALL_LOGS_TO_CONSOLE_PROPERTY = "sonar.log.console";
private static final String LOGBACK_LOGGER_NAME_PATTERN = "%logger{20}";
public LogbackHelper() {
LoggerContext rootContext = getRootContext();
logLevelConfig.getConfiguredByProperties().forEach((key, value) -> applyLevelByProperty(props, rootContext.getLogger(key), value));
logLevelConfig.getConfiguredByHardcodedLevel().forEach((key, value) -> applyHardcodedLevel(rootContext, key, value));
- Level propertyValueAsLevel = getPropertyValueAsLevel(props, SONAR_LOG_LEVEL_PROPERTY);
+ Level propertyValueAsLevel = getPropertyValueAsLevel(props, LOG_LEVEL.getKey());
boolean traceGloballyEnabled = propertyValueAsLevel == Level.TRACE;
logLevelConfig.getOffUnlessTrace().forEach(logger -> applyHardUnlessTrace(rootContext, logger, traceGloballyEnabled));
return rootContext;
* <p>
* <ul>
* <li>the file's name will use the prefix defined in {@link RootLoggerConfig#getProcessId()#getLogFilenamePrefix()}.</li>
- * <li>the file will follow the rotation policy defined in property {@link #ROLLING_POLICY_PROPERTY} and
- * the max number of files defined in property {@link #MAX_FILES_PROPERTY}</li>
+ * <li>the file will follow the rotation policy defined in property {@link ProcessProperties.Property#LOG_ROLLING_POLICY} and
+ * the max number of files defined in property {@link org.sonar.process.ProcessProperties.Property#LOG_MAX_FILES}</li>
* <li>the logs will follow the specified log encoder</li>
* </ul>
* </p>
/**
* Finds out whether we are in testing environment (usually ITs) and logs of all processes must be forward to
- * App's System.out. This is specified by the value of property {@link #ALL_LOGS_TO_CONSOLE_PROPERTY}.
+ * App's System.out. This is specified by the value of property {@link ProcessProperties.Property#LOG_CONSOLE}.
*/
public boolean isAllLogsToConsoleEnabled(Props props) {
- return props.valueAsBoolean(ALL_LOGS_TO_CONSOLE_PROPERTY, false);
+ return props.valueAsBoolean(LOG_CONSOLE.getKey(), false);
}
public Level getLoggerLevel(String loggerName) {
}
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);
+ String rollingPolicy = props.value(LOG_ROLLING_POLICY.getKey(), "time:yyyy-MM-dd");
+ int maxFiles = props.valueAsInt(LOG_MAX_FILES.getKey(), 7);
File logsDir = props.nonNullValueAsFile(PATH_LOGS.getKey());
if (rollingPolicy.startsWith("time:")) {
return new NoRollingPolicy(ctx, filenamePrefix, logsDir, maxFiles);
} else {
- throw new MessageException(format("Unsupported value for property %s: %s", ROLLING_POLICY_PROPERTY, rollingPolicy));
+ throw new MessageException(format("Unsupported value for property %s: %s", LOG_ROLLING_POLICY.getKey(), rollingPolicy));
}
}
assertThat(encoder).isInstanceOf(LayoutWrappingEncoder.class);
Layout layout = ((LayoutWrappingEncoder) encoder).getLayout();
assertThat(layout).isInstanceOf(LogbackJsonLayout.class);
- assertThat(((LogbackJsonLayout)layout).getProcessKey()).isEqualTo("web");
+ assertThat(((LogbackJsonLayout) layout).getProcessKey()).isEqualTo("web");
}
private LogLevelConfig.Builder newLogLevelConfig() {
};
}
+ @Test
+ public void log_to_console_setting_missing() {
+ assertThat(underTest.isAllLogsToConsoleEnabled(new Props(new Properties()))).isFalse();
+ }
+
+ @Test
+ public void log_to_console_setting_enabled() {
+ Properties properties = new Properties();
+ properties.setProperty("sonar.log.console", "true");
+ assertThat(underTest.isAllLogsToConsoleEnabled(new Props(properties))).isTrue();
+ }
+
+ @Test
+ public void log_to_console_setting_disabled() {
+ Properties properties = new Properties();
+ properties.setProperty("sonar.log.console", "false");
+ assertThat(underTest.isAllLogsToConsoleEnabled(new Props(properties))).isFalse();
+ }
+
public static class MemoryAppender extends AppenderBase<ILoggingEvent> {
private static final List<ILoggingEvent> LOGS = new ArrayList<>();
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.api.CoreProperties.SERVER_BASE_URL;
+import static org.sonar.process.ProcessProperties.Property.WEB_CONTEXT;
+import static org.sonar.process.ProcessProperties.Property.WEB_HOST;
@ComputeEngineSide
@ServerSide
public class UrlSettings {
- private static final String PROPERTY_CONTEXT = "sonar.web.context";
-
private static final int DEFAULT_PORT = 9000;
private static final int DEFAULT_HTTP_PORT = 80;
private static final String ALL_IPS_HOST = "0.0.0.0";
public UrlSettings(Configuration config) {
this.config = config;
- this.contextPath = config.get(PROPERTY_CONTEXT).orElse("")
+ this.contextPath = config.get(WEB_CONTEXT.getKey()).orElse("")
// Remove trailing slashes
.replaceFirst("(\\/+)$", "");
}
}
private String computeBaseUrl() {
- String host = config.get("sonar.web.host").orElse("");
+ String host = config.get(WEB_HOST.getKey()).orElse("");
int port = config.getInt("sonar.web.port").orElse(0);
- String context = config.get(PROPERTY_CONTEXT).orElse("");
+ String context = config.get(WEB_CONTEXT.getKey()).orElse("");
StringBuilder res = new StringBuilder();
res.append("http://");
package org.sonar.server.setting;
import com.google.common.annotations.VisibleForTesting;
-import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.apache.ibatis.exceptions.PersistenceException;
import org.sonar.api.CoreProperties;
import org.sonar.api.ce.ComputeEngineSide;
-import org.sonar.api.config.internal.Encryption;
-import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.Encryption;
import org.sonar.api.config.internal.Settings;
import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.System2;
-import org.sonar.core.util.SettingFormatter;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
@ServerSide
public class ThreadLocalSettings extends Settings {
private final Properties systemProps = new Properties();
- private final Properties corePropsFromEnvVariables = new Properties();
private static final ThreadLocal<Map<String, String>> CACHE = new ThreadLocal<>();
private Map<String, String> getPropertyDbFailureCache = Collections.emptyMap();
private Map<String, String> getPropertiesDbFailureCache = Collections.emptyMap();
private SettingLoader settingLoader;
- private System2 system2;
- public ThreadLocalSettings(System2 system2, PropertyDefinitions definitions, Properties props) {
- this(system2, definitions, props, new NopSettingLoader());
+ public ThreadLocalSettings(PropertyDefinitions definitions, Properties props) {
+ this(definitions, props, new NopSettingLoader());
}
@VisibleForTesting
- ThreadLocalSettings(System2 system2, PropertyDefinitions definitions, Properties props, SettingLoader settingLoader) {
+ ThreadLocalSettings(PropertyDefinitions definitions, Properties props, SettingLoader settingLoader) {
super(definitions, new Encryption(null));
- this.system2 = system2;
this.settingLoader = settingLoader;
-
- resolveCorePropertiesFromEnvironment();
props.forEach((k, v) -> systemProps.put(k, v == null ? null : v.toString().trim()));
// TODO something wrong about lifecycle here. It could be improved
return Optional.of(value);
}
- value = corePropsFromEnvVariables.getProperty(key);
- if (value != null) {
- return Optional.of(value);
+ Optional<String> envVal = getDefinitions().getValueFromEnv(key);
+ if (envVal.isPresent()) {
+ return envVal;
}
Map<String, String> dbProps = CACHE.get();
public Map<String, String> getProperties() {
Map<String, String> result = new HashMap<>();
loadAll(result);
- corePropsFromEnvVariables.forEach((k, v) -> result.put((String) k, (String) v));
+ getDefinitions().getAllPropertiesSetInEnv().forEach(result::put);
systemProps.forEach((key, value) -> result.put((String) key, (String) value));
return unmodifiableMap(result);
}
appendTo.putAll(getPropertiesDbFailureCache);
}
}
-
- private void resolveCorePropertiesFromEnvironment() {
- corePropsFromEnvVariables.putAll(this.getDefinitions().getAll()
- .stream()
- .map(PropertyDefinition::key)
- .flatMap(p -> {
- String envVar = SettingFormatter.fromJavaPropertyToEnvVariable(p);
- String envVarValue = system2.envVariable(envVar);
- if (envVarValue != null) {
- return Stream.of(new AbstractMap.SimpleEntry<>(p, envVarValue));
- } else {
- return Stream.empty();
- }
- })
- .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)));
- }
}
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.config.PropertyDefinition.builder;
private final String nonDeclaredKey = RandomStringUtils.randomAlphabetic(3);
private final String nonMultivalueKey = RandomStringUtils.randomAlphabetic(3);
private final String multivalueKey = RandomStringUtils.randomAlphabetic(3);
- private final MapSettings settings = new MapSettings(new PropertyDefinitions(
+ private final MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE,
builder(nonMultivalueKey).multiValues(false).build(),
builder(multivalueKey).multiValues(true).build()));
import org.junit.rules.ExpectedException;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import org.sonar.core.config.CorePropertyDefinitions;
import static org.assertj.core.api.Assertions.assertThat;
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private MapSettings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all()));
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, CorePropertyDefinitions.all()));
@Test
public void use_default_context_path() {
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
public void childSettings_should_retrieve_parent_settings() {
String multipleValuesKey = randomAlphanumeric(19);
PropertyDefinition multipleValues = PropertyDefinition.builder(multipleValuesKey).multiValues(true).build();
- MapSettings parent = new MapSettings(new PropertyDefinitions(Collections.singletonList(multipleValues)));
+ MapSettings parent = new MapSettings(new PropertyDefinitions(System2.INSTANCE, Collections.singletonList(multipleValues)));
ChildSettings underTest = new ChildSettings(parent);
parent.setProperty(randomAlphanumeric(10), randomAlphanumeric(20));
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.Property;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.utils.System2;
import org.sonar.core.config.CorePropertyDefinitions;
@Test
public void can_not_add_property_if_no_cache() {
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.set("foo", "wiz");
@Test
public void can_not_remove_system_property_if_no_cache() {
- underTest = create(ImmutableMap.of("foo", "bar"));
+ underTest = create(system, ImmutableMap.of("foo", "bar"));
underTest.remove("foo");
@Test
public void add_property_to_cache() {
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.load();
underTest.set("foo", "bar");
@Test
public void remove_property_from_cache() {
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.load();
underTest.set("foo", "bar");
@Test
public void getProperties_does_not_fail_on_duplicated_key() {
insertPropertyIntoDb("foo", "from_db");
- underTest = create(ImmutableMap.of("foo", "from_system"));
+ underTest = create(system, ImmutableMap.of("foo", "from_system"));
assertThat(underTest.get("foo")).hasValue("from_system");
assertThat(underTest.getProperties().get("foo")).isEqualTo("from_system");
public void load_encryption_secret_key_from_system_properties() throws Exception {
File secretKey = temp.newFile();
- underTest = create(ImmutableMap.of("foo", "bar", "sonar.secretKeyPath", secretKey.getAbsolutePath()));
+ underTest = create(system, ImmutableMap.of("foo", "bar", "sonar.secretKeyPath", secretKey.getAbsolutePath()));
assertThat(underTest.getEncryption().hasSecretKey()).isTrue();
}
@Test
public void encryption_secret_key_is_undefined_by_default() {
- underTest = create(ImmutableMap.of("foo", "bar", "sonar.secretKeyPath", "unknown/path/to/sonar-secret.txt"));
+ underTest = create(system, ImmutableMap.of("foo", "bar", "sonar.secretKeyPath", "unknown/path/to/sonar-secret.txt"));
assertThat(underTest.getEncryption().hasSecretKey()).isFalse();
}
- private ThreadLocalSettings create(Map<String, String> systemProps) {
+ private ThreadLocalSettings create(System2 system, Map<String, String> systemProps) {
+ PropertyDefinitions definitions = new PropertyDefinitions(system);
+ definitions.addComponents(CorePropertyDefinitions.all());
+ definitions.addComponent(new AnnotatedTestClass());
+
Properties p = new Properties();
p.putAll(systemProps);
- return new ThreadLocalSettings(system, new PropertyDefinitions(CorePropertyDefinitions.all()), p, dbSettingLoader);
+ return new ThreadLocalSettings(definitions, p, dbSettingLoader);
}
@Test
public void load_system_properties() {
- underTest = create(ImmutableMap.of("foo", "1", "bar", "2"));
+ underTest = create(system, ImmutableMap.of("foo", "1", "bar", "2"));
assertThat(underTest.get("foo")).hasValue("1");
assertThat(underTest.get("missing")).isNotPresent();
@Test
public void load_core_properties_from_environment() {
when(system.envVariable("SONAR_FORCEAUTHENTICATION")).thenReturn("true");
- underTest = create(ImmutableMap.of());
+ when(system.envVariable("SONAR_ANNOTATION_TEST_PROP")).thenReturn("113");
+ underTest = create(system, ImmutableMap.of());
assertThat(underTest.get("sonar.forceAuthentication")).hasValue("true");
+ assertThat(underTest.get("sonar.annotation.test.prop")).hasValue("113");
assertThat(underTest.get("missing")).isNotPresent();
- assertThat(underTest.getProperties()).containsOnly(entry("sonar.forceAuthentication", "true"));
+ assertThat(underTest.getProperties()).containsOnly(entry("sonar.forceAuthentication", "true"), entry("sonar.annotation.test.prop", "113"));
}
@Test
public void database_properties_are_not_cached_by_default() {
insertPropertyIntoDb("foo", "from db");
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
assertThat(underTest.get("foo")).hasValue("from db");
@Test
public void system_settings_have_precedence_over_database() {
insertPropertyIntoDb("foo", "from db");
- underTest = create(ImmutableMap.of("foo", "from system"));
+ underTest = create(system, ImmutableMap.of("foo", "from system"));
assertThat(underTest.get("foo")).hasValue("from system");
}
public void getProperties_are_all_properties_with_value() {
insertPropertyIntoDb("db", "from db");
insertPropertyIntoDb("empty", "");
- underTest = create(ImmutableMap.of("system", "from system"));
+ underTest = create(system, ImmutableMap.of("system", "from system"));
assertThat(underTest.getProperties()).containsOnly(entry("system", "from system"), entry("db", "from db"), entry("empty", ""));
}
@Test
public void getProperties_is_not_cached_in_thread_cache() {
insertPropertyIntoDb("foo", "bar");
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.load();
assertThat(underTest.getProperties())
public void load_creates_a_thread_specific_cache() throws InterruptedException {
insertPropertyIntoDb(A_KEY, "v1");
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.load();
assertThat(underTest.get(A_KEY)).hasValue("v1");
@Test
public void load_invalidates_cache_if_unload_has_not_been_called() {
- underTest = create(emptyMap());
+ underTest = create(system, emptyMap());
underTest.load();
underTest.set("foo", "bar");
// unload() is not called
@Test
public void keep_in_thread_cache_the_fact_that_a_property_is_not_in_db() {
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.load();
assertThat(underTest.get(A_KEY)).isNotPresent();
@Test
public void change_setting_loader() {
- underTest = new ThreadLocalSettings(system, new PropertyDefinitions(), new Properties());
+ underTest = new ThreadLocalSettings(new PropertyDefinitions(system), new Properties());
assertThat(underTest.getSettingLoader()).isNotNull();
@Test
public void cache_db_calls_if_property_is_not_persisted() {
- underTest = create(Collections.emptyMap());
+ underTest = create(system, Collections.emptyMap());
underTest.load();
assertThat(underTest.get(A_KEY)).isNotPresent();
assertThat(underTest.get(A_KEY)).isNotPresent();
SettingLoader settingLoaderMock = mock(SettingLoader.class);
PersistenceException toBeThrown = new PersistenceException("Faking an error connecting to DB");
doThrow(toBeThrown).when(settingLoaderMock).loadAll();
- underTest = new ThreadLocalSettings(system, new PropertyDefinitions(), new Properties(), settingLoaderMock);
+ underTest = new ThreadLocalSettings(new PropertyDefinitions(system), new Properties(), settingLoaderMock);
assertThat(underTest.getProperties())
.isEmpty();
SettingLoader settingLoaderMock = mock(SettingLoader.class);
PersistenceException toBeThrown = new PersistenceException("Faking an error connecting to DB");
doThrow(toBeThrown).when(settingLoaderMock).loadAll();
- underTest = new ThreadLocalSettings(system, new PropertyDefinitions(), new Properties(), settingLoaderMock);
+ underTest = new ThreadLocalSettings(new PropertyDefinitions(system), new Properties(), settingLoaderMock);
underTest.load();
assertThat(underTest.getProperties())
.doAnswer(invocationOnMock -> ImmutableMap.of(key, value2))
.when(settingLoaderMock)
.loadAll();
- underTest = new ThreadLocalSettings(system, new PropertyDefinitions(), new Properties(), settingLoaderMock);
+ underTest = new ThreadLocalSettings(new PropertyDefinitions(system), new Properties(), settingLoaderMock);
underTest.load();
assertThat(underTest.getProperties())
PersistenceException toBeThrown = new PersistenceException("Faking an error connecting to DB");
String key = randomAlphanumeric(3);
doThrow(toBeThrown).when(settingLoaderMock).load(key);
- underTest = new ThreadLocalSettings(system, new PropertyDefinitions(), new Properties(), settingLoaderMock);
+ underTest = new ThreadLocalSettings(new PropertyDefinitions(system), new Properties(), settingLoaderMock);
assertThat(underTest.get(key)).isEmpty();
}
PersistenceException toBeThrown = new PersistenceException("Faking an error connecting to DB");
String key = randomAlphanumeric(3);
doThrow(toBeThrown).when(settingLoaderMock).load(key);
- underTest = new ThreadLocalSettings(system, new PropertyDefinitions(), new Properties(), settingLoaderMock);
+ underTest = new ThreadLocalSettings(new PropertyDefinitions(system), new Properties(), settingLoaderMock);
underTest.load();
assertThat(underTest.get(key)).isEmpty();
return unmodifiableMap(map);
}
}
+
+ @org.sonar.api.Properties({
+ @Property(
+ key = "sonar.annotation.test.prop",
+ defaultValue = "60",
+ name = "Test annotation property",
+ global = false)
+ })
+ class AnnotatedTestClass {
+ }
}
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.time.DateUtils.addSeconds;
+import static org.sonar.process.ProcessProperties.Property.WEB_SESSION_TIMEOUT_IN_MIN;
import static org.sonar.server.authentication.Cookies.findCookie;
import static org.sonar.server.authentication.Cookies.newCookieBuilder;
@ServerSide
public class JwtHttpHandler {
-
- private static final String SESSION_TIMEOUT_IN_MINUTES_PROPERTY = "sonar.web.sessionTimeoutInMinutes";
private static final int SESSION_TIMEOUT_DEFAULT_VALUE_IN_MINUTES = 3 * 24 * 60;
private static final int MAX_SESSION_TIMEOUT_IN_MINUTES = 3 * 30 * 24 * 60;
}
private static int getSessionTimeoutInSeconds(Configuration config) {
- int minutes = config.getInt(SESSION_TIMEOUT_IN_MINUTES_PROPERTY).orElse(SESSION_TIMEOUT_DEFAULT_VALUE_IN_MINUTES);
- checkArgument(minutes > 0, "Property %s must be strictly positive. Got %s", SESSION_TIMEOUT_IN_MINUTES_PROPERTY, minutes);
- checkArgument(minutes <= MAX_SESSION_TIMEOUT_IN_MINUTES, "Property %s must not be greater than 3 months (%s minutes). Got %s minutes",
- SESSION_TIMEOUT_IN_MINUTES_PROPERTY, MAX_SESSION_TIMEOUT_IN_MINUTES, minutes);
+ int minutes = config.getInt(WEB_SESSION_TIMEOUT_IN_MIN.getKey()).orElse(SESSION_TIMEOUT_DEFAULT_VALUE_IN_MINUTES);
+ checkArgument(minutes > 0, "Property %s must be strictly positive. Got %s", WEB_SESSION_TIMEOUT_IN_MIN.getKey(), minutes);
+ checkArgument(minutes <= MAX_SESSION_TIMEOUT_IN_MINUTES,
+ "Property %s must not be greater than 3 months (%s minutes). Got %s minutes", WEB_SESSION_TIMEOUT_IN_MIN.getKey(),
+ MAX_SESSION_TIMEOUT_IN_MINUTES, minutes);
return minutes * 60;
}
import org.sonar.api.server.ws.Request;
import org.sonar.api.utils.log.Loggers;
+import static org.sonar.process.ProcessProperties.Property.WEB_SYSTEM_PASS_CODE;
+
@ServerSide
public class SystemPasscodeImpl implements SystemPasscode, Startable {
public static final String PASSCODE_HTTP_HEADER = "X-Sonar-Passcode";
- public static final String PASSCODE_CONF_PROPERTY = "sonar.web.systemPasscode";
private final Configuration configuration;
private String configuredPasscode;
@Override
public void start() {
- Optional<String> passcodeOpt = configuration.get(PASSCODE_CONF_PROPERTY)
+ Optional<String> passcodeOpt = configuration.get(WEB_SYSTEM_PASS_CODE.getKey())
// if present, result is never empty string
.map(StringUtils::trimToNull);
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.utils.System2;
import static java.util.Collections.singleton;
import static org.mockito.ArgumentMatchers.anyCollection;
@Before
public void setUp() {
- MapSettings settings = new MapSettings(new PropertyDefinitions(NotificationDaemon.class)).setProperty("sonar.notifications.delay", 1L);
+ MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, NotificationDaemon.class)).setProperty("sonar.notifications.delay", 1L);
underTest = new NotificationDaemon(settings.asConfig(), manager, notificationService);
inOrder = Mockito.inOrder(notificationService);
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.internal.Settings;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.config.internal.Settings;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
+import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import static org.assertj.core.api.Assertions.assertThat;
when(qualityGateChange.getType()).thenReturn("qgate-changes");
when(manager.getFromQueue()).thenReturn(notification).thenReturn(null);
- MapSettings settings = new MapSettings(new PropertyDefinitions(NotificationDaemon.class)).setProperty("sonar.notifications.delay", 1L);
+ MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, NotificationDaemon.class)).setProperty("sonar.notifications.delay", 1L);
underTest = new NotificationDaemon(settings.asConfig(), manager, service);
}
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.internal.Settings;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.config.internal.Settings;
+import org.sonar.api.utils.System2;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
import static org.apache.commons.lang.StringUtils.repeat;
private static final String PASSWORD_PROPERTY = "sonar.password";
- private PropertyDefinitions defs = new PropertyDefinitions(PropertyDefinition.builder(PASSWORD_PROPERTY).type(PropertyType.PASSWORD).build());
+ private PropertyDefinitions defs = new PropertyDefinitions(System2.INSTANCE, PropertyDefinition.builder(PASSWORD_PROPERTY).type(PropertyType.PASSWORD).build());
private Settings settings = new MapSettings(defs);
private SettingsSection underTest = new SettingsSection(settings);
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.utils.System2;
import org.sonar.db.property.PropertiesDao;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
public class RenameDeprecatedPropertyKeysTest {
@Test
public void should_rename_deprecated_keys() {
PropertiesDao dao = mock(PropertiesDao.class);
- PropertyDefinitions definitions = new PropertyDefinitions(FakeExtension.class);
+ PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE, FakeExtension.class);
RenameDeprecatedPropertyKeys task = new RenameDeprecatedPropertyKeys(dao, definitions);
task.start();
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.ce.queue.CeQueue;
+import org.sonar.process.ProcessProperties;
import org.sonar.server.user.AbstractUserSession;
import org.sonar.server.user.SystemPasscode;
-import org.sonar.server.user.SystemPasscodeImpl;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.Ce;
public void define(WebService.NewController controller) {
controller.createAction("info")
.setDescription("Gets information about Compute Engine. Requires the system administration permission or " +
- "system passcode (see " + SystemPasscodeImpl.PASSCODE_CONF_PROPERTY + " in sonar.properties).")
+ "system passcode (see " + ProcessProperties.Property.WEB_SYSTEM_PASS_CODE + " in sonar.properties).")
.setSince("7.2")
.setInternal(true)
.setHandler(this)
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.ce.queue.CeQueue;
+import org.sonar.process.ProcessProperties;
import org.sonar.server.user.AbstractUserSession;
import org.sonar.server.user.SystemPasscode;
-import org.sonar.server.user.SystemPasscodeImpl;
import org.sonar.server.user.UserSession;
public class PauseAction implements CeWsAction {
public void define(WebService.NewController controller) {
controller.createAction("pause")
.setDescription("Requests pause of Compute Engine workers. Requires the system administration permission or " +
- "system passcode (see " + SystemPasscodeImpl.PASSCODE_CONF_PROPERTY + " in sonar.properties).")
+ "system passcode (see " + ProcessProperties.Property.WEB_SYSTEM_PASS_CODE + " in sonar.properties).")
.setSince("7.2")
.setInternal(true)
.setHandler(this)
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.ce.queue.CeQueue;
+import org.sonar.process.ProcessProperties;
import org.sonar.server.user.AbstractUserSession;
import org.sonar.server.user.SystemPasscode;
-import org.sonar.server.user.SystemPasscodeImpl;
import org.sonar.server.user.UserSession;
public class ResumeAction implements CeWsAction {
public void define(WebService.NewController controller) {
controller.createAction("resume")
.setDescription("Resumes pause of Compute Engine workers. Requires the system administration permission or " +
- "system passcode (see " + SystemPasscodeImpl.PASSCODE_CONF_PROPERTY + " in sonar.properties).")
+ "system passcode (see " + ProcessProperties.Property.WEB_SYSTEM_PASS_CODE + " in sonar.properties).")
.setSince("7.2")
.setInternal(true)
.setHandler(this)
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.utils.System2;
import org.sonar.core.config.CorePropertyDefinitions;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
when(qGateComputer.getMetricsRelatedTo(qualityGate)).thenReturn(singleton(CoreMetrics.ALERT_STATUS_KEY));
when(qGateComputer.refreshGateStatus(eq(project), same(qualityGate), any(MeasureMatrix.class)))
.thenReturn(newQualityGate);
- MapSettings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all()));
+ MapSettings settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, CorePropertyDefinitions.all()));
ProjectConfigurationLoader configurationLoader = new TestProjectConfigurationLoader(settings.asConfig());
LiveMeasureComputerImpl underTest = new LiveMeasureComputerImpl(db.getDbClient(), formulaFactory, qGateComputer, configurationLoader, projectIndexer);
private DbClient dbClient = db.getDbClient();
private ComponentDbTester componentDb = new ComponentDbTester(db);
private ComponentDto project;
- private PropertyDefinitions propertyDefinitions = new PropertyDefinitions();
+ private PropertyDefinitions propertyDefinitions = new PropertyDefinitions(System2.INSTANCE);
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private SettingsWsSupport support = new SettingsWsSupport(defaultOrganizationProvider, userSession);
private WsActionTester ws = new WsActionTester(
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
private ComponentFinder componentFinder = TestComponentFinder.from(db);
- private PropertyDefinitions definitions = new PropertyDefinitions();
+ private PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
private SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
private SettingValidations settingValidations = new SettingValidations(definitions, dbClient, i18n);
private ComponentDto project;
private ComponentFinder componentFinder = TestComponentFinder.from(db);
private I18nRule i18n = new I18nRule();
- private PropertyDefinitions definitions = new PropertyDefinitions();
+ private PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
private FakeSettingsNotifier settingsChangeNotifier = new FakeSettingsNotifier(dbClient);
private SettingsUpdater settingsUpdater = new SettingsUpdater(dbClient, definitions);
private SettingValidations validations = new SettingValidations(definitions, dbClient, i18n);
PropertyDbTester propertyDb = new PropertyDbTester(db);
ComponentDbTester componentDb = new ComponentDbTester(db);
- PropertyDefinitions definitions = new PropertyDefinitions();
+ PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
ComponentDto project;
SettingsUpdater underTest= new SettingsUpdater(dbClient, definitions);
private DbClient dbClient = db.getDbClient();
private PropertyDbTester propertyDb = new PropertyDbTester(db);
private ComponentDbTester componentDb = new ComponentDbTester(db);
- private PropertyDefinitions definitions = new PropertyDefinitions();
+ private PropertyDefinitions definitions = new PropertyDefinitions(System2.INSTANCE);
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private SettingsWsSupport support = new SettingsWsSupport(defaultOrganizationProvider, userSession);
private ComponentDto project;
import org.sonar.process.Props;
import static java.lang.String.format;
+import static org.sonar.process.ProcessProperties.Property.WEB_HOST;
+import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_ACCEPT_COUNT;
+import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_MAX_THREADS;
+import static org.sonar.process.ProcessProperties.Property.WEB_HTTP_MIN_THREADS;
/**
* Configuration of Tomcat connectors
Connector connector = new Connector(HTTP_PROTOCOL);
connector.setURIEncoding("UTF-8");
- connector.setProperty("address", props.value("sonar.web.host", "0.0.0.0"));
+ connector.setProperty("address", props.value(WEB_HOST.getKey(), "0.0.0.0"));
connector.setProperty("socket.soReuseAddress", "true");
// see https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
private static void configurePool(Props props, Connector connector) {
connector.setProperty("acceptorThreadCount", String.valueOf(2));
- connector.setProperty("minSpareThreads", String.valueOf(props.valueAsInt("sonar.web.http.minThreads", 5)));
- connector.setProperty("maxThreads", String.valueOf(props.valueAsInt("sonar.web.http.maxThreads", 50)));
- connector.setProperty("acceptCount", String.valueOf(props.valueAsInt("sonar.web.http.acceptCount", 25)));
+ connector.setProperty("minSpareThreads", String.valueOf(props.valueAsInt(WEB_HTTP_MIN_THREADS.getKey(), 5)));
+ connector.setProperty("maxThreads", String.valueOf(props.valueAsInt(WEB_HTTP_MAX_THREADS.getKey(), 50)));
+ connector.setProperty("acceptCount", String.valueOf(props.valueAsInt(WEB_HTTP_ACCEPT_COUNT.getKey(), 25)));
}
private static void configureCompression(Connector connector) {
import static java.lang.String.format;
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.WEB_CONTEXT;
/**
* Configures Tomcat contexts:
* </ul>
*/
public class TomcatContexts {
-
- private static final String PROPERTY_CONTEXT = "sonar.web.context";
private static final String WEB_DEPLOY_PATH_RELATIVE_TO_DATA_DIR = "web/deploy";
private final Fs fs;
}
static String getContextPath(Props props) {
- String context = props.value(PROPERTY_CONTEXT, "");
+ String context = props.value(WEB_CONTEXT.getKey(), "");
if ("/".equals(context)) {
context = "";
} else if (!"".equals(context) && context != null && !context.startsWith("/")) {
- throw MessageException.of(format("Value of '%s' must start with a forward slash: '%s'", PROPERTY_CONTEXT, context));
+ throw MessageException.of(format("Value of '%s' must start with a forward slash: '%s'", WEB_CONTEXT.getKey(), context));
}
return context;
}
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.System2;
import static com.google.common.collect.ImmutableList.copyOf;
import static java.util.Objects.requireNonNull;
}
protected ComponentContainer(MutablePicoContainer picoContainer) {
- this(picoContainer, new PropertyDefinitions());
+ this(picoContainer, new PropertyDefinitions(System2.INSTANCE));
}
protected ComponentContainer(MutablePicoContainer picoContainer, PropertyDefinitions propertyDefinitions) {
package org.sonar.core.util;
import java.util.Locale;
+import org.apache.commons.lang.StringUtils;
+
+import static org.apache.commons.lang.StringUtils.trim;
public final class SettingFormatter {
private SettingFormatter() {
public static String fromJavaPropertyToEnvVariable(String property) {
return property.toUpperCase(Locale.ENGLISH).replace('.', '_').replace('-', '_');
}
+
+ /**
+ * Value is split and trimmed.
+ */
+ public static String[] getStringArrayBySeparator(String value, String separator) {
+ String[] strings = StringUtils.splitByWholeSeparator(value, separator);
+ String[] result = new String[strings.length];
+ for (int index = 0; index < strings.length; index++) {
+ result[index] = trim(strings[index]);
+ }
+ return result;
+ }
}
String output = SettingFormatter.fromJavaPropertyToEnvVariable("some.randomProperty-123.test");
assertThat(output).isEqualTo("SOME_RANDOMPROPERTY_123_TEST");
}
+
+ @Test
+ public void test_getStringArrayBySeparator_on_input_with_separator() {
+ String[] result = SettingFormatter.getStringArrayBySeparator(" abc, DeF , ghi", ",");
+ assertThat(result).containsExactly("abc", "DeF", "ghi");
+ }
+
+ @Test
+ public void test_getStringArrayBySeparator_on_input_without_separator() {
+ String[] result = SettingFormatter.getStringArrayBySeparator(" abc, DeF , ghi", ";");
+ assertThat(result).containsExactly("abc, DeF , ghi");
+ }
}
import java.util.Optional;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.utils.System2;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
private final ConfigurationBridge configurationBridge;
public MapSettings() {
- this(new PropertyDefinitions());
+ this(new PropertyDefinitions(System2.INSTANCE));
}
public MapSettings(PropertyDefinitions definitions) {
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
@Before
public void init_definitions() {
- definitions = new PropertyDefinitions();
+ definitions = new PropertyDefinitions(System2.INSTANCE);
definitions.addComponent(Init.class);
}
public void set_property_string_throws_NPE_if_key_is_null() {
String key = randomAlphanumeric(3);
- Settings underTest = new MapSettings(new PropertyDefinitions(singletonList(PropertyDefinition.builder(key).multiValues(true).build())));
+ Settings underTest = new MapSettings(new PropertyDefinitions(System2.INSTANCE, singletonList(PropertyDefinition.builder(key).multiValues(true).build())));
expectKeyNullNPE();
public void set_property_string_array_trims_key() {
String key = randomAlphanumeric(3);
- Settings underTest = new MapSettings(new PropertyDefinitions(singletonList(PropertyDefinition.builder(key).multiValues(true).build())));
+ Settings underTest = new MapSettings(new PropertyDefinitions(System2.INSTANCE, singletonList(PropertyDefinition.builder(key).multiValues(true).build())));
Random random = new Random();
String blankBefore = blank(random);
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.Properties;
import org.sonar.api.Property;
-import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.api.utils.System2;
import static java.util.Objects.requireNonNull;
+import static java.util.Optional.ofNullable;
/**
* Metadata of all the properties declared by plugins
public final class PropertyDefinitions {
private final Map<String, PropertyDefinition> definitions = new HashMap<>();
+ private final Map<String, String> propertyValueFromEnvironment = new HashMap<>();
private final Map<String, Category> categories = new HashMap<>();
private final Map<String, SubCategory> subcategories = new HashMap<>();
// deprecated key -> new key
private final Map<String, String> deprecatedKeys = new HashMap<>();
- public PropertyDefinitions(Object... components) {
+ private final System2 system;
+
+ public PropertyDefinitions(System2 system, Object... components) {
+ this.system = system;
addComponents(Arrays.asList(components));
}
- public PropertyDefinitions(Collection<PropertyDefinition> components) {
+ public PropertyDefinitions(System2 system, Collection<PropertyDefinition> components) {
+ this.system = system;
addComponents(components);
}
private PropertyDefinitions add(PropertyDefinition definition, String defaultCategory) {
if (!definitions.containsKey(definition.key())) {
definitions.put(definition.key(), definition);
+ String envVar = definition.key().toUpperCase(Locale.ENGLISH).replace('.', '_').replace('-', '_');
+ ofNullable(system.envVariable(envVar)).ifPresent(value -> propertyValueFromEnvironment.put(definition.key(), value));
String category = StringUtils.defaultIfBlank(definition.category(), defaultCategory);
categories.put(definition.key(), new Category(category));
String subcategory = StringUtils.defaultIfBlank(definition.subCategory(), category);
return definitions.get(validKey(key));
}
+ public Optional<String> getValueFromEnv(String key) {
+ return ofNullable(propertyValueFromEnvironment.get(key));
+ }
+
+ public Map<String, String> getAllPropertiesSetInEnv() {
+ return new HashMap<>(propertyValueFromEnvironment);
+ }
+
public Collection<PropertyDefinition> getAll() {
return definitions.values();
}
*/
package org.sonar.api.config;
+import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.utils.System2;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class PropertyDefinitionsTest {
@Rule
PropertyDefinition.builder("foo").name("Foo").build(),
PropertyDefinition.builder("one").name("One").build(),
PropertyDefinition.builder("two").name("Two").defaultValue("2").build());
- PropertyDefinitions def = new PropertyDefinitions(list);
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE, list);
assertProperties(def);
}
@Test
public void should_inspect_plugin_objects() {
- PropertyDefinitions def = new PropertyDefinitions(
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE,
PropertyDefinition.builder("foo").name("Foo").build(),
PropertyDefinition.builder("one").name("One").build(),
PropertyDefinition.builder("two").name("Two").defaultValue("2").build());
@Test
public void should_inspect_annotation_plugin_objects() {
- PropertyDefinitions def = new PropertyDefinitions(new PluginWithProperty(), new PluginWithProperties());
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE, new PluginWithProperty(), new PluginWithProperties());
assertProperties(def);
}
@Test
public void should_inspect_plugin_classes() {
- PropertyDefinitions def = new PropertyDefinitions(PluginWithProperty.class, PluginWithProperties.class);
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE, PluginWithProperty.class, PluginWithProperties.class);
assertProperties(def);
}
@Test
public void test_categories() {
- PropertyDefinitions def = new PropertyDefinitions(
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE,
PropertyDefinition.builder("inCateg").name("In Categ").category("categ").build(),
PropertyDefinition.builder("noCateg").name("No categ").build());
@Test
public void test_categories_on_annotation_plugin() {
- PropertyDefinitions def = new PropertyDefinitions(Categories.class);
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE, Categories.class);
assertThat(def.getCategory("inCateg")).isEqualTo("categ");
assertThat(def.getCategory("noCateg")).isEqualTo("");
@Test
public void test_default_category() {
- PropertyDefinitions def = new PropertyDefinitions();
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE);
def.addComponent(PropertyDefinition.builder("inCateg").name("In Categ").category("categ").build(), "default");
def.addComponent(PropertyDefinition.builder("noCateg").name("No categ").build(), "default");
@Test
public void test_default_category_on_annotation_plugin() {
- PropertyDefinitions def = new PropertyDefinitions();
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE);
def.addComponent(Categories.class, "default");
assertThat(def.getCategory("inCateg")).isEqualTo("categ");
assertThat(def.getCategory("noCateg")).isEqualTo("default");
@Test
public void should_return_special_categories() {
- PropertyDefinitions def = new PropertyDefinitions();
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE);
assertThat(def.propertiesByCategory(null).get(new Category("general")).keySet()).containsOnly(new SubCategory("email"));
assertThat(def.propertiesByCategory(null).get(new Category("general")).keySet().iterator().next().isSpecial()).isTrue();
@Test
public void should_group_by_category() {
- PropertyDefinitions def = new PropertyDefinitions(
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE,
PropertyDefinition.builder("global1").name("Global1").category("catGlobal1").build(),
PropertyDefinition.builder("global2").name("Global2").category("catGlobal1").build(),
PropertyDefinition.builder("global3").name("Global3").category("catGlobal2").build(),
@Test
public void should_group_by_subcategory() {
- PropertyDefinitions def = new PropertyDefinitions(
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE,
PropertyDefinition.builder("global1").name("Global1").category("catGlobal1").subCategory("sub1").build(),
PropertyDefinition.builder("global2").name("Global2").category("catGlobal1").subCategory("sub2").build(),
PropertyDefinition.builder("global3").name("Global3").category("catGlobal1").build(),
@Test
public void should_group_by_category_on_annotation_plugin() {
- PropertyDefinitions def = new PropertyDefinitions(ByCategory.class);
+ PropertyDefinitions def = new PropertyDefinitions(System2.INSTANCE, ByCategory.class);
assertThat(def.propertiesByCategory(null).keySet()).contains(new Category("catglobal1"), new Category("catglobal2"));
assertThat(def.propertiesByCategory(Qualifiers.PROJECT).keySet()).containsOnly(new Category("catproject"));
@Test
public void validKey_throws_NPE_if_key_is_null() {
- PropertyDefinitions underTest = new PropertyDefinitions();
+ PropertyDefinitions underTest = new PropertyDefinitions(System2.INSTANCE);
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("key can't be null");
@Test
public void get_throws_NPE_if_key_is_null() {
- PropertyDefinitions underTest = new PropertyDefinitions();
+ PropertyDefinitions underTest = new PropertyDefinitions(System2.INSTANCE);
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("key can't be null");
Random random = new Random();
String key = RandomStringUtils.randomAlphanumeric(4);
String deprecatedKey = RandomStringUtils.randomAlphanumeric(4);
- PropertyDefinitions underTest = new PropertyDefinitions(singletonList(
+ PropertyDefinitions underTest = new PropertyDefinitions(System2.INSTANCE, singletonList(
PropertyDefinition.builder(key)
.deprecatedKey(deprecatedKey)
.build()));
String untrimmedKey = blank(random) + deprecatedKey + blank(random);
assertThat(underTest.get(untrimmedKey).key())
- .describedAs("expecting key %s being returned for get(%s)", key, untrimmedKey)
- .isEqualTo(key);
+ .describedAs("expecting key %s being returned for get(%s)", key, untrimmedKey)
+ .isEqualTo(key);
}
private static String blank(Random random) {
return b.toString();
}
+ @Test
+ public void get_value_from_env() {
+ System2 system = mock(System2.class);
+ when(system.envVariable("FOO")).thenReturn("777");
+ when(system.envVariable("ONE")).thenReturn("888");
+ when(system.envVariable("SOME_COMPLETELY_RANDOM_ENV_VAR")).thenReturn("999");
+
+ PropertyDefinitions underTest = new PropertyDefinitions(system, new PluginWithProperty(), new PluginWithProperties());
+
+ assertThat(underTest.getValueFromEnv("foo")).hasValue("777");
+ assertThat(underTest.getValueFromEnv("one")).hasValue("888");
+ assertThat(underTest.getValueFromEnv("two")).isEmpty();
+ assertThat(underTest.getValueFromEnv("some.unrecognizable.prop")).isEmpty();
+ }
+
+ @Test
+ public void get_all_properties_set_in_env() {
+ System2 system = mock(System2.class);
+ when(system.envVariable("FOO")).thenReturn("777");
+ when(system.envVariable("ONE")).thenReturn("888");
+ when(system.envVariable("SOME_COMPLETELY_RANDOM_ENV_VAR")).thenReturn("999");
+
+ PropertyDefinitions underTest = new PropertyDefinitions(system, new PluginWithProperty(), new PluginWithProperties());
+
+ assertThat(underTest.getAllPropertiesSetInEnv()).containsExactlyInAnyOrderEntriesOf(ImmutableMap.of("foo", "777", "one", "888"));
+ }
+
@Property(key = "foo", name = "Foo")
static final class PluginWithProperty {
}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import static org.assertj.core.api.Assertions.assertThat;
public class GlobalConfigurationProviderTest {
- public static final String SOME_VALUE = "some_value";
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public void should_load_global_settings() {
when(globalServerSettings.properties()).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true"));
- GlobalConfiguration globalConfig = new GlobalConfigurationProvider().provide(globalServerSettings, scannerProps, new PropertyDefinitions());
+ GlobalConfiguration globalConfig = new GlobalConfigurationProvider().provide(globalServerSettings, scannerProps, new PropertyDefinitions(System2.INSTANCE));
assertThat(globalConfig.get("sonar.cpd.cross")).hasValue("true");
}
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.Configuration;
-import org.sonar.api.config.internal.Encryption;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.PropertyFieldDefinition;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@Test
public void accessingMultiValuedPropertiesShouldBeConsistentWithDeclaration() {
- Configuration config = new DefaultConfiguration(new PropertyDefinitions(Arrays.asList(
+ Configuration config = new DefaultConfiguration(new PropertyDefinitions(System2.INSTANCE, Arrays.asList(
PropertyDefinition.builder("single").multiValues(false).build(),
PropertyDefinition.builder("multiA").multiValues(true).build())), new Encryption(null),
ImmutableMap.of("single", "foo", "multiA", "a,b", "notDeclared", "c,d")) {
@Test
public void accessingPropertySetPropertiesShouldBeConsistentWithDeclaration() {
- Configuration config = new DefaultConfiguration(new PropertyDefinitions(Arrays.asList(
+ Configuration config = new DefaultConfiguration(new PropertyDefinitions(System2.INSTANCE, Arrays.asList(
PropertyDefinition.builder("props").fields(PropertyFieldDefinition.build("foo1").name("Foo1").build(), PropertyFieldDefinition.build("foo2").name("Foo2").build()).build())),
new Encryption(null),
ImmutableMap.of("props", "1,2", "props.1.foo1", "a", "props.1.foo2", "b")) {
@Test
public void getDefaultValues() {
- Configuration config = new DefaultConfiguration(new PropertyDefinitions(Arrays.asList(
+ Configuration config = new DefaultConfiguration(new PropertyDefinitions(System2.INSTANCE, Arrays.asList(
PropertyDefinition.builder("single").multiValues(false).defaultValue("default").build(),
PropertyDefinition.builder("multiA").multiValues(true).defaultValue("foo,bar").build())), new Encryption(null),
ImmutableMap.of()) {
assertThat(getStringArray("a\n,b\n")).containsExactly("a", "b");
assertThat(getStringArray("a\n,b\n,\"\"")).containsExactly("a", "b", "");
assertThat(getStringArray("a\n, \" \" ,b\n")).containsExactly("a", " ", "b");
- assertThat(getStringArray(" \" , ,, \", a\n,b\n")).containsExactly(" , ,, ", "a","b");
+ assertThat(getStringArray(" \" , ,, \", a\n,b\n")).containsExactly(" , ,, ", "a", "b");
assertThat(getStringArray("a\n,,b\n")).containsExactly("a", "b");
assertThat(getStringArray("a,\n\nb,c")).containsExactly("a", "b", "c");
assertThat(getStringArray("a,b\n\nc,d")).containsExactly("a", "b\nc", "d");
}
private String[] getStringArray(String value) {
- return new DefaultConfiguration(new PropertyDefinitions(Arrays.asList(
+ return new DefaultConfiguration(new PropertyDefinitions(System2.INSTANCE, singletonList(
PropertyDefinition.builder("multi").multiValues(true).build())), new Encryption(null),
ImmutableMap.of("multi", value)) {
}.getStringArray("multi");
import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
-import org.sonar.api.config.internal.Encryption;
import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.scanner.config.DefaultConfiguration;
import org.sonar.scanner.scan.ProjectConfiguration;
public void loadAllReportPaths() {
Map<String, String> settings = new HashMap<>();
settings.put(GenericCoverageSensor.REPORT_PATHS_PROPERTY_KEY, "report.xml,report2.xml");
- PropertyDefinitions defs = new PropertyDefinitions(GenericCoverageSensor.properties());
+ PropertyDefinitions defs = new PropertyDefinitions(System2.INSTANCE, GenericCoverageSensor.properties());
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), settings);
Set<String> reportPaths = new GenericCoverageSensor(config).loadReportPaths();
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.batch.sensor.internal.SensorContextTester;
import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.Encryption;
+import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.scanner.config.DefaultConfiguration;
import org.sonar.scanner.deprecated.test.TestPlanBuilder;
import org.sonar.scanner.scan.ProjectConfiguration;
-import org.sonar.api.batch.sensor.internal.SensorContextTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
Map<String, String> settings = new HashMap<>();
settings.put(GenericTestExecutionSensor.OLD_UNIT_TEST_REPORT_PATHS_PROPERTY_KEY, "report.xml");
- PropertyDefinitions defs = new PropertyDefinitions(GenericTestExecutionSensor.properties());
+ PropertyDefinitions defs = new PropertyDefinitions(System2.INSTANCE, GenericTestExecutionSensor.properties());
DefaultConfiguration config = new ProjectConfiguration(defs, new Encryption(null), settings);
new GenericTestExecutionSensor(mock(TestPlanBuilder.class), config).execute(context);
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.System2;
import org.sonar.core.config.IssueExclusionProperties;
import static org.assertj.core.api.Assertions.assertThat;
@Before
public void init() {
- settings = new MapSettings(new PropertyDefinitions(IssueExclusionProperties.all()));
+ settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, IssueExclusionProperties.all()));
}
@Test
import org.junit.Test;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.utils.System2;
import org.sonar.core.config.IssueExclusionProperties;
import static org.assertj.core.api.Assertions.assertThat;
@Before
public void init() {
- settings = new MapSettings(new PropertyDefinitions(IssueExclusionProperties.all()));
+ settings = new MapSettings(new PropertyDefinitions(System2.INSTANCE, IssueExclusionProperties.all()));
patternsInitializer = new IssueInclusionPatternInitializer(settings.asConfig());
}