From da92c49827337bd34fbf077d5d74c9fbfb8ec287 Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Mon, 9 Jun 2014 15:16:10 +0200 Subject: [PATCH] Separate bootstrap settings and task settings --- .../issue/InitialOpenIssuesStackTest.java | 7 +- .../sonar/batch/bootstrap/AnalysisMode.java | 26 +++--- .../sonar/batch/bootstrap/BatchSettings.java | 58 +++++-------- .../batch/bootstrap/BootstrapContainer.java | 44 ++++------ .../batch/bootstrap/BootstrapProperties.java | 14 +--- .../batch/bootstrap/BootstrapSettings.java | 83 ------------------- .../sonar/batch/bootstrap/ServerClient.java | 25 +++--- .../sonar/batch/bootstrap/TaskContainer.java | 33 ++++++-- .../sonar/batch/bootstrap/TaskProperties.java | 36 ++++++++ .../batch/bootstrap/TempFolderProvider.java | 5 +- .../sonar/batch/bootstrap/UserProperties.java | 62 ++++++++++++++ .../org/sonar/batch/bootstrapper/Batch.java | 56 ++++++++++--- .../scan/DeprecatedProjectReactorBuilder.java | 6 +- .../org/sonar/batch/scan/ModuleSettings.java | 35 ++------ .../batch/scan/ProjectReactorBuilder.java | 12 +-- .../batch/scan/ProjectScanContainer.java | 5 +- .../settings/DefaultSettingsReferential.java | 79 ++++++++++++++++++ .../batch/settings/SettingsReferential.java | 43 ++++++++++ .../batch/bootstrap/AnalysisModeTest.java | 50 +++++------ .../batch/bootstrap/BatchSettingsTest.java | 74 +++++------------ .../bootstrap/BootstrapContainerTest.java | 36 +------- .../bootstrap/BootstrapSettingsTest.java | 76 ----------------- .../batch/bootstrap/ServerClientTest.java | 15 ++-- .../batch/bootstrap/TaskContainerTest.java | 61 ++++++++++++++ .../bootstrap/TempFolderProviderTest.java | 3 +- .../org/sonar/batch/index/CachesTest.java | 10 +-- .../batch/phases/UpdateStatusJobTest.java | 2 - .../DeprecatedProjectReactorBuilderTest.java | 7 +- .../sonar/batch/scan/ModuleSettingsTest.java | 25 +++--- .../batch/scan/ProjectReactorBuilderTest.java | 13 ++- .../batch/scan/ProjectScanContainerTest.java | 26 +++--- .../DefaultSettingsReferentialTest.java | 69 +++++++++++++++ .../java/org/sonar/api/config/Settings.java | 8 ++ 33 files changed, 615 insertions(+), 489 deletions(-) delete mode 100644 sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskProperties.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/bootstrap/UserProperties.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/settings/DefaultSettingsReferential.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/settings/SettingsReferential.java delete mode 100644 sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java create mode 100644 sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java create mode 100644 sonar-batch/src/test/java/org/sonar/batch/settings/DefaultSettingsReferentialTest.java diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java index e21ec2ba6b5..aa81851122d 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java @@ -20,7 +20,6 @@ package org.sonar.plugins.core.issue; -import java.util.Collections; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -28,13 +27,13 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.batch.bootstrap.BootstrapProperties; -import org.sonar.batch.bootstrap.BootstrapSettings; import org.sonar.batch.bootstrap.TempFolderProvider; import org.sonar.batch.index.Caches; import org.sonar.core.issue.db.IssueChangeDto; import org.sonar.core.issue.db.IssueDto; import java.io.IOException; +import java.util.Collections; import java.util.List; import static org.fest.assertions.Assertions.assertThat; @@ -45,9 +44,7 @@ public class InitialOpenIssuesStackTest { public static TemporaryFolder temp = new TemporaryFolder(); public static Caches createCacheOnTemp(TemporaryFolder temp) { - BootstrapSettings bootstrapSettings = new BootstrapSettings( - new BootstrapProperties(Collections.emptyMap()) - ); + BootstrapProperties bootstrapSettings = new BootstrapProperties(Collections.emptyMap()); try { bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath()); } catch (IOException e) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java index b524b5b6acf..4415122c3f6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java @@ -39,8 +39,8 @@ public class AnalysisMode implements BatchComponent { private boolean incremental; private int previewReadTimeoutSec; - public AnalysisMode(BootstrapSettings bootstrapSettings) { - init(bootstrapSettings); + public AnalysisMode(BootstrapProperties bootstrapProps) { + init(bootstrapProps); } public boolean isPreview() { @@ -51,13 +51,13 @@ public class AnalysisMode implements BatchComponent { return incremental; } - private void init(BootstrapSettings bootstrapSettings) { - if (bootstrapSettings.properties().containsKey(CoreProperties.DRY_RUN)) { + private void init(BootstrapProperties bootstrapProps) { + if (bootstrapProps.properties().containsKey(CoreProperties.DRY_RUN)) { LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead.", CoreProperties.DRY_RUN, CoreProperties.ANALYSIS_MODE)); - preview = "true".equals(bootstrapSettings.property(CoreProperties.DRY_RUN)); + preview = "true".equals(bootstrapProps.property(CoreProperties.DRY_RUN)); incremental = false; } else { - String mode = bootstrapSettings.property(CoreProperties.ANALYSIS_MODE); + String mode = bootstrapProps.property(CoreProperties.ANALYSIS_MODE); preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode); incremental = CoreProperties.ANALYSIS_MODE_INCREMENTAL.equals(mode); } @@ -68,19 +68,19 @@ public class AnalysisMode implements BatchComponent { } // To stay compatible with plugins that use the old property to check mode if (incremental || preview) { - bootstrapSettings.properties().put(CoreProperties.DRY_RUN, "true"); - previewReadTimeoutSec = loadPreviewReadTimeout(bootstrapSettings); + bootstrapProps.properties().put(CoreProperties.DRY_RUN, "true"); + previewReadTimeoutSec = loadPreviewReadTimeout(bootstrapProps); } } // SONAR-4488 Allow to increase preview read timeout - private int loadPreviewReadTimeout(BootstrapSettings bootstrapSettings) { + private int loadPreviewReadTimeout(BootstrapProperties bootstrapProps) { int readTimeoutSec; - if (bootstrapSettings.property(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC) != null) { + if (bootstrapProps.property(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC) != null) { LOG.warn("Property {} is deprecated. Please use {} instead.", CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, CoreProperties.PREVIEW_READ_TIMEOUT_SEC); - readTimeoutSec = Integer.parseInt(bootstrapSettings.property(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC)); - } else if (bootstrapSettings.property(CoreProperties.PREVIEW_READ_TIMEOUT_SEC) != null) { - readTimeoutSec = Integer.parseInt(bootstrapSettings.property(CoreProperties.PREVIEW_READ_TIMEOUT_SEC)); + readTimeoutSec = Integer.parseInt(bootstrapProps.property(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC)); + } else if (bootstrapProps.property(CoreProperties.PREVIEW_READ_TIMEOUT_SEC) != null) { + readTimeoutSec = Integer.parseInt(bootstrapProps.property(CoreProperties.PREVIEW_READ_TIMEOUT_SEC)); } else { readTimeoutSec = DEFAULT_PREVIEW_READ_TIMEOUT_SEC; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java index 63f0824663c..b818a602361 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java @@ -19,39 +19,40 @@ */ package org.sonar.batch.bootstrap; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; +import org.sonar.batch.settings.SettingsReferential; import javax.annotation.Nullable; -import java.util.List; + import java.util.Map; public class BatchSettings extends Settings { - public static final String BATCH_BOOTSTRAP_PROPERTIES_URL = "/batch_bootstrap/properties"; + + private static final Logger LOG = LoggerFactory.getLogger(BatchSettings.class); + private Configuration deprecatedConfiguration; - private boolean preview; - private final BootstrapSettings bootstrapSettings; - private final ServerClient client; + private final BootstrapProperties bootstrapProps; + private final SettingsReferential settingsReferential; private final AnalysisMode mode; private Map savedProperties; - public BatchSettings(BootstrapSettings bootstrapSettings, PropertyDefinitions propertyDefinitions, - ServerClient client, Configuration deprecatedConfiguration, AnalysisMode mode) { + public BatchSettings(BootstrapProperties bootstrapProps, PropertyDefinitions propertyDefinitions, + SettingsReferential settingsReferential, Configuration deprecatedConfiguration, AnalysisMode mode) { super(propertyDefinitions); this.mode = mode; - getEncryption().setPathToSecretKey(bootstrapSettings.property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); - this.bootstrapSettings = bootstrapSettings; - this.client = client; + getEncryption().setPathToSecretKey(bootstrapProps.property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); + this.bootstrapProps = bootstrapProps; + this.settingsReferential = settingsReferential; this.deprecatedConfiguration = deprecatedConfiguration; init(null); } @@ -59,26 +60,24 @@ public class BatchSettings extends Settings { public void init(@Nullable ProjectReactor reactor) { savedProperties = this.getProperties(); - this.preview = mode.isPreview(); if (reactor != null) { - LoggerFactory.getLogger(BatchSettings.class).info("Load project settings"); - String branch = bootstrapSettings.property(CoreProperties.PROJECT_BRANCH_PROPERTY); + LOG.info("Load project settings"); + + String branch = reactor.getRoot().getProperties().getProperty(CoreProperties.PROJECT_BRANCH_PROPERTY); String projectKey = reactor.getRoot().getKey(); if (StringUtils.isNotBlank(branch)) { projectKey = String.format("%s:%s", projectKey, branch); } downloadSettings(projectKey); } else { - LoggerFactory.getLogger(BatchSettings.class).info("Load batch settings"); + LOG.info("Load global settings"); downloadSettings(null); } - addProperties(bootstrapSettings.properties()); + addProperties(bootstrapProps.properties()); if (reactor != null) { addProperties(reactor.getRoot().getProperties()); } - properties.putAll(System.getenv()); - addProperties(System.getProperties()); } /** @@ -89,21 +88,10 @@ public class BatchSettings extends Settings { } private void downloadSettings(@Nullable String projectKey) { - String url; if (StringUtils.isNotBlank(projectKey)) { - url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?project=" + projectKey + "&dryRun=" + preview; + addProperties(settingsReferential.projectSettings(projectKey)); } else { - url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?dryRun=" + preview; - } - String jsonText = client.request(url); - - List> json = new Gson().fromJson(jsonText, new TypeToken>>() { - }.getType()); - - for (Map jsonProperty : json) { - String key = jsonProperty.get("k"); - String value = jsonProperty.get("v"); - setProperty(key, value); + addProperties(settingsReferential.globalSettings()); } } @@ -124,8 +112,8 @@ public class BatchSettings extends Settings { @Override protected void doOnGetProperties(String key) { - if (preview && key.endsWith(".secured") && !key.contains(".license")) { - throw new SonarException("Access to the secured property '" + key + if (mode.isPreview() && key.endsWith(".secured") && !key.contains(".license")) { + throw MessageException.of("Access to the secured property '" + key + "' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode."); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java index c2076bc83f3..feffc2f6ede 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.bootstrap; -import org.sonar.core.cluster.NullQueue; - import org.apache.commons.configuration.PropertiesConfiguration; import org.sonar.api.Plugin; import org.sonar.api.config.EmailSettings; @@ -31,7 +29,6 @@ import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.System2; import org.sonar.api.utils.UriReader; import org.sonar.api.utils.internal.TempFolderCleaner; -import org.sonar.batch.bootstrapper.EnvironmentInformation; import org.sonar.batch.components.PastMeasuresLoader; import org.sonar.batch.components.PastSnapshotFinder; import org.sonar.batch.components.PastSnapshotFinderByDate; @@ -39,8 +36,9 @@ import org.sonar.batch.components.PastSnapshotFinderByDays; import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis; import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion; import org.sonar.batch.components.PastSnapshotFinderByVersion; -import org.sonar.batch.scan.DeprecatedProjectReactorBuilder; -import org.sonar.batch.scan.ProjectReactorBuilder; +import org.sonar.batch.settings.DefaultSettingsReferential; +import org.sonar.batch.settings.SettingsReferential; +import org.sonar.core.cluster.NullQueue; import org.sonar.core.config.Logback; import org.sonar.core.i18n.DefaultI18n; import org.sonar.core.i18n.RuleI18nManager; @@ -64,13 +62,16 @@ import java.util.Map; public class BootstrapContainer extends ComponentContainer { - private BootstrapContainer() { + private final Map bootstrapProperties; + + private BootstrapContainer(Map bootstrapProperties) { super(); + this.bootstrapProperties = bootstrapProperties; } - public static BootstrapContainer create(List objects) { - BootstrapContainer container = new BootstrapContainer(); - container.add(objects); + public static BootstrapContainer create(Map bootstrapProperties, List extensions) { + BootstrapContainer container = new BootstrapContainer(bootstrapProperties); + container.add(extensions); return container; } @@ -84,7 +85,7 @@ public class BootstrapContainer extends ComponentContainer { private void addBootstrapComponents() { add( new PropertiesConfiguration(), - BootstrapSettings.class, + new BootstrapProperties(bootstrapProperties), AnalysisMode.class, PluginDownloader.class, BatchPluginRepository.class, @@ -100,21 +101,10 @@ public class BootstrapContainer extends ComponentContainer { HttpDownloader.class, UriReader.class, new FileCacheProvider(), - System2.INSTANCE, - projectReactorBuilder()); - } - - private Class projectReactorBuilder() { - if (isRunnerVersionLessThan2Dot4()) { - return DeprecatedProjectReactorBuilder.class; + System2.INSTANCE); + if (getComponentByType(SettingsReferential.class) == null) { + add(DefaultSettingsReferential.class); } - return ProjectReactorBuilder.class; - } - - private boolean isRunnerVersionLessThan2Dot4() { - EnvironmentInformation env = this.getComponentByType(EnvironmentInformation.class); - // Starting from SQ Runner 2.4 the key is "SonarQubeRunner" - return env != null && "SonarRunner".equals(env.getKey()); } private void addDatabaseComponents() { @@ -163,7 +153,6 @@ public class BootstrapContainer extends ComponentContainer { @Override protected void doAfterStart() { installPlugins(); - executeTask(); } private void installPlugins() { @@ -174,7 +163,8 @@ public class BootstrapContainer extends ComponentContainer { } } - void executeTask() { - new TaskContainer(this).execute(); + public void executeTask(Map taskProperties) { + new TaskContainer(this, taskProperties).execute(); } + } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapProperties.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapProperties.java index 71b6e589a85..97db4c2b3df 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapProperties.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapProperties.java @@ -19,24 +19,18 @@ */ package org.sonar.batch.bootstrap; -import com.google.common.collect.ImmutableMap; +import org.sonar.api.CoreProperties; import java.util.Map; /** - * Batch properties that are not specific to a project (for example + * Immutable batch properties that are not specific to a task (for example * coming from global configuration file of sonar-runner). */ -public class BootstrapProperties { - - private final Map properties; +public class BootstrapProperties extends UserProperties { public BootstrapProperties(Map properties) { - this.properties = ImmutableMap.copyOf(properties); - } - - Map properties() { - return properties; + super(properties, properties.get(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java deleted file mode 100644 index 179bc8db3ab..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.bootstrap; - -import com.google.common.collect.Maps; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.api.config.Encryption; - -import javax.annotation.Nullable; - -import java.util.Map; -import java.util.Properties; - -/** - * @since 2.12 - */ -public class BootstrapSettings { - private Map properties; - private final Encryption encryption; - - public BootstrapSettings(BootstrapProperties bootstrapProperties) { - this(bootstrapProperties, null); - } - - public BootstrapSettings(BootstrapProperties bootstrapProperties, @Nullable ProjectReactor projectReactor) { - properties = Maps.newHashMap(); - // order is important -> bottom-up. The last one overrides all the others. - properties.putAll(bootstrapProperties.properties()); - if (projectReactor != null) { - addProperties(projectReactor.getRoot().getProperties()); - } - properties.putAll(System.getenv()); - addProperties(System.getProperties()); - encryption = new Encryption(properties.get(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); - } - - private void addProperties(Properties p) { - for (Map.Entry entry : p.entrySet()) { - if (entry.getValue() != null) { - properties.put(entry.getKey().toString(), entry.getValue().toString()); - } - } - } - - public Map properties() { - return properties; - } - - public String property(String key) { - String value = properties.get(key); - if (value != null && encryption.isEncrypted(value)) { - try { - value = encryption.decrypt(value); - } catch (Exception e) { - throw new IllegalStateException("Fail to decrypt the property " + key + ". Please check your secret key.", e); - } - } - return value; - } - - public String property(String key, String defaultValue) { - return StringUtils.defaultString(property(key), defaultValue); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java index 111f28b36b8..d43ef8e0e71 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java @@ -29,7 +29,6 @@ import org.apache.commons.lang.StringUtils; import org.sonar.api.BatchComponent; import org.sonar.api.CoreProperties; import org.sonar.api.utils.HttpDownloader; -import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrapper.EnvironmentInformation; import javax.annotation.Nullable; @@ -47,16 +46,16 @@ import java.net.URI; */ public class ServerClient implements BatchComponent { - private BootstrapSettings settings; + private BootstrapProperties props; private HttpDownloader.BaseHttpDownloader downloader; - public ServerClient(BootstrapSettings settings, EnvironmentInformation env) { - this.settings = settings; + public ServerClient(BootstrapProperties settings, EnvironmentInformation env) { + this.props = settings; this.downloader = new HttpDownloader.BaseHttpDownloader(settings.properties(), env.toString()); } public String getURL() { - return StringUtils.removeEnd(settings.property("sonar.host.url", "http://localhost:9000"), "/"); + return StringUtils.removeEnd(StringUtils.defaultIfBlank(props.property("sonar.host.url"), "http://localhost:9000"), "/"); } public void download(String pathStartingWithSlash, File toFile) { @@ -70,7 +69,7 @@ public class ServerClient implements BatchComponent { } catch (HttpDownloader.HttpException he) { throw handleHttpException(he); } catch (IOException e) { - throw new SonarException(String.format("Unable to download '%s' to: %s", pathStartingWithSlash, toFile), e); + throw new IllegalStateException(String.format("Unable to download '%s' to: %s", pathStartingWithSlash, toFile), e); } } @@ -89,7 +88,7 @@ public class ServerClient implements BatchComponent { } catch (HttpDownloader.HttpException e) { throw wrapHttpException ? handleHttpException(e) : e; } catch (IOException e) { - throw new SonarException(String.format("Unable to request: %s", pathStartingWithSlash), e); + throw new IllegalStateException(String.format("Unable to request: %s", pathStartingWithSlash), e); } } @@ -107,19 +106,19 @@ public class ServerClient implements BatchComponent { } return inputSupplier; } catch (Exception e) { - throw new SonarException(String.format("Unable to request: %s", uri), e); + throw new IllegalStateException(String.format("Unable to request: %s", uri), e); } } private RuntimeException handleHttpException(HttpDownloader.HttpException he) { if (he.getResponseCode() == 401) { - return new SonarException(String.format(getMessageWhenNotAuthorized(), CoreProperties.LOGIN, CoreProperties.PASSWORD)); + return new IllegalStateException(String.format(getMessageWhenNotAuthorized(), CoreProperties.LOGIN, CoreProperties.PASSWORD)); } if (he.getResponseCode() == 403) { // SONAR-4397 Details are in response content - return new SonarException(he.getResponseContent()); + return new IllegalStateException(he.getResponseContent()); } - return new SonarException(String.format("Fail to execute request [code=%s, url=%s]", he.getResponseCode(), he.getUri()), he); + return new IllegalStateException(String.format("Fail to execute request [code=%s, url=%s]", he.getResponseCode(), he.getUri()), he); } private String getMessageWhenNotAuthorized() { @@ -130,10 +129,10 @@ public class ServerClient implements BatchComponent { } private String getLogin() { - return settings.property(CoreProperties.LOGIN); + return props.property(CoreProperties.LOGIN); } private String getPassword() { - return settings.property(CoreProperties.PASSWORD); + return props.property(CoreProperties.PASSWORD); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java index b328680a990..4bdda269f46 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java @@ -26,17 +26,25 @@ import org.sonar.api.resources.ResourceTypes; import org.sonar.api.task.Task; import org.sonar.api.task.TaskComponent; import org.sonar.api.task.TaskDefinition; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; +import org.sonar.batch.bootstrapper.EnvironmentInformation; +import org.sonar.batch.scan.DeprecatedProjectReactorBuilder; +import org.sonar.batch.scan.ProjectReactorBuilder; import org.sonar.batch.scan.ScanTask; import org.sonar.batch.tasks.ListTask; import org.sonar.batch.tasks.Tasks; import org.sonar.core.permission.PermissionFacade; import org.sonar.core.resource.DefaultResourcePermissions; +import java.util.Map; + public class TaskContainer extends ComponentContainer { - public TaskContainer(ComponentContainer parent) { + private final Map taskProperties; + + public TaskContainer(ComponentContainer parent, Map taskProperties) { super(parent); + this.taskProperties = taskProperties; } @Override @@ -46,10 +54,12 @@ public class TaskContainer extends ComponentContainer { installComponentsUsingTaskExtensions(); } - private void installCoreTasks() { + void installCoreTasks() { + add(new TaskProperties(taskProperties, getParent().getComponentByType(BootstrapProperties.class).property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH))); add( ScanTask.DEFINITION, ScanTask.class, - ListTask.DEFINITION, ListTask.class); + ListTask.DEFINITION, ListTask.class, + projectReactorBuilder()); } private void installTaskExtensions() { @@ -60,6 +70,19 @@ public class TaskContainer extends ComponentContainer { }); } + private Class projectReactorBuilder() { + if (isRunnerVersionLessThan2Dot4()) { + return DeprecatedProjectReactorBuilder.class; + } + return ProjectReactorBuilder.class; + } + + private boolean isRunnerVersionLessThan2Dot4() { + EnvironmentInformation env = this.getComponentByType(EnvironmentInformation.class); + // Starting from SQ Runner 2.4 the key is "SonarQubeRunner" + return env != null && "SonarRunner".equals(env.getKey()); + } + private void installComponentsUsingTaskExtensions() { add( ResourceTypes.class, @@ -75,7 +98,7 @@ public class TaskContainer extends ComponentContainer { TaskDefinition def = getComponentByType(Tasks.class).definition(taskKey); if (def == null) { - throw new SonarException("Task " + taskKey + " does not exist"); + throw MessageException.of("Task " + taskKey + " does not exist"); } Task task = getComponentByType(def.taskClass()); if (task != null) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskProperties.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskProperties.java new file mode 100644 index 00000000000..d469fcdbe05 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskProperties.java @@ -0,0 +1,36 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.bootstrap; + +import javax.annotation.Nullable; + +import java.util.Map; + +/** + * Batch properties that are specific to a task (for example + * coming from sonar-project.properties). + */ +public class TaskProperties extends UserProperties { + + public TaskProperties(Map properties, @Nullable String pathToSecretKey) { + super(properties, pathToSecretKey); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java index 267b29e3057..50a736b5e4c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java @@ -20,6 +20,7 @@ package org.sonar.batch.bootstrap; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; import org.picocontainer.injectors.ProviderAdapter; import org.sonar.api.CoreProperties; import org.sonar.api.utils.TempFolder; @@ -30,8 +31,8 @@ import java.io.IOException; public class TempFolderProvider extends ProviderAdapter { - public TempFolder provide(BootstrapSettings bootstrapSettings) { - String workingDirPath = bootstrapSettings.property(CoreProperties.WORKING_DIRECTORY, CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE); + public TempFolder provide(BootstrapProperties bootstrapProps) { + String workingDirPath = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE); File workingDir = new File(workingDirPath); File tempDir = new File(workingDir, ".sonartmp"); try { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/UserProperties.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/UserProperties.java new file mode 100644 index 00000000000..42ae3d94a47 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/UserProperties.java @@ -0,0 +1,62 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.bootstrap; + +import com.google.common.collect.Maps; +import org.sonar.api.config.Encryption; + +import javax.annotation.Nullable; + +import java.util.Map; + +/** + * Properties that are coming from bootstrapper. + */ +public abstract class UserProperties { + + private final Map properties; + private final Encryption encryption; + + public UserProperties(Map properties, @Nullable String pathToSecretKey) { + encryption = new Encryption(pathToSecretKey); + Map decryptedProps = Maps.newHashMap(); + for (Map.Entry entry : properties.entrySet()) { + String value = entry.getValue(); + if (value != null && encryption.isEncrypted(value)) { + try { + value = encryption.decrypt(value); + } catch (Exception e) { + throw new IllegalStateException("Fail to decrypt the property " + entry.getKey() + ". Please check your secret key.", e); + } + } + decryptedProps.put(entry.getKey(), value); + } + this.properties = Maps.newHashMap(decryptedProps); + } + + public Map properties() { + return properties; + } + + public String property(String key) { + return properties.get(key); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java index 9d90cf0b6ee..972450aebde 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -22,7 +22,6 @@ package org.sonar.batch.bootstrapper; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.sonar.batch.bootstrap.BootstrapContainer; -import org.sonar.batch.bootstrap.BootstrapProperties; import java.util.Collections; import java.util.List; @@ -35,9 +34,11 @@ import java.util.Map; */ public final class Batch { + private boolean started = false; private LoggingConfiguration logging; private List components; private Map bootstrapProperties = Maps.newHashMap(); + private BootstrapContainer bootstrapContainer; private Batch(Builder builder) { components = Lists.newArrayList(); @@ -57,24 +58,59 @@ public final class Batch { return logging; } + /** + * @deprecated since 4.4 use {@link #start()}, {@link #executeTask(Map)} and then {@link #stop()} + */ + @Deprecated public Batch execute() { configureLogging(); - startBatch(); + start().executeTask(bootstrapProperties).stop(); return this; } - private void configureLogging() { - if (logging != null) { - logging.configure(); + /** + * @since 4.4 + */ + public synchronized Batch start() { + if (started) { + throw new IllegalStateException("Batch is already started"); } + + configureLogging(); + bootstrapContainer = BootstrapContainer.create(bootstrapProperties, components); + bootstrapContainer.startComponents(); + this.started = true; + + return this; } - private void startBatch() { - List all = Lists.newArrayList(components); - all.add(new BootstrapProperties(bootstrapProperties)); + /** + * @since 4.4 + */ + public Batch executeTask(Map taskProperties) { + if (!started) { + throw new IllegalStateException("Batch is not started. Unable to execute task."); + } - BootstrapContainer bootstrapContainer = BootstrapContainer.create(all); - bootstrapContainer.execute(); + bootstrapContainer.executeTask(taskProperties); + return this; + } + + /** + * @since 4.4 + */ + public synchronized void stop() { + if (!started) { + throw new IllegalStateException("Batch is not started."); + } + + bootstrapContainer.stopComponents(); + } + + private void configureLogging() { + if (logging != null) { + logging.configure(); + } } public static Builder builder() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilder.java index a0c3f5d173b..c9983e33243 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilder.java @@ -20,7 +20,7 @@ package org.sonar.batch.scan; import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.batch.bootstrap.BootstrapSettings; +import org.sonar.batch.bootstrap.TaskProperties; import java.io.File; import java.io.IOException; @@ -38,8 +38,8 @@ public class DeprecatedProjectReactorBuilder extends ProjectReactorBuilder { private static final String PROPERTY_PROJECT_CONFIG_FILE = "sonar.projectConfigFile"; - public DeprecatedProjectReactorBuilder(BootstrapSettings settings) { - super(settings); + public DeprecatedProjectReactorBuilder(TaskProperties props) { + super(props); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java index e10d8a6c984..da469b8bb89 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java @@ -20,24 +20,20 @@ package org.sonar.batch.scan; import com.google.common.collect.Lists; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringUtils; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; import org.sonar.batch.bootstrap.AnalysisMode; import org.sonar.batch.bootstrap.BatchSettings; -import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.settings.SettingsReferential; import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; -import static org.sonar.batch.bootstrap.BatchSettings.BATCH_BOOTSTRAP_PROPERTIES_URL; +import java.util.List; /** * @since 2.12 @@ -45,12 +41,13 @@ import static org.sonar.batch.bootstrap.BatchSettings.BATCH_BOOTSTRAP_PROPERTIES public class ModuleSettings extends Settings { private final Configuration deprecatedCommonsConf; - private final ServerClient client; + private final SettingsReferential settingsReferential; private AnalysisMode analysisMode; - public ModuleSettings(BatchSettings batchSettings, ProjectDefinition project, Configuration deprecatedCommonsConf, ServerClient client, AnalysisMode analysisMode) { + public ModuleSettings(BatchSettings batchSettings, ProjectDefinition project, Configuration deprecatedCommonsConf, SettingsReferential settingsReferential, + AnalysisMode analysisMode) { super(batchSettings.getDefinitions()); - this.client = client; + this.settingsReferential = settingsReferential; this.analysisMode = analysisMode; getEncryption().setPathToSecretKey(batchSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); @@ -62,8 +59,6 @@ public class ModuleSettings extends Settings { private ModuleSettings init(ProjectDefinition project, BatchSettings batchSettings) { addProjectProperties(project, batchSettings); addBuildProperties(project); - addEnvironmentVariables(); - addSystemProperties(); return this; } @@ -74,19 +69,7 @@ public class ModuleSettings extends Settings { projectKey = String.format("%s:%s", projectKey, branch); } addProperties(batchSettings.getProperties()); - downloadSettings(projectKey); - } - - private void downloadSettings(String moduleKey) { - String url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?project=" + moduleKey + "&dryRun=" + analysisMode.isPreview(); - String jsonText = client.request(url); - List> json = new Gson().fromJson(jsonText, new TypeToken>>() { - }.getType()); - for (Map jsonProperty : json) { - String key = jsonProperty.get("k"); - String value = jsonProperty.get("v"); - setProperty(key, value); - } + addProperties(settingsReferential.projectSettings(projectKey)); } private void addBuildProperties(ProjectDefinition project) { @@ -127,7 +110,7 @@ public class ModuleSettings extends Settings { @Override protected void doOnGetProperties(String key) { if (analysisMode.isPreview() && key.endsWith(".secured") && !key.contains(".license")) { - throw new SonarException("Access to the secured property '" + key + throw MessageException.of("Access to the secured property '" + key + "' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode."); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java index 6fcd09ad568..f1700a38fcb 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.batch.bootstrap.BootstrapSettings; +import org.sonar.batch.bootstrap.TaskProperties; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -101,16 +101,16 @@ public class ProjectReactorBuilder { private static final List NON_HERITED_PROPERTIES_FOR_CHILD = Lists.newArrayList(PROPERTY_PROJECT_BASEDIR, CoreProperties.WORKING_DIRECTORY, PROPERTY_MODULES, CoreProperties.PROJECT_DESCRIPTION_PROPERTY); - private BootstrapSettings settings; + private TaskProperties props; private File rootProjectWorkDir; - public ProjectReactorBuilder(BootstrapSettings settings) { - this.settings = settings; + public ProjectReactorBuilder(TaskProperties props) { + this.props = props; } public ProjectReactor execute() { Properties bootstrapProperties = new Properties(); - bootstrapProperties.putAll(settings.properties()); + bootstrapProperties.putAll(props.properties()); ProjectDefinition rootProject = defineProject(bootstrapProperties, null); rootProjectWorkDir = rootProject.getWorkDir(); defineChildren(rootProject); @@ -142,7 +142,7 @@ public class ProjectReactorBuilder { @VisibleForTesting protected File initRootProjectWorkDir(File baseDir) { - String workDir = settings.property(CoreProperties.WORKING_DIRECTORY); + String workDir = props.property(CoreProperties.WORKING_DIRECTORY); if (StringUtils.isBlank(workDir)) { return new File(baseDir, CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 335884d7f87..b6dca14dafd 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -35,7 +35,6 @@ import org.sonar.batch.DefaultFileLinesContextFactory; import org.sonar.batch.DefaultResourceCreationLock; import org.sonar.batch.ProjectConfigurator; import org.sonar.batch.ProjectTree; -import org.sonar.batch.bootstrap.BootstrapSettings; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; @@ -108,10 +107,10 @@ public class ProjectScanContainer extends ComponentContainer { if (reactor == null) { // OK, not present, so look for a custom ProjectBootstrapper ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class); - BootstrapSettings settings = getComponentByType(BootstrapSettings.class); + Settings settings = getComponentByType(Settings.class); if (bootstrapper == null // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used. - || "true".equals(settings.property("sonar.mojoUseRunner"))) { + || "true".equals(settings.getString("sonar.mojoUseRunner"))) { // Use default SonarRunner project bootstrapper ProjectReactorBuilder builder = getComponentByType(ProjectReactorBuilder.class); reactor = builder.execute(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/settings/DefaultSettingsReferential.java b/sonar-batch/src/main/java/org/sonar/batch/settings/DefaultSettingsReferential.java new file mode 100644 index 00000000000..6241b0804dc --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/settings/DefaultSettingsReferential.java @@ -0,0 +1,79 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.settings; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.ServerClient; + +import javax.annotation.Nullable; + +import java.util.List; +import java.util.Map; + +/** + * Default implementation of {@link SettingsReferential} that fetch settings from remote SQ server using WS. + * @since 4.4 + */ +public class DefaultSettingsReferential implements SettingsReferential { + + private static final String BATCH_BOOTSTRAP_PROPERTIES_URL = "/batch_bootstrap/properties"; + + private final ServerClient serverClient; + private final AnalysisMode analysisMode; + + public DefaultSettingsReferential(ServerClient serverClient, AnalysisMode analysisMode) { + this.serverClient = serverClient; + this.analysisMode = analysisMode; + } + + @Override + public Map globalSettings() { + return downloadSettings(null); + } + + @Override + public Map projectSettings(String moduleKey) { + return downloadSettings(moduleKey); + } + + private Map downloadSettings(@Nullable String moduleKey) { + Map result = Maps.newHashMap(); + String url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?dryRun=" + analysisMode.isPreview(); + if (moduleKey != null) { + url += "&project=" + moduleKey; + } + String jsonText = serverClient.request(url); + + List> json = new Gson().fromJson(jsonText, new TypeToken>>() { + }.getType()); + + for (Map jsonProperty : json) { + String key = jsonProperty.get("k"); + String value = jsonProperty.get("v"); + result.put(key, value); + } + + return result; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/settings/SettingsReferential.java b/sonar-batch/src/main/java/org/sonar/batch/settings/SettingsReferential.java new file mode 100644 index 00000000000..d4d7367e3ea --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/settings/SettingsReferential.java @@ -0,0 +1,43 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.settings; + +import org.sonar.api.BatchComponent; + +import java.util.Map; + +/** + * Settings referential + * @since 4.4 + */ +public interface SettingsReferential extends BatchComponent { + + /** + * Provide global settings + */ + Map globalSettings(); + + /** + * Provide settings for a given project or sub-project (includes global settings) + * @param projectKey + */ + Map projectSettings(String projectKey); + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java index 4370ffaf8b9..aafcb3f5cea 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java @@ -19,7 +19,7 @@ */ package org.sonar.batch.bootstrap; -import org.junit.Before; +import com.google.common.collect.ImmutableMap; import org.junit.Test; import org.sonar.api.CoreProperties; @@ -29,22 +29,15 @@ import static org.fest.assertions.Assertions.assertThat; public class AnalysisModeTest { - BootstrapSettings bootstrapSettings; - - @Before - public void prepare() { - bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap())); - } - @Test public void regular_analysis_by_default() { - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + AnalysisMode mode = new AnalysisMode(new BootstrapProperties(Collections.emptyMap())); assertThat(mode.isPreview()).isFalse(); assertThat(mode.isIncremental()).isFalse(); - bootstrapSettings.properties().put(CoreProperties.ANALYSIS_MODE, "pouet"); - mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, "pouet")); + mode = new AnalysisMode(bootstrapProps); assertThat(mode.isPreview()).isFalse(); assertThat(mode.isIncremental()).isFalse(); @@ -52,8 +45,8 @@ public class AnalysisModeTest { @Test public void support_analysis_mode() { - bootstrapSettings.properties().put(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ANALYSIS); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ANALYSIS)); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.isPreview()).isFalse(); assertThat(mode.isIncremental()).isFalse(); @@ -61,30 +54,30 @@ public class AnalysisModeTest { @Test public void support_preview_mode() { - bootstrapSettings.properties().put(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.isPreview()).isTrue(); assertThat(mode.isIncremental()).isFalse(); - assertThat(bootstrapSettings.property(CoreProperties.DRY_RUN)).isEqualTo("true"); + assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true"); } @Test public void support_incremental_mode() { - bootstrapSettings.properties().put(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL)); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.isPreview()).isTrue(); assertThat(mode.isIncremental()).isTrue(); - assertThat(bootstrapSettings.property(CoreProperties.DRY_RUN)).isEqualTo("true"); + assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true"); } @Test public void support_deprecated_dryrun_property() { - bootstrapSettings.properties().put(CoreProperties.DRY_RUN, "true"); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.DRY_RUN, "true")); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.isPreview()).isTrue(); assertThat(mode.isIncremental()).isFalse(); @@ -92,26 +85,25 @@ public class AnalysisModeTest { @Test public void should_get_default_preview_read_timeout() { - bootstrapSettings.properties().put(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.getPreviewReadTimeoutSec()).isEqualTo(60); } @Test public void should_download_database_with_deprecated_overriden_timeout() { - bootstrapSettings.properties().put(CoreProperties.DRY_RUN, "true"); - bootstrapSettings.properties().put(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, "80"); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.DRY_RUN, "true", CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, "80")); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.getPreviewReadTimeoutSec()).isEqualTo(80); } @Test public void should_download_database_with_overriden_timeout() { - bootstrapSettings.properties().put(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW); - bootstrapSettings.properties().put(CoreProperties.PREVIEW_READ_TIMEOUT_SEC, "80"); - AnalysisMode mode = new AnalysisMode(bootstrapSettings); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW, + CoreProperties.PREVIEW_READ_TIMEOUT_SEC, "80")); + AnalysisMode mode = new AnalysisMode(bootstrapProps); assertThat(mode.getPreviewReadTimeoutSec()).isEqualTo(80); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java index 767897e4fe3..1b507af9c7f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java @@ -19,6 +19,7 @@ */ package org.sonar.batch.bootstrap; +import com.google.common.collect.ImmutableMap; import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; import org.junit.Before; @@ -29,7 +30,8 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; +import org.sonar.batch.settings.SettingsReferential; import java.util.Collections; @@ -51,38 +53,24 @@ public class BatchSettingsTest { private static final String BRANCH_REACTOR_JSON_RESPONSE = "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," + "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\"}]"; - ServerClient client = mock(ServerClient.class); + SettingsReferential settingsRef = mock(SettingsReferential.class); ProjectDefinition project = ProjectDefinition.create().setKey("struts"); Configuration deprecatedConf = new BaseConfiguration(); - BootstrapSettings bootstrapSettings; + BootstrapProperties bootstrapProps; private AnalysisMode mode; @Before public void prepare() { - bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap())); + bootstrapProps = new BootstrapProperties(Collections.emptyMap()); mode = mock(AnalysisMode.class); } - @Test - public void should_load_system_props() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - System.setProperty("BatchSettingsTest.testSystemProp", "system"); - // Reconstruct bootstrap settings to get system property - bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap())); - - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); - - assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system"); - } - @Test public void should_load_project_props() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); project.setProperty("project.prop", "project"); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); batchSettings.init(new ProjectReactor(project)); assertThat(batchSettings.getString("project.prop")).isEqualTo("project"); @@ -90,19 +78,18 @@ public class BatchSettingsTest { @Test public void should_load_global_settings() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + when(settingsRef.globalSettings()).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true")); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); assertThat(batchSettings.getBoolean("sonar.cpd.cross")).isTrue(); } @Test public void should_load_project_root_settings() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); + when(settingsRef.projectSettings("struts")).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true", "sonar.java.coveragePlugin", "jacoco")); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); batchSettings.init(new ProjectReactor(project)); assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco"); @@ -110,12 +97,11 @@ public class BatchSettingsTest { @Test public void should_load_project_root_settings_on_branch() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts:mybranch&dryRun=false")).thenReturn(BRANCH_REACTOR_JSON_RESPONSE); + project.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch"); - bootstrapSettings.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch"); + when(settingsRef.projectSettings("struts:mybranch")).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true", "sonar.java.coveragePlugin", "jacoco")); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); batchSettings.init(new ProjectReactor(project)); assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco"); @@ -123,10 +109,9 @@ public class BatchSettingsTest { @Test public void should_not_fail_when_accessing_secured_properties() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE_WITH_SECURED); - when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); + when(settingsRef.projectSettings("struts")).thenReturn(ImmutableMap.of("sonar.foo.secured", "bar", "sonar.foo.license.secured", "bar2")); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); batchSettings.init(new ProjectReactor(project)); assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); @@ -135,38 +120,25 @@ public class BatchSettingsTest { @Test public void should_fail_when_accessing_secured_properties_in_dryrun() { - when(client.request("/batch_bootstrap/properties?dryRun=true")).thenReturn(JSON_RESPONSE_WITH_SECURED); - when(client.request("/batch_bootstrap/properties?project=struts&dryRun=true")).thenReturn(REACTOR_JSON_RESPONSE); + when(settingsRef.projectSettings("struts")).thenReturn(ImmutableMap.of("sonar.foo.secured", "bar", "sonar.foo.license.secured", "bar2")); when(mode.isPreview()).thenReturn(true); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); batchSettings.init(new ProjectReactor(project)); assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); - thrown.expect(SonarException.class); + thrown.expect(MessageException.class); thrown .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode."); batchSettings.getString("sonar.foo.secured"); } - @Test - public void system_props_should_override_build_props() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - System.setProperty("BatchSettingsTest.testSystemProp", "system"); - project.setProperty("BatchSettingsTest.testSystemProp", "build"); - - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); - - assertThat(batchSettings.getString("BatchSettingsTest.testSystemProp")).isEqualTo("system"); - } - @Test public void should_forward_to_deprecated_commons_configuration() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); + when(settingsRef.projectSettings("struts")).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true", "sonar.java.coveragePlugin", "jacoco")); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); batchSettings.init(new ProjectReactor(project)); assertThat(deprecatedConf.getString("sonar.cpd.cross")).isEqualTo("true"); @@ -183,8 +155,8 @@ public class BatchSettingsTest { @Test public void project_should_be_optional() { - when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); - BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf, mode); + when(settingsRef.globalSettings()).thenReturn(ImmutableMap.of("sonar.cpd.cross", "true")); + BatchSettings batchSettings = new BatchSettings(bootstrapProps, new PropertyDefinitions(), settingsRef, deprecatedConf, mode); assertThat(batchSettings.getProperties()).isNotEmpty(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java index cb611c8ae66..c31bd9fea47 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java @@ -27,9 +27,6 @@ import org.sonar.api.Plugin; import org.sonar.api.SonarPlugin; import org.sonar.api.platform.PluginMetadata; import org.sonar.api.utils.TempFolder; -import org.sonar.batch.bootstrapper.EnvironmentInformation; -import org.sonar.batch.scan.DeprecatedProjectReactorBuilder; -import org.sonar.batch.scan.ProjectReactorBuilder; import org.sonar.core.config.Logback; import java.util.Arrays; @@ -45,8 +42,7 @@ import static org.mockito.Mockito.when; public class BootstrapContainerTest { @Test public void should_add_components() { - BootstrapContainer container = BootstrapContainer.create(Collections.emptyList()); - container.add(new BootstrapProperties(Collections.emptyMap())); + BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), Collections.emptyList()); container.doBeforeStart(); assertThat(container.getComponentByType(Logback.class)).isNotNull(); @@ -55,7 +51,7 @@ public class BootstrapContainerTest { @Test public void should_add_bootstrap_extensions() { - BootstrapContainer container = BootstrapContainer.create(Lists.newArrayList(Foo.class, new Bar())); + BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), Lists.newArrayList(Foo.class, new Bar())); container.doBeforeStart(); assertThat(container.getComponentByType(Foo.class)).isNotNull(); @@ -71,37 +67,13 @@ public class BootstrapContainerTest { metadata, plugin )); - BootstrapContainer container = spy(BootstrapContainer.create(Lists.newArrayList(pluginRepository))); - doNothing().when(container).executeTask(); + BootstrapContainer container = spy(BootstrapContainer.create(Collections.emptyMap(), Lists.newArrayList(pluginRepository))); + doNothing().when(container).executeTask(Collections.emptyMap()); container.doAfterStart(); assertThat(container.getComponentsByType(Plugin.class)).containsOnly(plugin); } - @Test - public void should_add_project_reactor_builder_by_default() { - BootstrapContainer container = BootstrapContainer.create(Lists.newArrayList()); - container.add(new BootstrapProperties(Collections.emptyMap())); - container.doBeforeStart(); - - assertThat(container.getComponentByType(ProjectReactorBuilder.class)).isNotNull().isInstanceOf(ProjectReactorBuilder.class); - - container = BootstrapContainer.create(Lists.newArrayList(new EnvironmentInformation("SonarQubeRunner", "2.4"))); - container.add(new BootstrapProperties(Collections.emptyMap())); - container.doBeforeStart(); - - assertThat(container.getComponentByType(ProjectReactorBuilder.class)).isNotNull().isInstanceOf(ProjectReactorBuilder.class); - } - - @Test - public void should_add_deprecated_project_reactor_builder_if_old_runner() { - BootstrapContainer container = BootstrapContainer.create(Lists.newArrayList(new EnvironmentInformation("SonarRunner", "2.3"))); - container.add(new BootstrapProperties(Collections.emptyMap())); - container.doBeforeStart(); - - assertThat(container.getComponentByType(DeprecatedProjectReactorBuilder.class)).isNotNull().isInstanceOf(DeprecatedProjectReactorBuilder.class); - } - public static class Foo implements BatchExtension { } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java deleted file mode 100644 index 7da55ba606c..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.bootstrap; - -import com.google.common.collect.ImmutableMap; -import org.junit.Test; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.bootstrap.ProjectReactor; - -import java.util.Collections; -import java.util.Map; - -import static org.fest.assertions.Assertions.assertThat; - -public class BootstrapSettingsTest { - - @Test - public void project_settings_should_be_optional() { - Map props = ImmutableMap.of("foo", "bar"); - BootstrapSettings settings = new BootstrapSettings(new BootstrapProperties(props)); - - assertThat(settings.property("foo")).isEqualTo("bar"); - } - - @Test - public void should_load_project_settings() { - // this is the project as defined in the bootstrapper - ProjectDefinition project = ProjectDefinition.create(); - project.setProperty("foo", "bar"); - ProjectReactor reactor = new ProjectReactor(project); - BootstrapSettings settings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap()), reactor); - - assertThat(settings.property("foo")).isEqualTo("bar"); - assertThat(settings.properties().size()).isGreaterThan(1); - } - - @Test - public void environment_should_override_project_settings() { - ProjectDefinition project = ProjectDefinition.create(); - project.setProperty("BootstrapSettingsTest.testEnv", "build"); - System.setProperty("BootstrapSettingsTest.testEnv", "env"); - - ProjectReactor reactor = new ProjectReactor(project); - BootstrapSettings settings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap()), reactor); - - assertThat(settings.property("BootstrapSettingsTest.testEnv")).isEqualTo("env"); - } - - @Test - public void should_get_default_value_of_missing_property() { - ProjectDefinition project = ProjectDefinition.create(); - project.setProperty("foo", "bar"); - ProjectReactor reactor = new ProjectReactor(project); - BootstrapSettings settings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap()), reactor); - - assertThat(settings.property("foo", "default_value")).isEqualTo("bar"); - assertThat(settings.property("missing", "default_value")).isEqualTo("default_value"); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java index 742f53e25dc..34060a4ee30 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java @@ -43,7 +43,6 @@ import java.io.IOException; import static javax.servlet.http.HttpServletResponse.SC_OK; import static org.apache.commons.io.IOUtils.write; import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -55,7 +54,7 @@ public class ServerClientTest { @Rule public ExpectedException thrown = ExpectedException.none(); MockHttpServer server = null; - BootstrapSettings settings = mock(BootstrapSettings.class); + BootstrapProperties bootstrapProps = mock(BootstrapProperties.class); @After public void stopServer() { @@ -66,8 +65,8 @@ public class ServerClientTest { @Test public void should_remove_url_ending_slash() throws Exception { - BootstrapSettings settings = mock(BootstrapSettings.class); - when(settings.property(eq("sonar.host.url"), anyString())).thenReturn("http://localhost:8080/sonar/"); + BootstrapProperties settings = mock(BootstrapProperties.class); + when(settings.property("sonar.host.url")).thenReturn("http://localhost:8080/sonar/"); ServerClient client = new ServerClient(settings, new EnvironmentInformation("Junit", "4")); @@ -119,8 +118,8 @@ public class ServerClientTest { server.start(); server.setMockResponseStatus(401); - when(settings.property(eq("sonar.login"))).thenReturn("login"); - when(settings.property(eq("sonar.password"))).thenReturn("password"); + when(bootstrapProps.property(eq("sonar.login"))).thenReturn("login"); + when(bootstrapProps.property(eq("sonar.password"))).thenReturn("password"); thrown.expectMessage("Not authorized. Please check the properties sonar.login and sonar.password"); newServerClient().request("/foo"); @@ -137,8 +136,8 @@ public class ServerClientTest { } private ServerClient newServerClient() { - when(settings.property(eq("sonar.host.url"), anyString())).thenReturn("http://localhost:" + server.getPort()); - return new ServerClient(settings, new EnvironmentInformation("Junit", "4")); + when(bootstrapProps.property("sonar.host.url")).thenReturn("http://localhost:" + server.getPort()); + return new ServerClient(bootstrapProps, new EnvironmentInformation("Junit", "4")); } static class MockHttpServer { diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java new file mode 100644 index 00000000000..41616656012 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java @@ -0,0 +1,61 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.bootstrap; + +import com.google.common.collect.Lists; +import org.junit.Test; +import org.sonar.batch.bootstrapper.EnvironmentInformation; +import org.sonar.batch.scan.DeprecatedProjectReactorBuilder; +import org.sonar.batch.scan.ProjectReactorBuilder; + +import java.util.Collections; + +import static org.fest.assertions.Assertions.assertThat; + +public class TaskContainerTest { + + @Test + public void should_add_project_reactor_builder_by_default() { + BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), + Lists.newArrayList(new BootstrapProperties(Collections.emptyMap()))); + TaskContainer taskContainer = new TaskContainer(container, Collections.emptyMap()); + taskContainer.installCoreTasks(); + + assertThat(taskContainer.getComponentByType(ProjectReactorBuilder.class)).isNotNull().isInstanceOf(ProjectReactorBuilder.class); + + container = BootstrapContainer.create(Collections.emptyMap(), + Lists.newArrayList(new BootstrapProperties(Collections.emptyMap()), new EnvironmentInformation("SonarQubeRunner", "2.4"))); + taskContainer = new TaskContainer(container, Collections.emptyMap()); + taskContainer.installCoreTasks(); + + assertThat(taskContainer.getComponentByType(ProjectReactorBuilder.class)).isNotNull().isInstanceOf(ProjectReactorBuilder.class); + } + + @Test + public void should_add_deprecated_project_reactor_builder_if_old_runner() { + BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), + Lists.newArrayList(new BootstrapProperties(Collections.emptyMap()), new EnvironmentInformation("SonarRunner", "2.3"))); + TaskContainer taskContainer = new TaskContainer(container, Collections.emptyMap()); + taskContainer.installCoreTasks(); + + assertThat(taskContainer.getComponentByType(DeprecatedProjectReactorBuilder.class)).isNotNull().isInstanceOf(DeprecatedProjectReactorBuilder.class); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java index 90c380248e6..605a768851f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java @@ -43,8 +43,7 @@ public class TempFolderProviderTest { public void createTempFolder() throws Exception { File workingDir = temp.newFolder(); TempFolderProvider tempFolderProvider = new TempFolderProvider(); - TempFolder tempFolder = tempFolderProvider.provide(new BootstrapSettings( - new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath())))); + TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath()))); tempFolder.newDir(); tempFolder.newFile(); assertThat(new File(workingDir, ".sonartmp")).exists(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java index 3b3ab52b083..65a4333e58b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java @@ -19,7 +19,7 @@ */ package org.sonar.batch.index; -import java.util.Collections; +import com.google.common.collect.ImmutableMap; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -27,7 +27,6 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.batch.bootstrap.BootstrapProperties; -import org.sonar.batch.bootstrap.BootstrapSettings; import org.sonar.batch.bootstrap.TempFolderProvider; import java.io.File; @@ -43,15 +42,12 @@ public class CachesTest { public static TemporaryFolder temp = new TemporaryFolder(); public static Caches createCacheOnTemp(TemporaryFolder temp) { - BootstrapSettings bootstrapSettings = new BootstrapSettings( - new BootstrapProperties(Collections.emptyMap()) - ); try { - bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath()); + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath())); + return new Caches(new TempFolderProvider().provide(bootstrapProps)); } catch (IOException e) { throw new RuntimeException(e); } - return new Caches(new TempFolderProvider().provide(bootstrapSettings)); } Caches caches; diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java index 4d6f1de7074..9768619144e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java @@ -29,7 +29,6 @@ import org.sonar.api.database.model.Snapshot; import org.sonar.api.resources.Project; import org.sonar.api.security.ResourcePermissions; import org.sonar.batch.bootstrap.AnalysisMode; -import org.sonar.batch.bootstrap.BootstrapSettings; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.index.DefaultResourcePersister; import org.sonar.batch.index.ResourceCache; @@ -49,7 +48,6 @@ import static org.mockito.Mockito.when; public class UpdateStatusJobTest extends AbstractDbUnitTestCase { private AnalysisMode mode; - private BootstrapSettings bootstrapSettings; @Before public void setUp() { diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilderTest.java index a5fa0efc325..c3deb16032a 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilderTest.java @@ -25,8 +25,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.batch.bootstrap.BootstrapProperties; -import org.sonar.batch.bootstrap.BootstrapSettings; +import org.sonar.batch.bootstrap.TaskProperties; import org.sonar.test.TestUtils; import java.io.File; @@ -183,8 +182,8 @@ public class DeprecatedProjectReactorBuilderTest { props.put(name, runnerProps.getProperty(name)); } props.put("sonar.projectBaseDir", TestUtils.getResource(this.getClass(), projectFolder).getAbsolutePath()); - BootstrapProperties bootstrapProps = new BootstrapProperties(props); - ProjectReactor projectReactor = new DeprecatedProjectReactorBuilder(new BootstrapSettings(bootstrapProps)).execute(); + TaskProperties taskProps = new TaskProperties(props, null); + ProjectReactor projectReactor = new DeprecatedProjectReactorBuilder(taskProps).execute(); return projectReactor.getRoot(); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java index 47b6300bcb2..0140f39a7d2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java @@ -28,10 +28,10 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; import org.sonar.batch.bootstrap.AnalysisMode; import org.sonar.batch.bootstrap.BatchSettings; -import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.settings.SettingsReferential; import java.util.List; @@ -44,7 +44,7 @@ public class ModuleSettingsTest { @Rule public ExpectedException thrown = ExpectedException.none(); - ServerClient client = mock(ServerClient.class); + SettingsReferential settingsRef = mock(SettingsReferential.class); private AnalysisMode mode; @Before @@ -74,14 +74,12 @@ public class ModuleSettingsTest { "overridding", "batch", "on-batch", "true" )); - when(client.request("/batch_bootstrap/properties?project=struts-core&dryRun=false")) - .thenReturn("[{\"k\":\"on-module\",\"v\":\"true\"}," + - "{\"k\":\"overridding\",\"v\":\"module\"}]"); + when(settingsRef.projectSettings("struts-core")).thenReturn(ImmutableMap.of("on-module", "true", "overridding", "module")); ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); Configuration deprecatedConf = new PropertiesConfiguration(); - ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client, mode); + ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, settingsRef, mode); assertThat(moduleSettings.getString("overridding")).isEqualTo("module"); assertThat(moduleSettings.getString("on-batch")).isEqualTo("true"); @@ -99,13 +97,12 @@ public class ModuleSettingsTest { when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( "sonar.foo.secured", "bar" )); - when(client.request("/batch_bootstrap/properties?project=struts-core&dryRun=false")) - .thenReturn("[{\"k\":\"sonar.foo.license.secured\",\"v\":\"bar2\"}]"); + when(settingsRef.projectSettings("struts-core")).thenReturn(ImmutableMap.of("sonar.foo.license.secured", "bar2")); ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); Configuration deprecatedConf = new PropertiesConfiguration(); - ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client, mode); + ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, settingsRef, mode); assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); assertThat(moduleSettings.getString("sonar.foo.secured")).isEqualTo("bar"); @@ -118,20 +115,18 @@ public class ModuleSettingsTest { when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( "sonar.foo.secured", "bar" )); + when(settingsRef.projectSettings("struts-core")).thenReturn(ImmutableMap.of("sonar.foo.license.secured", "bar2")); when(mode.isPreview()).thenReturn(true); - when(client.request("/batch_bootstrap/properties?project=struts-core&dryRun=true")) - .thenReturn("[{\"k\":\"sonar.foo.license.secured\",\"v\":\"bar2\"}]"); - ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); Configuration deprecatedConf = new PropertiesConfiguration(); - ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, client, mode); + ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf, settingsRef, mode); assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); - thrown.expect(SonarException.class); + thrown.expect(MessageException.class); thrown .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in preview mode. The SonarQube plugin which requires this property must be deactivated in preview mode."); moduleSettings.getString("sonar.foo.secured"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java index 85a83bbfba2..631a58c766e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java @@ -26,8 +26,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.batch.bootstrap.BootstrapProperties; -import org.sonar.batch.bootstrap.BootstrapSettings; +import org.sonar.batch.bootstrap.TaskProperties; import org.sonar.test.TestUtils; import java.io.File; @@ -404,7 +403,7 @@ public class ProjectReactorBuilderTest { @Test public void shouldInitRootWorkDir() { - ProjectReactorBuilder builder = new ProjectReactorBuilder(new BootstrapSettings(new BootstrapProperties(Maps.newHashMap()))); + ProjectReactorBuilder builder = new ProjectReactorBuilder(new TaskProperties(Maps.newHashMap(), null)); File baseDir = new File("target/tmp/baseDir"); File workDir = builder.initRootProjectWorkDir(baseDir); @@ -416,7 +415,7 @@ public class ProjectReactorBuilderTest { public void shouldInitWorkDirWithCustomRelativeFolder() { Map props = Maps.newHashMap(); props.put("sonar.working.directory", ".foo"); - ProjectReactorBuilder builder = new ProjectReactorBuilder(new BootstrapSettings(new BootstrapProperties(props))); + ProjectReactorBuilder builder = new ProjectReactorBuilder(new TaskProperties(props, null)); File baseDir = new File("target/tmp/baseDir"); File workDir = builder.initRootProjectWorkDir(baseDir); @@ -428,7 +427,7 @@ public class ProjectReactorBuilderTest { public void shouldInitRootWorkDirWithCustomAbsoluteFolder() { Map props = Maps.newHashMap(); props.put("sonar.working.directory", new File("src").getAbsolutePath()); - ProjectReactorBuilder builder = new ProjectReactorBuilder(new BootstrapSettings(new BootstrapProperties(props))); + ProjectReactorBuilder builder = new ProjectReactorBuilder(new TaskProperties(props, null)); File baseDir = new File("target/tmp/baseDir"); File workDir = builder.initRootProjectWorkDir(baseDir); @@ -492,8 +491,8 @@ public class ProjectReactorBuilderTest { props.put(name, runnerProps.getProperty(name)); } props.put("sonar.projectBaseDir", TestUtils.getResource(this.getClass(), projectFolder).getAbsolutePath()); - BootstrapProperties bootstrapProps = new BootstrapProperties(props); - ProjectReactor projectReactor = new ProjectReactorBuilder(new BootstrapSettings(bootstrapProps)).execute(); + TaskProperties bootstrapProps = new TaskProperties(props, null); + ProjectReactor projectReactor = new ProjectReactorBuilder(bootstrapProps).execute(); return projectReactor.getRoot(); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java index 66657c5054b..8f585fd36c4 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java @@ -19,7 +19,6 @@ */ package org.sonar.batch.scan; -import com.google.common.collect.Maps; import org.junit.Before; import org.junit.Test; import org.sonar.api.BatchExtension; @@ -32,8 +31,6 @@ import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.Settings; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.task.TaskExtension; -import org.sonar.batch.bootstrap.BootstrapProperties; -import org.sonar.batch.bootstrap.BootstrapSettings; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.profiling.PhasesSumUpTimeProfiler; import org.sonar.batch.scan.maven.MavenPluginExecutor; @@ -45,19 +42,23 @@ import static org.mockito.Mockito.when; public class ProjectScanContainerTest { private ProjectBootstrapper projectBootstrapper; - private BootstrapSettings bootstrapSettings; + private ProjectScanContainer container; + private Settings settings; + private ComponentContainer parentContainer; @Before public void prepare() { projectBootstrapper = mock(ProjectBootstrapper.class); when(projectBootstrapper.bootstrap()).thenReturn(new ProjectReactor(ProjectDefinition.create())); - bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Maps.newHashMap())); + settings = new Settings(); + parentContainer = new ComponentContainer(); + parentContainer.add(settings); + container = new ProjectScanContainer(parentContainer); } @Test public void should_add_fake_maven_executor_on_non_maven_env() { - ProjectScanContainer container = new ProjectScanContainer(new ComponentContainer()); - container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings); + container.add(mock(ExtensionInstaller.class), projectBootstrapper); container.doBeforeStart(); assertThat(container.getComponentByType(MavenPluginExecutor.class)).isNotNull(); @@ -65,8 +66,7 @@ public class ProjectScanContainerTest { @Test public void should_use_maven_executor_provided_by_maven() { - ProjectScanContainer container = new ProjectScanContainer(new ComponentContainer()); - container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings); + container.add(mock(ExtensionInstaller.class), projectBootstrapper); MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class); container.add(mavenPluginExecutor); container.doBeforeStart(); @@ -77,11 +77,7 @@ public class ProjectScanContainerTest { @Test public void should_activate_profiling() { - ComponentContainer parentContainer = new ComponentContainer(); - Settings settings = new Settings(); - parentContainer.add(settings); - ProjectScanContainer container = new ProjectScanContainer(parentContainer); - container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings); + container.add(mock(ExtensionInstaller.class), projectBootstrapper); container.doBeforeStart(); assertThat(container.getComponentsByType(PhasesSumUpTimeProfiler.class)).hasSize(0); @@ -89,7 +85,7 @@ public class ProjectScanContainerTest { settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, "true"); container = new ProjectScanContainer(parentContainer); - container.add(mock(ExtensionInstaller.class), projectBootstrapper, bootstrapSettings); + container.add(mock(ExtensionInstaller.class), projectBootstrapper); container.doBeforeStart(); assertThat(container.getComponentsByType(PhasesSumUpTimeProfiler.class)).hasSize(1); diff --git a/sonar-batch/src/test/java/org/sonar/batch/settings/DefaultSettingsReferentialTest.java b/sonar-batch/src/test/java/org/sonar/batch/settings/DefaultSettingsReferentialTest.java new file mode 100644 index 00000000000..7fda9daaa6c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/settings/DefaultSettingsReferentialTest.java @@ -0,0 +1,69 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.settings; + +import org.fest.assertions.MapAssert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.ServerClient; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultSettingsReferentialTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private static final String JSON_RESPONSE = "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}]"; + + private static final String REACTOR_JSON_RESPONSE = "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," + + "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\"}]"; + + ServerClient client = mock(ServerClient.class); + + private AnalysisMode mode; + + private DefaultSettingsReferential ref; + + @Before + public void prepare() { + mode = mock(AnalysisMode.class); + ref = new DefaultSettingsReferential(client, mode); + } + + @Test + public void should_load_project_props() { + when(client.request("/batch_bootstrap/properties?dryRun=false&project=struts")).thenReturn(REACTOR_JSON_RESPONSE); + + assertThat(ref.projectSettings("struts")).hasSize(2).includes(MapAssert.entry("sonar.cpd.cross", "true")); + } + + @Test + public void should_load_global_settings() { + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + + assertThat(ref.globalSettings()).hasSize(1).includes(MapAssert.entry("sonar.cpd.cross", "true")); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java index 1c2dd4e29be..3af2bacebd2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java @@ -331,10 +331,18 @@ public class Settings implements BatchComponent, ServerComponent { return this; } + /** + * @deprecated since 4.4 For embedding purpose all properties should be provided by the bootstrapper + */ + @Deprecated public Settings addSystemProperties() { return addProperties(System.getProperties()); } + /** + * @deprecated since 4.4 For embedding purpose all properties should be provided by the bootstrapper + */ + @Deprecated public Settings addEnvironmentVariables() { return addProperties(System.getenv()); } -- 2.39.5