]> source.dussan.org Git - sonarqube.git/commitdiff
Separate bootstrap settings and task settings
authorJulien HENRY <julien.henry@sonarsource.com>
Mon, 9 Jun 2014 13:16:10 +0000 (15:16 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 10 Jun 2014 10:36:10 +0000 (12:36 +0200)
33 files changed:
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapProperties.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapSettings.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskProperties.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/UserProperties.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
sonar-batch/src/main/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilder.java
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/settings/DefaultSettingsReferential.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/settings/SettingsReferential.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapSettingsTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java
sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java
sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/DeprecatedProjectReactorBuilderTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ProjectReactorBuilderTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
sonar-batch/src/test/java/org/sonar/batch/settings/DefaultSettingsReferentialTest.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java

index e21ec2ba6b58db2370ea2c8543854547634c986a..aa81851122d349ac9c16904f81e28e8ec6036b36 100644 (file)
@@ -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.<String,String>emptyMap())
-    );
+    BootstrapProperties bootstrapSettings = new BootstrapProperties(Collections.<String, String>emptyMap());
     try {
       bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath());
     } catch (IOException e) {
index b524b5b6acfde4b43381350b9fd835f5d94df727..4415122c3f657e99c16e180ad8bc7b2a75ffbb5f 100644 (file)
@@ -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;
     }
index 63f0824663c313dce2fa84e49c6fb6cef71f5f66..b818a60236198c3974be749e1b86bc41c6ab7579 100644 (file)
  */
 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<String, String> 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<Map<String, String>> json = new Gson().fromJson(jsonText, new TypeToken<List<Map<String, String>>>() {
-    }.getType());
-
-    for (Map<String, String> 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.");
     }
   }
index c2076bc83f31c3bbf47fab4aa2840bac632ca638..feffc2f6ede78bd44d94646cc9769c485f50f48c 100644 (file)
@@ -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<String, String> bootstrapProperties;
+
+  private BootstrapContainer(Map<String, String> bootstrapProperties) {
     super();
+    this.bootstrapProperties = bootstrapProperties;
   }
 
-  public static BootstrapContainer create(List objects) {
-    BootstrapContainer container = new BootstrapContainer();
-    container.add(objects);
+  public static BootstrapContainer create(Map<String, String> 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<String, String> taskProperties) {
+    new TaskContainer(this, taskProperties).execute();
   }
+
 }
index 71b6e589a854f05f89c58a14b4cab71fc74b62a6..97db4c2b3df673743ec43bc5f1dbb7d94bce664a 100644 (file)
  */
 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<String, String> properties;
+public class BootstrapProperties extends UserProperties {
 
   public BootstrapProperties(Map<String, String> properties) {
-    this.properties = ImmutableMap.copyOf(properties);
-  }
-
-  Map<String, String> 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 (file)
index 179bc8d..0000000
+++ /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<String, String> 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<Object, Object> entry : p.entrySet()) {
-      if (entry.getValue() != null) {
-        properties.put(entry.getKey().toString(), entry.getValue().toString());
-      }
-    }
-  }
-
-  public Map<String, String> 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);
-  }
-}
index 111f28b36b87065fc945cf95aa26acf27b45f8de..d43ef8e0e711ded34dc5f5416efb6eb1ee6c8765 100644 (file)
@@ -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);
   }
 }
index b328680a990d2a0ffcbdae0144772e0e607d3c0c..4bdda269f46894c9bd100ccf07d373a30959ab44 100644 (file)
@@ -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<String, String> taskProperties;
+
+  public TaskContainer(ComponentContainer parent, Map<String, String> 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 (file)
index 0000000..d469fcd
--- /dev/null
@@ -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<String, String> properties, @Nullable String pathToSecretKey) {
+    super(properties, pathToSecretKey);
+  }
+
+}
index 267b29e30579a37c1e43ac4bce422978dea2d4e0..50a736b5e4cdf1684286ac6ee1648ff7f35daeb6 100644 (file)
@@ -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 (file)
index 0000000..42ae3d9
--- /dev/null
@@ -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<String, String> properties;
+  private final Encryption encryption;
+
+  public UserProperties(Map<String, String> properties, @Nullable String pathToSecretKey) {
+    encryption = new Encryption(pathToSecretKey);
+    Map<String, String> decryptedProps = Maps.newHashMap();
+    for (Map.Entry<String, String> 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<String, String> properties() {
+    return properties;
+  }
+
+  public String property(String key) {
+    return properties.get(key);
+  }
+
+}
index 9d90cf0b6ee4dbc144433e9f7b0684ee7a7bd8cd..972450aebdeab54ea8b16325760b8ea6fe038dcb 100644 (file)
@@ -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<Object> components;
   private Map<String, String> 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<Object> all = Lists.newArrayList(components);
-    all.add(new BootstrapProperties(bootstrapProperties));
+  /**
+   * @since 4.4
+   */
+  public Batch executeTask(Map<String, String> 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() {
index a0c3f5d173bc7f6e49f33abfb6d2b773161d6373..c9983e33243ab3711933f76dae9133255d28b1f0 100644 (file)
@@ -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
index e10d8a6c9846b0daac6ff9c30e51f863ac5acfdd..da469b8bb89b873feb6013911fadd9edd97cb558 100644 (file)
 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<Map<String, String>> json = new Gson().fromJson(jsonText, new TypeToken<List<Map<String, String>>>() {
-    }.getType());
-    for (Map<String, String> 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.");
     }
   }
index 6fcd09ad56824335e5a9022aeb4eb7666c833ea0..f1700a38fcbadbfb97d32790603c30b947d6332a 100644 (file)
@@ -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<String> 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);
     }
index 335884d7f8779e59058c5a888820ab5ca1f104d3..b6dca14dafd8e722dae41348848e7e04d5ebf190 100644 (file)
@@ -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 (file)
index 0000000..6241b08
--- /dev/null
@@ -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<String, String> globalSettings() {
+    return downloadSettings(null);
+  }
+
+  @Override
+  public Map<String, String> projectSettings(String moduleKey) {
+    return downloadSettings(moduleKey);
+  }
+
+  private Map<String, String> downloadSettings(@Nullable String moduleKey) {
+    Map<String, String> result = Maps.newHashMap();
+    String url = BATCH_BOOTSTRAP_PROPERTIES_URL + "?dryRun=" + analysisMode.isPreview();
+    if (moduleKey != null) {
+      url += "&project=" + moduleKey;
+    }
+    String jsonText = serverClient.request(url);
+
+    List<Map<String, String>> json = new Gson().fromJson(jsonText, new TypeToken<List<Map<String, String>>>() {
+    }.getType());
+
+    for (Map<String, String> 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 (file)
index 0000000..d4d7367
--- /dev/null
@@ -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<String, String> globalSettings();
+
+  /**
+   * Provide settings for a given project or sub-project (includes global settings)
+   * @param projectKey
+   */
+  Map<String, String> projectSettings(String projectKey);
+
+}
index 4370ffaf8b92fcbbc0fb65d960af078667990a26..aafcb3f5ceaa7819a83dba445527e019ced25b12 100644 (file)
@@ -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.<String, String>emptyMap()));
-  }
-
   @Test
   public void regular_analysis_by_default() {
-    AnalysisMode mode = new AnalysisMode(bootstrapSettings);
+    AnalysisMode mode = new AnalysisMode(new BootstrapProperties(Collections.<String, String>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);
   }
index 767897e4fe32946aab6f0bce2e2f62be259c544b..1b507af9c7f507d3ac2c04ea0959a7a1aca7e4f3 100644 (file)
@@ -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.<String, String>emptyMap()));
+    bootstrapProps = new BootstrapProperties(Collections.<String, String>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.<String, String>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();
   }
 }
index cb611c8ae668decfbf9068355d8aa1e1c54da1f7..c31bd9fea47df376d55cdda278e1d0fd40ca09fd 100644 (file)
@@ -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.<String, String>emptyMap()));
+    BootstrapContainer container = BootstrapContainer.create(Collections.<String, String>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.<String, String>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.<Object>newArrayList(pluginRepository)));
-    doNothing().when(container).executeTask();
+    BootstrapContainer container = spy(BootstrapContainer.create(Collections.<String, String>emptyMap(), Lists.<Object>newArrayList(pluginRepository)));
+    doNothing().when(container).executeTask(Collections.<String, String>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.<String, String>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.<String, String>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.<String, String>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 (file)
index 7da55ba..0000000
+++ /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<String, String> 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.<String, String>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.<String, String>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.<String, String>emptyMap()), reactor);
-
-    assertThat(settings.property("foo", "default_value")).isEqualTo("bar");
-    assertThat(settings.property("missing", "default_value")).isEqualTo("default_value");
-  }
-}
index 742f53e25dc7e418868f3252860cd648f11a0f36..34060a4ee30dc5d8faefc49ad11074516de912d9 100644 (file)
@@ -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 (file)
index 0000000..4161665
--- /dev/null
@@ -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.<String, String>emptyMap(),
+      Lists.newArrayList(new BootstrapProperties(Collections.<String, String>emptyMap())));
+    TaskContainer taskContainer = new TaskContainer(container, Collections.<String, String>emptyMap());
+    taskContainer.installCoreTasks();
+
+    assertThat(taskContainer.getComponentByType(ProjectReactorBuilder.class)).isNotNull().isInstanceOf(ProjectReactorBuilder.class);
+
+    container = BootstrapContainer.create(Collections.<String, String>emptyMap(),
+      Lists.newArrayList(new BootstrapProperties(Collections.<String, String>emptyMap()), new EnvironmentInformation("SonarQubeRunner", "2.4")));
+    taskContainer = new TaskContainer(container, Collections.<String, String>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.<String, String>emptyMap(),
+      Lists.newArrayList(new BootstrapProperties(Collections.<String, String>emptyMap()), new EnvironmentInformation("SonarRunner", "2.3")));
+    TaskContainer taskContainer = new TaskContainer(container, Collections.<String, String>emptyMap());
+    taskContainer.installCoreTasks();
+
+    assertThat(taskContainer.getComponentByType(DeprecatedProjectReactorBuilder.class)).isNotNull().isInstanceOf(DeprecatedProjectReactorBuilder.class);
+  }
+
+}
index 90c380248e6988abec7557bc3fad84eb3c2fafc9..605a768851f1fef9445acd7f2d5e1193dc0708a9 100644 (file)
@@ -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();
index 3b3ab52b083a46a342b5fae99522bb778a18cf45..65a4333e58bab4a246b55fa4bfee9e3f396cb9cb 100644 (file)
@@ -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.<String,String>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;
index 4d6f1de707473fab0e87c0d1a0604867d52f64d5..9768619144ebb3c974f31cb53f975691b8be3826 100644 (file)
@@ -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() {
index a5fa0efc325522a08d01172931e64445040ca358..c3deb16032a1ad0563ce31c339ca16bb16a22c58 100644 (file)
@@ -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();
   }
 
index 47b6300bcb21af53bbeca3de9c9dd77f8477f74b..0140f39a7d2a5609aaee511fc6d818b65d353f81 100644 (file)
@@ -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");
index 85a83bbfba23c7caf55cea7493fa3b50d9b6c578..631a58c766ea0ee237bb7a02633830213b7b5400 100644 (file)
@@ -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.<String, String>newHashMap())));
+    ProjectReactorBuilder builder = new ProjectReactorBuilder(new TaskProperties(Maps.<String, String>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<String, String> props = Maps.<String, String>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<String, String> props = Maps.<String, String>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();
   }
 
index 66657c5054b5c261a9f9c439f3644ef06a8e6dba..8f585fd36c4e6400803882a8b986f5778b36627d 100644 (file)
@@ -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.<String, String>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 (file)
index 0000000..7fda9da
--- /dev/null
@@ -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"));
+  }
+}
index 1c2dd4e29beb8e68bc1b46cd7687ac6537dff04d..3af2bacebd295a0bc1012dc871295137094b363f 100644 (file)
@@ -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());
   }